- Improve ClearImage/Rear-plane emulation accuracy and performance for both 3D renderers.

OpenGL Renderer:
- Do additional optimizations to ClearImage/Rear-plane emulation.
- Make FBO support check a little less strict.
- Some minor code cleanup.
This commit is contained in:
rogerman 2012-12-25 05:10:51 +00:00
parent 887f78a0d0
commit dcf601ebb2
4 changed files with 49 additions and 45 deletions

View File

@ -109,11 +109,11 @@ static bool isShaderSupported = false;
// ClearImage/Rear-plane (FBO)
static GLenum oglClearImageTextureID[2] = {0}; // 0 - image, 1 - depth
static GLuint oglClearImageBuffers = 0;
static u32 *oglClearImageColor = NULL;
static float *oglClearImageDepth = NULL;
static GLushort *oglClearImageColor = NULL;
static GLuint *oglClearImageDepth = NULL;
static u16 *oglClearImageColorTemp = NULL;
static u16 *oglClearImageDepthTemp = NULL;
static u32 oglClearImageScrollOld = 0;
static u16 oglClearImageScrollOld = 0;
// VBO
static GLuint vboVertexID;
@ -148,6 +148,7 @@ static GLfloat *color4fBuffer = NULL;
static GLushort *vertIndexBuffer = NULL;
static CACHE_ALIGN GLfloat material_8bit_to_float[255] = {0};
static CACHE_ALIGN GLuint dsDepthToD24S8_LUT[32768] = {0};
static const GLfloat divide5bitBy31LUT[32] = {0.0, 0.03225806451613, 0.06451612903226, 0.09677419354839,
0.1290322580645, 0.1612903225806, 0.1935483870968, 0.2258064516129,
0.258064516129, 0.2903225806452, 0.3225806451613, 0.3548387096774,
@ -495,8 +496,8 @@ static void OGLReset()
if (isFBOSupported)
{
memset(oglClearImageColor, 0, 256*192*sizeof(u32));
memset(oglClearImageDepth, 0, 256*192*sizeof(float));
memset(oglClearImageColor, 0, 256*192*sizeof(GLushort));
memset(oglClearImageDepth, 0, 256*192*sizeof(GLuint));
memset(oglClearImageColorTemp, 0, 256*192*sizeof(u16));
memset(oglClearImageDepthTemp, 0, 256*192*sizeof(u16));
oglClearImageScrollOld = 0;
@ -566,6 +567,9 @@ static char OGLInit(void)
for (u8 i = 0; i < 255; i++)
material_8bit_to_float[i] = (GLfloat)(i<<2)/255.f;
for (unsigned int i = 0; i < 32768; i++)
dsDepthToD24S8_LUT[i] = (GLuint)DS_DEPTH15TO24(i) << 8;
expandFreeTextures();
// Maintain our own vertex index buffer for vertex batching and primitive
@ -719,7 +723,11 @@ static char OGLInit(void)
}
// FBO Setup
isFBOSupported = (strstr(extString, "GL_ARB_framebuffer_object") == NULL)?false:true;
isFBOSupported = ( (strstr(extString, "GL_ARB_framebuffer_object") == NULL) &&
(strstr(extString, "GL_EXT_framebuffer_object") == NULL ||
strstr(extString, "GL_EXT_framebuffer_blit") == NULL ||
strstr(extString, "GL_EXT_packed_depth_stencil") == NULL) ) ? false: true;
if (isFBOSupported)
{
// ClearImage/Rear-plane
@ -740,11 +748,10 @@ static char OGLInit(void)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 256, 192, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, 256, 192, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
// FBO - init
glGenFramebuffersEXT(1, &oglClearImageBuffers);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oglClearImageBuffers);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, oglClearImageTextureID[0], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, oglClearImageTextureID[1], 0);
@ -759,9 +766,9 @@ static char OGLInit(void)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
oglClearImageColor = new u32[256*192];
oglClearImageColor = new GLushort[256*192];
oglClearImageColorTemp = new u16[256*192];
oglClearImageDepth = new float[256*192];
oglClearImageDepth = new GLuint[256*192];
oglClearImageDepthTemp = new u16[256*192];
}
else
@ -1203,21 +1210,23 @@ static void GL_ReadFramebuffer()
}
}
// TODO: optimize
// Tested: Sonic Chronicles Dark Brotherhood
// The Chronicles of Narnia - The Lion, The Witch and The Wardrobe
// Harry Potter and the Order of the Phoenix
static void oglClearImageFBO()
{
if (!isFBOSupported) return;
//printf("enableClearImage\n");
if (!isFBOSupported)
{
return;
}
u16* clearImage = (u16*)MMU.texInfo.textureSlotAddr[2];
u16* clearDepth = (u16*)MMU.texInfo.textureSlotAddr[3];
u16 scroll = T1ReadWord(MMU.ARM9_REG,0x356); //CLRIMAGE_OFFSET
if ((oglClearImageScrollOld != scroll)||
(memcmp(clearImage, oglClearImageColorTemp, 256*192*2) != 0) ||
(memcmp(clearDepth, oglClearImageDepthTemp, 256*192*2) != 0))
if (oglClearImageScrollOld != scroll ||
memcmp(clearImage, oglClearImageColorTemp, 256*192*2) ||
memcmp(clearDepth, oglClearImageDepthTemp, 256*192*2) )
{
oglClearImageScrollOld = scroll;
memcpy(oglClearImageColorTemp, clearImage, 256*192*2);
@ -1225,21 +1234,19 @@ static void oglClearImageFBO()
u16 xscroll = scroll&0xFF;
u16 yscroll = (scroll>>8)&0xFF;
u32 dd = 256*192-256;
for(int iy=0;iy<192;iy++)
unsigned int dd = 256*192-256;
for(unsigned int iy=0;iy<192;iy++)
{
int y = ((iy + yscroll)&255)<<8;
for(int ix=0;ix<256;ix++)
unsigned int y = ((iy + yscroll)&255)<<8;
for(unsigned int ix=0;ix<256;ix++)
{
int x = (ix + xscroll)&255;
int adr = y + x;
unsigned int x = (ix + xscroll)&255;
unsigned int adr = y + x;
u16 col = clearImage[adr];
oglClearImageColor[dd] = RGB15TO32(col,255*(col>>15));
u16 depth = clearDepth[adr] & 0x7FFF;
oglClearImageDepth[dd] = (float)gfx3d_extendDepth_15_to_24(depth) / (float)0x00FFFFFF;
oglClearImageColor[dd] = clearImage[adr];
oglClearImageDepth[dd] = dsDepthToD24S8_LUT[clearDepth[adr] & 0x7FFF];
dd++;
}
@ -1251,9 +1258,9 @@ static void oglClearImageFBO()
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, oglClearImageColor);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, oglClearImageColor);
glBindTexture(GL_TEXTURE_2D, oglClearImageTextureID[1]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_DEPTH_COMPONENT, GL_FLOAT, oglClearImageDepth);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, oglClearImageDepth);
glActiveTexture(GL_TEXTURE0);
}

