GFX3D:
- Remove NDS_3D_GetLineData(), as it wasn't appropriately named or used for its intended purpose. - Add NDS_3D_RenderFinish(), which is what should have been used in the first place. (Purpose: Blocks the thread until 3D rendering is finished.) - Optimize gpu3DNull so that it doesn't have to clear the 3D layer every frame. task.h: - Fix multiple #include compiling bug. SoftRasterizer: - Improve the performance of rendering in multithreaded mode. - Improve the stability of reset and shutdown in multithreaded mode. - Do some minor code cleanup. OpenGL Renderer: - Improve the stability of reset and shutdown. - Do some minor code cleanup.
This commit is contained in:
parent
ad65e6abf7
commit
a2f078ec81
|
@ -117,8 +117,7 @@ enum OGLTextureUnitID
|
||||||
|
|
||||||
// Multithreading States
|
// Multithreading States
|
||||||
static bool enableMultithreading = false;
|
static bool enableMultithreading = false;
|
||||||
static bool isReadPixelsWorking = false;
|
static Task oglReadPixelsTask[2];
|
||||||
static Task oglReadPixelsTask;
|
|
||||||
|
|
||||||
// Polygon Info
|
// Polygon Info
|
||||||
static GLfloat polyAlpha = 1.0f;
|
static GLfloat polyAlpha = 1.0f;
|
||||||
|
@ -498,42 +497,52 @@ static void OGLInitShaders(const char *oglExtensionString)
|
||||||
|
|
||||||
static void OGLReset()
|
static void OGLReset()
|
||||||
{
|
{
|
||||||
|
gpuScreen3DHasNewData[0] = false;
|
||||||
|
gpuScreen3DHasNewData[1] = false;
|
||||||
|
|
||||||
|
if (enableMultithreading)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
oglReadPixelsTask[i].finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!BEGINGL())
|
||||||
|
return;
|
||||||
|
|
||||||
|
glFinish();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
memset(GPU_screen3D[i], 0, sizeof(GPU_screen3D[i]));
|
||||||
|
}
|
||||||
|
|
||||||
if(isShaderSupported)
|
if(isShaderSupported)
|
||||||
{
|
{
|
||||||
hasTexture = false;
|
hasTexture = false;
|
||||||
|
|
||||||
if(BEGINGL())
|
glUniform1i(uniformPolyID, 0);
|
||||||
{
|
glUniform1f(uniformPolyAlpha, 1.0f);
|
||||||
glUniform1i(uniformPolyID, 0);
|
glUniform2f(uniformTexScale, 1.0f, 1.0f);
|
||||||
glUniform1f(uniformPolyAlpha, 1.0f);
|
glUniform1i(uniformHasTexture, GL_FALSE);
|
||||||
glUniform2f(uniformTexScale, 1.0f, 1.0f);
|
glUniform1i(uniformPolygonMode, 0);
|
||||||
glUniform1i(uniformHasTexture, GL_FALSE);
|
glUniform1i(uniformToonShadingMode, 0);
|
||||||
glUniform1i(uniformPolygonMode, 0);
|
glUniform1i(uniformWBuffer, 0);
|
||||||
glUniform1i(uniformToonShadingMode, 0);
|
glUniform1i(uniformEnableAlphaTest, GL_TRUE);
|
||||||
glUniform1i(uniformWBuffer, 0);
|
glUniform1f(uniformAlphaTestRef, 0.0f);
|
||||||
glUniform1i(uniformEnableAlphaTest, GL_TRUE);
|
|
||||||
glUniform1f(uniformAlphaTestRef, 0.0f);
|
|
||||||
|
|
||||||
ENDGL();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
|
memset(color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
|
||||||
}
|
}
|
||||||
|
|
||||||
TexCache_Reset();
|
ENDGL();
|
||||||
if (currTexture)
|
|
||||||
delete currTexture;
|
|
||||||
currTexture = NULL;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
memset(GPU_screen3D[i], 0, sizeof(GPU_screen3D[i]));
|
|
||||||
gpuScreen3DHasNewData[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(vertIndexBuffer, 0, VERT_INDEX_BUFFER_SIZE * sizeof(GLushort));
|
memset(vertIndexBuffer, 0, VERT_INDEX_BUFFER_SIZE * sizeof(GLushort));
|
||||||
|
currTexture = NULL;
|
||||||
|
|
||||||
|
Default3D_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//static class OGLTexCacheUser : public ITexCacheUser
|
//static class OGLTexCacheUser : public ITexCacheUser
|
||||||
|
@ -636,13 +645,25 @@ static bool OGLIsMinimumVersionSupported(const char *oglVersionString)
|
||||||
|
|
||||||
static char OGLInit(void)
|
static char OGLInit(void)
|
||||||
{
|
{
|
||||||
|
char result = 0;
|
||||||
|
|
||||||
if(!oglrender_init)
|
if(!oglrender_init)
|
||||||
return 0;
|
return result;
|
||||||
if(!oglrender_init())
|
if(!oglrender_init())
|
||||||
return 0;
|
return result;
|
||||||
|
|
||||||
|
result = Default3D_Init();
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if(!BEGINGL())
|
if(!BEGINGL())
|
||||||
return 0;
|
{
|
||||||
|
INFO("OpenGL: Could not initialize -- BEGINGL() failed.");
|
||||||
|
result = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Get OpenGL info
|
// Get OpenGL info
|
||||||
const char *oglVendorString = (const char *)glGetString(GL_VENDOR);
|
const char *oglVendorString = (const char *)glGetString(GL_VENDOR);
|
||||||
|
@ -655,13 +676,10 @@ static char OGLInit(void)
|
||||||
OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_REVISION,
|
OGL_MINIMUM_GPU_VERSION_REQUIRED_MAJOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_MINOR, OGL_MINIMUM_GPU_VERSION_REQUIRED_REVISION,
|
||||||
oglVersionString, oglVendorString, oglRendererString);
|
oglVersionString, oglVendorString, oglRendererString);
|
||||||
|
|
||||||
return 0;
|
result = 0;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, 256, 192);
|
|
||||||
if (glGetError() != GL_NO_ERROR)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const char *oglExtensionString = (const char *)glGetString(GL_EXTENSIONS);
|
const char *oglExtensionString = (const char *)glGetString(GL_EXTENSIONS);
|
||||||
|
|
||||||
for (u8 i = 0; i < 255; i++)
|
for (u8 i = 0; i < 255; i++)
|
||||||
|
@ -936,8 +954,6 @@ static char OGLInit(void)
|
||||||
ENDGL();
|
ENDGL();
|
||||||
|
|
||||||
// Multithreading Setup
|
// Multithreading Setup
|
||||||
isReadPixelsWorking = false;
|
|
||||||
|
|
||||||
if (CommonSettings.num_cores > 1)
|
if (CommonSettings.num_cores > 1)
|
||||||
{
|
{
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
|
@ -947,7 +963,11 @@ static char OGLInit(void)
|
||||||
enableMultithreading = false;
|
enableMultithreading = false;
|
||||||
#else
|
#else
|
||||||
enableMultithreading = true;
|
enableMultithreading = true;
|
||||||
oglReadPixelsTask.start(false);
|
|
||||||
|
for (unsigned int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
oglReadPixelsTask[i].start(false);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -960,27 +980,28 @@ static char OGLInit(void)
|
||||||
INFO("OpenGL: Initialized successfully.\n[GPU Info - Version: %s, Vendor: %s, Renderer: %s]\n",
|
INFO("OpenGL: Initialized successfully.\n[GPU Info - Version: %s, Vendor: %s, Renderer: %s]\n",
|
||||||
oglVersionString, oglVendorString, oglRendererString);
|
oglVersionString, oglVendorString, oglRendererString);
|
||||||
|
|
||||||
return 1;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OGLClose()
|
static void OGLClose()
|
||||||
{
|
{
|
||||||
if (enableMultithreading)
|
|
||||||
{
|
|
||||||
oglReadPixelsTask.finish();
|
|
||||||
oglReadPixelsTask.shutdown();
|
|
||||||
isReadPixelsWorking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpuScreen3DHasNewData[0] = false;
|
gpuScreen3DHasNewData[0] = false;
|
||||||
gpuScreen3DHasNewData[1] = false;
|
gpuScreen3DHasNewData[1] = false;
|
||||||
|
|
||||||
delete [] vertIndexBuffer;
|
if (enableMultithreading)
|
||||||
vertIndexBuffer = NULL;
|
{
|
||||||
|
for (unsigned int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
oglReadPixelsTask[i].finish();
|
||||||
|
oglReadPixelsTask[i].shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!BEGINGL())
|
if(!BEGINGL())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glFinish();
|
||||||
|
|
||||||
if(isShaderSupported)
|
if(isShaderSupported)
|
||||||
{
|
{
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
@ -992,6 +1013,8 @@ static void OGLClose()
|
||||||
glDeleteShader(vertexShaderID);
|
glDeleteShader(vertexShaderID);
|
||||||
glDeleteShader(fragmentShaderID);
|
glDeleteShader(fragmentShaderID);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ToonTable);
|
||||||
|
glBindTexture(GL_TEXTURE_1D, 0);
|
||||||
glDeleteTextures(1, &texToonTableID);
|
glDeleteTextures(1, &texToonTableID);
|
||||||
|
|
||||||
isShaderSupported = false;
|
isShaderSupported = false;
|
||||||
|
@ -1004,27 +1027,20 @@ static void OGLClose()
|
||||||
|
|
||||||
if (isVAOSupported)
|
if (isVAOSupported)
|
||||||
{
|
{
|
||||||
|
glBindVertexArray(0);
|
||||||
glDeleteVertexArrays(1, &vaoMainStatesID);
|
glDeleteVertexArrays(1, &vaoMainStatesID);
|
||||||
isVAOSupported = false;
|
isVAOSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//kill the tex cache to free all the texture ids
|
|
||||||
TexCache_Reset();
|
|
||||||
|
|
||||||
while(!freeTextureIds.empty())
|
|
||||||
{
|
|
||||||
GLuint temp = freeTextureIds.front();
|
|
||||||
freeTextureIds.pop();
|
|
||||||
glDeleteTextures(1,&temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isVBOSupported)
|
if (isVBOSupported)
|
||||||
{
|
{
|
||||||
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||||
glDeleteBuffersARB(1, &vboVertexID);
|
glDeleteBuffersARB(1, &vboVertexID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPBOSupported)
|
if (isPBOSupported)
|
||||||
{
|
{
|
||||||
|
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
||||||
glDeleteBuffersARB(2, pboRenderDataID);
|
glDeleteBuffersARB(2, pboRenderDataID);
|
||||||
pboRenderBuffer[0] = NULL;
|
pboRenderBuffer[0] = NULL;
|
||||||
pboRenderBuffer[1] = NULL;
|
pboRenderBuffer[1] = NULL;
|
||||||
|
@ -1033,14 +1049,36 @@ static void OGLClose()
|
||||||
// FBO
|
// FBO
|
||||||
if (isFBOSupported)
|
if (isFBOSupported)
|
||||||
{
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_ClearImage);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
|
|
||||||
glDeleteFramebuffersEXT(1, &fboClearImageID);
|
glDeleteFramebuffersEXT(1, &fboClearImageID);
|
||||||
glDeleteTextures(1, &texClearImageColorID);
|
glDeleteTextures(1, &texClearImageColorID);
|
||||||
glDeleteTextures(1, &texClearImageDepthStencilID);
|
glDeleteTextures(1, &texClearImageDepthStencilID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//kill the tex cache to free all the texture ids
|
||||||
|
TexCache_Reset();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
while(!freeTextureIds.empty())
|
||||||
|
{
|
||||||
|
GLuint temp = freeTextureIds.front();
|
||||||
|
freeTextureIds.pop();
|
||||||
|
glDeleteTextures(1,&temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
glFinish();
|
||||||
|
|
||||||
ENDGL();
|
ENDGL();
|
||||||
|
|
||||||
|
delete [] vertIndexBuffer;
|
||||||
|
vertIndexBuffer = NULL;
|
||||||
|
|
||||||
|
Default3D_Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void texDeleteCallback(TexCacheItem* item)
|
static void texDeleteCallback(TexCacheItem* item)
|
||||||
|
@ -1318,15 +1356,14 @@ static void GL_ReadFramebuffer()
|
||||||
{
|
{
|
||||||
static unsigned int bufferIndex = 0;
|
static unsigned int bufferIndex = 0;
|
||||||
|
|
||||||
if (enableMultithreading && isReadPixelsWorking)
|
|
||||||
{
|
|
||||||
oglReadPixelsTask.finish();
|
|
||||||
isReadPixelsWorking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferIndex = (bufferIndex + 1) & 0x01;
|
bufferIndex = (bufferIndex + 1) & 0x01;
|
||||||
gpuScreen3DBufferIndex = bufferIndex;
|
gpuScreen3DBufferIndex = bufferIndex;
|
||||||
|
|
||||||
|
if (enableMultithreading)
|
||||||
|
{
|
||||||
|
oglReadPixelsTask[bufferIndex].finish();
|
||||||
|
}
|
||||||
|
|
||||||
if (isPBOSupported)
|
if (isPBOSupported)
|
||||||
{
|
{
|
||||||
if(!BEGINGL()) return;
|
if(!BEGINGL()) return;
|
||||||
|
@ -1353,14 +1390,12 @@ static void GL_ReadFramebuffer()
|
||||||
// H-Blank, and let that logic determine whether a pixel read is needed or not.
|
// H-Blank, and let that logic determine whether a pixel read is needed or not.
|
||||||
// This can save us some time in cases where games don't require the 3D layer
|
// This can save us some time in cases where games don't require the 3D layer
|
||||||
// for this particular frame.
|
// for this particular frame.
|
||||||
|
|
||||||
|
gpuScreen3DHasNewData[bufferIndex] = true;
|
||||||
|
|
||||||
if (enableMultithreading)
|
if (enableMultithreading)
|
||||||
{
|
{
|
||||||
isReadPixelsWorking = true;
|
oglReadPixelsTask[bufferIndex].execute(&execReadPixelsTask, &bufferIndex);
|
||||||
oglReadPixelsTask.execute(&execReadPixelsTask, &bufferIndex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gpuScreen3DHasNewData[bufferIndex] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1738,27 +1773,26 @@ static void OGLRender()
|
||||||
|
|
||||||
static void OGLVramReconfigureSignal()
|
static void OGLVramReconfigureSignal()
|
||||||
{
|
{
|
||||||
TexCache_Invalidate();
|
Default3D_VramReconfigureSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8* OGLGetLineData(u8 lineNumber)
|
static void OGLRenderFinish()
|
||||||
{
|
{
|
||||||
// If OpenGL is still reading back pixels on a separate thread, wait for it to finish.
|
// If OpenGL is still reading back pixels on a separate thread, wait for it to finish.
|
||||||
if (isReadPixelsWorking)
|
// Otherwise, just do the pixel read now.
|
||||||
{
|
|
||||||
oglReadPixelsTask.finish();
|
|
||||||
isReadPixelsWorking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're doing a pixel read on this thread and we have new rendered data,
|
|
||||||
// then do the pixel read now.
|
|
||||||
if (gpuScreen3DHasNewData[gpuScreen3DBufferIndex])
|
if (gpuScreen3DHasNewData[gpuScreen3DBufferIndex])
|
||||||
{
|
{
|
||||||
execReadPixelsTask(&gpuScreen3DBufferIndex);
|
if (enableMultithreading)
|
||||||
|
{
|
||||||
|
oglReadPixelsTask[gpuScreen3DBufferIndex].finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
execReadPixelsTask(&gpuScreen3DBufferIndex);
|
||||||
|
}
|
||||||
|
|
||||||
gpuScreen3DHasNewData[gpuScreen3DBufferIndex] = false;
|
gpuScreen3DHasNewData[gpuScreen3DBufferIndex] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( gfx3d_convertedScreen + (lineNumber << (8+2)) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU3DInterface gpu3Dgl = {
|
GPU3DInterface gpu3Dgl = {
|
||||||
|
@ -1767,6 +1801,6 @@ GPU3DInterface gpu3Dgl = {
|
||||||
OGLReset,
|
OGLReset,
|
||||||
OGLClose,
|
OGLClose,
|
||||||
OGLRender,
|
OGLRender,
|
||||||
OGLVramReconfigureSignal,
|
OGLRenderFinish,
|
||||||
OGLGetLineData
|
OGLVramReconfigureSignal
|
||||||
};
|
};
|
||||||
|
|
|
@ -489,6 +489,8 @@ void gfx3d_init()
|
||||||
|
|
||||||
void gfx3d_reset()
|
void gfx3d_reset()
|
||||||
{
|
{
|
||||||
|
gpu3D->NDS_3D_RenderFinish();
|
||||||
|
|
||||||
#ifdef _SHOW_VTX_COUNTERS
|
#ifdef _SHOW_VTX_COUNTERS
|
||||||
max_polys = max_verts = 0;
|
max_polys = max_verts = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2183,13 +2185,12 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
|
||||||
|
|
||||||
drawPending = FALSE;
|
drawPending = FALSE;
|
||||||
|
|
||||||
//if the null 3d core is chosen, then we need to clear out the 3d buffers to keep old data from being rendered
|
if(!CommonSettings.showGpu.main)
|
||||||
if(gpu3D == &gpu3DNull || !CommonSettings.showGpu.main)
|
|
||||||
{
|
{
|
||||||
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
|
memset(gfx3d_convertedScreen,0,sizeof(gfx3d_convertedScreen));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu3D->NDS_3D_Render();
|
gpu3D->NDS_3D_Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2301,14 +2302,8 @@ void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest)
|
||||||
|
|
||||||
void gfx3d_GetLineData(int line, u8** dst)
|
void gfx3d_GetLineData(int line, u8** dst)
|
||||||
{
|
{
|
||||||
if (gpu3D->NDS_3D_GetLineData == NULL)
|
gpu3D->NDS_3D_RenderFinish();
|
||||||
{
|
*dst = gfx3d_convertedScreen+((line)<<(8+2));
|
||||||
*dst = gfx3d_convertedScreen+((line)<<(8+2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*dst = gpu3D->NDS_3D_GetLineData(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gfx3d_GetLineData15bpp(int line, u16** dst)
|
void gfx3d_GetLineData15bpp(int line, u16** dst)
|
||||||
|
|
|
@ -67,7 +67,7 @@ static u8 decal_table[32][64][64];
|
||||||
static u8 index_lookup_table[65];
|
static u8 index_lookup_table[65];
|
||||||
static u8 index_start_table[8];
|
static u8 index_start_table[8];
|
||||||
|
|
||||||
|
static bool softRastHasNewData = false;
|
||||||
|
|
||||||
////optimized float floor useful in limited cases
|
////optimized float floor useful in limited cases
|
||||||
////from http://www.stereopsis.com/FPU.html#convert
|
////from http://www.stereopsis.com/FPU.html#convert
|
||||||
|
@ -1073,7 +1073,7 @@ static SoftRasterizerEngine mainSoftRasterizer;
|
||||||
static Task rasterizerUnitTask[_MAX_CORES];
|
static Task rasterizerUnitTask[_MAX_CORES];
|
||||||
static RasterizerUnit<true> rasterizerUnit[_MAX_CORES];
|
static RasterizerUnit<true> rasterizerUnit[_MAX_CORES];
|
||||||
static RasterizerUnit<false> _HACK_viewer_rasterizerUnit;
|
static RasterizerUnit<false> _HACK_viewer_rasterizerUnit;
|
||||||
static int rasterizerCores;
|
static unsigned int rasterizerCores;
|
||||||
static bool rasterizerUnitTasksInited = false;
|
static bool rasterizerUnitTasksInited = false;
|
||||||
|
|
||||||
static void* execRasterizerUnit(void* arg)
|
static void* execRasterizerUnit(void* arg)
|
||||||
|
@ -1085,6 +1085,12 @@ static void* execRasterizerUnit(void* arg)
|
||||||
|
|
||||||
static char SoftRastInit(void)
|
static char SoftRastInit(void)
|
||||||
{
|
{
|
||||||
|
char result = Default3D_Init();
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if(!rasterizerUnitTasksInited)
|
if(!rasterizerUnitTasksInited)
|
||||||
{
|
{
|
||||||
rasterizerUnitTasksInited = true;
|
rasterizerUnitTasksInited = true;
|
||||||
|
@ -1095,7 +1101,7 @@ static char SoftRastInit(void)
|
||||||
rasterizerCores = CommonSettings.num_cores;
|
rasterizerCores = CommonSettings.num_cores;
|
||||||
if (rasterizerCores > _MAX_CORES)
|
if (rasterizerCores > _MAX_CORES)
|
||||||
rasterizerCores = _MAX_CORES;
|
rasterizerCores = _MAX_CORES;
|
||||||
if(CommonSettings.num_cores == 1)
|
if(CommonSettings.num_cores <= 1)
|
||||||
{
|
{
|
||||||
rasterizerCores = 1;
|
rasterizerCores = 1;
|
||||||
rasterizerUnit[0].SLI_MASK = 0;
|
rasterizerUnit[0].SLI_MASK = 0;
|
||||||
|
@ -1146,22 +1152,44 @@ static char SoftRastInit(void)
|
||||||
TexCache_Reset();
|
TexCache_Reset();
|
||||||
|
|
||||||
printf("SoftRast Initialized with cores=%d\n",rasterizerCores);
|
printf("SoftRast Initialized with cores=%d\n",rasterizerCores);
|
||||||
return 1;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftRastReset() {
|
static void SoftRastReset()
|
||||||
TexCache_Reset();
|
{
|
||||||
|
if (rasterizerCores > 1)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < rasterizerCores; i++)
|
||||||
|
{
|
||||||
|
rasterizerUnitTask[i].finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
softRastHasNewData = false;
|
||||||
|
|
||||||
|
Default3D_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftRastClose()
|
static void SoftRastClose()
|
||||||
{
|
{
|
||||||
for(int i=0; i<_MAX_CORES; i++)
|
if (rasterizerCores > 1)
|
||||||
rasterizerUnitTask[i].shutdown();
|
{
|
||||||
|
for(unsigned int i = 0; i < rasterizerCores; i++)
|
||||||
|
{
|
||||||
|
rasterizerUnitTask[i].finish();
|
||||||
|
rasterizerUnitTask[i].shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rasterizerUnitTasksInited = false;
|
rasterizerUnitTasksInited = false;
|
||||||
|
softRastHasNewData = false;
|
||||||
|
|
||||||
|
Default3D_Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftRastVramReconfigureSignal() {
|
static void SoftRastVramReconfigureSignal()
|
||||||
TexCache_Invalidate();
|
{
|
||||||
|
Default3D_VramReconfigureSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SoftRastConvertFramebuffer()
|
static void SoftRastConvertFramebuffer()
|
||||||
|
@ -1622,24 +1650,44 @@ static void SoftRastRender()
|
||||||
mainSoftRasterizer.performCoordAdjustment(true);
|
mainSoftRasterizer.performCoordAdjustment(true);
|
||||||
mainSoftRasterizer.setupTextures(true);
|
mainSoftRasterizer.setupTextures(true);
|
||||||
|
|
||||||
|
softRastHasNewData = true;
|
||||||
if(rasterizerCores==1)
|
|
||||||
|
if (rasterizerCores > 1)
|
||||||
{
|
{
|
||||||
rasterizerUnit[0].mainLoop<false>(&mainSoftRasterizer);
|
for(unsigned int i = 0; i < rasterizerCores; i++)
|
||||||
|
{
|
||||||
|
rasterizerUnitTask[i].execute(&execRasterizerUnit, (void *)i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(int i=0;i<rasterizerCores;i++) rasterizerUnitTask[i].execute(execRasterizerUnit,(void*)i);
|
rasterizerUnit[0].mainLoop<false>(&mainSoftRasterizer);
|
||||||
for(int i=0;i<rasterizerCores;i++) rasterizerUnitTask[i].finish();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SoftRastRenderFinish()
|
||||||
|
{
|
||||||
|
if (!softRastHasNewData)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rasterizerCores > 1)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < rasterizerCores; i++)
|
||||||
|
{
|
||||||
|
rasterizerUnitTask[i].finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TexCache_EvictFrame();
|
TexCache_EvictFrame();
|
||||||
|
|
||||||
|
|
||||||
mainSoftRasterizer.framebufferProcess();
|
mainSoftRasterizer.framebufferProcess();
|
||||||
|
|
||||||
// printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count);
|
// printf("rendered %d of %d polys after backface culling\n",gfx3d.polylist->count-culled,gfx3d.polylist->count);
|
||||||
SoftRastConvertFramebuffer();
|
SoftRastConvertFramebuffer();
|
||||||
|
|
||||||
|
softRastHasNewData = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU3DInterface gpu3DRasterize = {
|
GPU3DInterface gpu3DRasterize = {
|
||||||
|
@ -1648,7 +1696,7 @@ GPU3DInterface gpu3DRasterize = {
|
||||||
SoftRastReset,
|
SoftRastReset,
|
||||||
SoftRastClose,
|
SoftRastClose,
|
||||||
SoftRastRender,
|
SoftRastRender,
|
||||||
SoftRastVramReconfigureSignal,
|
SoftRastRenderFinish,
|
||||||
NULL
|
SoftRastVramReconfigureSignal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,23 +17,62 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "render3D.h"
|
#include "render3D.h"
|
||||||
|
#include "gfx3d.h"
|
||||||
|
#include "texcache.h"
|
||||||
|
|
||||||
int cur3DCore = GPU3D_NULL;
|
int cur3DCore = GPU3D_NULL;
|
||||||
|
|
||||||
static void NDS_nullFunc1 (void){}
|
|
||||||
static char NDS_nullFunc2 (void){ return 1; }
|
|
||||||
|
|
||||||
GPU3DInterface gpu3DNull = {
|
GPU3DInterface gpu3DNull = {
|
||||||
"None",
|
"None",
|
||||||
NDS_nullFunc2, //NDS_3D_Init
|
Default3D_Init,
|
||||||
NDS_nullFunc1, //NDS_3D_Reset
|
Default3D_Reset,
|
||||||
NDS_nullFunc1, //NDS_3D_Close
|
Default3D_Close,
|
||||||
NDS_nullFunc1, //NDS_3D_Render
|
Default3D_Render,
|
||||||
NDS_nullFunc1, //NDS_3D_VramReconfigureSignal
|
Default3D_RenderFinish,
|
||||||
0
|
Default3D_VramReconfigureSignal
|
||||||
};
|
};
|
||||||
|
|
||||||
GPU3DInterface *gpu3D = &gpu3DNull;
|
GPU3DInterface *gpu3D = &gpu3DNull;
|
||||||
|
static bool default3DAlreadyClearedLayer = false;
|
||||||
|
|
||||||
|
char Default3D_Init()
|
||||||
|
{
|
||||||
|
default3DAlreadyClearedLayer = false;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default3D_Reset()
|
||||||
|
{
|
||||||
|
default3DAlreadyClearedLayer = false;
|
||||||
|
|
||||||
|
TexCache_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default3D_Close()
|
||||||
|
{
|
||||||
|
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
|
||||||
|
default3DAlreadyClearedLayer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default3D_Render()
|
||||||
|
{
|
||||||
|
if (!default3DAlreadyClearedLayer)
|
||||||
|
{
|
||||||
|
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
|
||||||
|
default3DAlreadyClearedLayer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default3D_RenderFinish()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void Default3D_VramReconfigureSignal()
|
||||||
|
{
|
||||||
|
TexCache_Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
void NDS_3D_SetDriver (int core3DIndex)
|
void NDS_3D_SetDriver (int core3DIndex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,22 +30,24 @@ typedef struct Render3DInterface
|
||||||
const char * name;
|
const char * name;
|
||||||
|
|
||||||
//called once when the plugin starts up
|
//called once when the plugin starts up
|
||||||
char (CALL_CONVENTION* NDS_3D_Init) (void);
|
char (CALL_CONVENTION* NDS_3D_Init) ();
|
||||||
|
|
||||||
//called when the emulator resets (is this necessary?)
|
//called when the emulator resets (is this necessary?)
|
||||||
void (CALL_CONVENTION* NDS_3D_Reset) (void);
|
void (CALL_CONVENTION* NDS_3D_Reset) ();
|
||||||
|
|
||||||
//called when the plugin shuts down
|
//called when the plugin shuts down
|
||||||
void (CALL_CONVENTION* NDS_3D_Close) (void);
|
void (CALL_CONVENTION* NDS_3D_Close) ();
|
||||||
|
|
||||||
//called when the renderer should do its job and render the current display lists
|
//called when the renderer should do its job and render the current display lists
|
||||||
void (CALL_CONVENTION* NDS_3D_Render) (void);
|
void (CALL_CONVENTION* NDS_3D_Render) ();
|
||||||
|
|
||||||
|
// Called whenever 3D rendering needs to finish. This function should block the calling thread
|
||||||
|
// and only release the block when 3D rendering is finished. (Before reading the 3D layer, be
|
||||||
|
// sure to always call this function.)
|
||||||
|
void (CALL_CONVENTION* NDS_3D_RenderFinish) ();
|
||||||
|
|
||||||
//called when the emulator reconfigures its vram. you may need to invalidate your texture cache.
|
//called when the emulator reconfigures its vram. you may need to invalidate your texture cache.
|
||||||
void (CALL_CONVENTION* NDS_3D_VramReconfigureSignal) ();
|
void (CALL_CONVENTION* NDS_3D_VramReconfigureSignal) ();
|
||||||
|
|
||||||
//called when the emulator requests rendered graphics data
|
|
||||||
u8* (CALL_CONVENTION* NDS_3D_GetLineData) (u8 lineNumber);
|
|
||||||
|
|
||||||
} GPU3DInterface;
|
} GPU3DInterface;
|
||||||
|
|
||||||
|
@ -61,6 +63,13 @@ extern GPU3DInterface gpu3DNull;
|
||||||
// Extern pointer
|
// Extern pointer
|
||||||
extern GPU3DInterface *gpu3D;
|
extern GPU3DInterface *gpu3D;
|
||||||
|
|
||||||
|
char Default3D_Init();
|
||||||
|
void Default3D_Reset();
|
||||||
|
void Default3D_Close();
|
||||||
|
void Default3D_Render();
|
||||||
|
void Default3D_RenderFinish();
|
||||||
|
void Default3D_VramReconfigureSignal();
|
||||||
|
|
||||||
void NDS_3D_SetDriver (int core3DIndex);
|
void NDS_3D_SetDriver (int core3DIndex);
|
||||||
bool NDS_3D_ChangeCore(int newCore);
|
bool NDS_3D_ChangeCore(int newCore);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TASK_H_
|
#ifndef _TASK_H_
|
||||||
|
#define _TASK_H_
|
||||||
|
|
||||||
//Sort of like a single-thread thread pool.
|
//Sort of like a single-thread thread pool.
|
||||||
//You hand it a worker function and then call finish() to synch with its completion
|
//You hand it a worker function and then call finish() to synch with its completion
|
||||||
|
|
Loading…
Reference in New Issue