View File

@ -253,6 +253,7 @@ CACHE_ALIGN u32 color_15bit_to_24bit_reverse[32768];
CACHE_ALIGN u32 color_15bit_to_24bit[32768];
CACHE_ALIGN u16 color_15bit_to_16bit_reverse[32768];
CACHE_ALIGN u8 mixTable555[32][32][32];
CACHE_ALIGN u32 dsDepthExtend_15bit_to_24bit[32768];
//is this a crazy idea? this table spreads 5 bits evenly over 31 from exactly 0 to INT_MAX
CACHE_ALIGN const int material_5bit_to_31bit[] = {
@ -435,6 +436,9 @@ static void makeTables() {
{
color_15bit_to_24bit_reverse[i] = RGB15TO24_BITLOGIC_REVERSE((u16)i);
color_15bit_to_16bit_reverse[i] = (((i & 0x001F) << 11) | (material_5bit_to_6bit[(i & 0x03E0) >> 5] << 5) | ((i & 0x7C00) >> 10));
// 15-bit to 24-bit depth formula from http://nocash.emubase.de/gbatek.htm#ds3drearplane
dsDepthExtend_15bit_to_24bit[i] = (i*0x200)+((i+1)>>15)*0x01FF;
}
for (int i = 0; i < 65536; i++)
@ -555,7 +559,7 @@ void gfx3d_reset()
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
gfx3d.state.clearDepth = gfx3d_extendDepth_15_to_24(0x7FFF);
gfx3d.state.clearDepth = DS_DEPTH15TO24(0x7FFF);
clInd2 = 0;
isSwapBuffers = FALSE;
@ -1643,8 +1647,7 @@ void gfx3d_glFogOffset (u32 v)
void gfx3d_glClearDepth(u32 v)
{
v &= 0x7FFF;
gfx3d.state.clearDepth = gfx3d_extendDepth_15_to_24(v);
gfx3d.state.clearDepth = DS_DEPTH15TO24(v);
}
// Ignored for now

View File

@ -110,14 +110,8 @@ inline u32 RGB15TO6665(u16 col, u8 alpha5)
#define GFX3D_5TO6(x) ((x)?(((x)<<1)+1):0)
inline u32 gfx3d_extendDepth_15_to_24(u32 depth)
{
//formula from http://nocash.emubase.de/gbatek.htm#ds3drearplane
//return (depth*0x200)+((depth+1)>>15)*0x01FF;
//I think this might be slightly faster
if(depth==0x7FFF) return 0x00FFFFFF;
else return depth<<9;
}
// 15-bit to 24-bit depth formula from http://nocash.emubase.de/gbatek.htm#ds3drearplane
#define DS_DEPTH15TO24(depth) ( dsDepthExtend_15bit_to_24bit[depth & 0x7FFF] )
// POLYGON ATTRIBUTES - BIT LOCATIONS
enum
@ -696,6 +690,7 @@ extern GFX3D gfx3d;
extern CACHE_ALIGN u32 color_15bit_to_24bit[32768];
extern CACHE_ALIGN u32 color_15bit_to_24bit_reverse[32768];
extern CACHE_ALIGN u16 color_15bit_to_16bit_reverse[32768];
extern CACHE_ALIGN u32 dsDepthExtend_15bit_to_24bit[32768];
extern CACHE_ALIGN u8 mixTable555[32][32][32];
extern CACHE_ALIGN const int material_5bit_to_31bit[32];
extern CACHE_ALIGN const u8 material_5bit_to_8bit[32];

View File

@ -1223,10 +1223,9 @@ void SoftRasterizerEngine::initFramebuffer(const int width, const int height, co
//this is tested quite well in the sonic chronicles main map mode
//where depth values are used for trees etc you can walk behind
u32 depth = clearDepth[adr];
u16 depth = clearDepth[adr];
dst->fogged = BIT15(depth);
//TODO - might consider a lookup table for this
dst->depth = gfx3d_extendDepth_15_to_24(depth&0x7FFF);
dst->depth = DS_DEPTH15TO24(depth);
dstColor++;
dst++;