Render3D:

- Get rid of annoying flickering when switching 3D renderers.
- More code cleanup and refactoring.
This commit is contained in:
rogerman 2015-05-07 05:49:53 +00:00
parent 0c0f968d01
commit c36b8cbebb
10 changed files with 187 additions and 210 deletions

View File

@ -843,7 +843,7 @@ static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt)
{
//if(!nds.isIn3dVblank())
// PROGINFO("Changing texture or texture palette mappings outside of 3d vblank\n");
gpu3D->NDS_3D_VramReconfigureSignal();
CurrentRenderer->VramReconfigureSignal();
}
//-------------------------------

View File

@ -2510,7 +2510,6 @@ void NDS_Reset()
Screen_Reset();
gfx3d_reset();
gpu3D->NDS_3D_Reset();
WIFI_Reset();
memcpy(FW_Mac, (MMU.fw.data + 0x36), 6);

View File

@ -37,7 +37,6 @@ typedef struct
} OGLVersion;
static OGLVersion _OGLDriverVersion = {0, 0, 0};
static OpenGLRenderer *_OGLRenderer = NULL;
// Lookup Tables
static CACHE_ALIGN GLfloat material_8bit_to_float[256] = {0};
@ -56,14 +55,14 @@ const GLubyte PostprocessElementBuffer[6] = {0, 1, 2, 2, 3, 0};
const GLenum RenderDrawList[4] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT};
static bool BEGINGL()
bool BEGINGL()
{
if(oglrender_beginOpenGL)
return oglrender_beginOpenGL();
else return true;
}
static void ENDGL()
void ENDGL()
{
if(oglrender_endOpenGL)
oglrender_endOpenGL();
@ -572,13 +571,14 @@ static void OGLGetDriverVersion(const char *oglVersionString,
}
}
void texDeleteCallback(TexCacheItem *item)
void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2)
{
_OGLRenderer->DeleteTexture(item);
OpenGLRenderer *oglRenderer = (OpenGLRenderer *)param1;
oglRenderer->DeleteTexture(texItem);
}
template<bool require_profile, bool enable_3_2>
static Render3D* OGLInit()
static Render3D* OpenGLRendererCreate()
{
OpenGLRenderer *newRenderer = NULL;
Render3DError error = OGLERROR_NOERR;
@ -599,11 +599,6 @@ static Render3D* OGLInit()
return NULL;
}
// Force the creation of a new rendering object since we don't know what OpenGL version
// the user might be requesting.
delete _OGLRenderer;
_OGLRenderer = NULL;
// Get OpenGL info
const char *oglVersionString = (const char *)glGetString(GL_VERSION);
const char *oglVendorString = (const char *)glGetString(GL_VENDOR);
@ -615,7 +610,7 @@ static Render3D* OGLInit()
if(!strcmp(oglVendorString,"Intel") && strstr(oglRendererString,"965"))
{
INFO("OpenGL: Incompatible graphic card detected. Disabling OpenGL support.\n");
return _OGLRenderer;
return newRenderer;
}
// Check the driver's OpenGL version
@ -627,7 +622,7 @@ static Render3D* OGLInit()
OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MAJOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_MINOR, OGLRENDER_MINIMUM_DRIVER_VERSION_REQUIRED_REVISION,
oglVersionString, oglVendorString, oglRendererString);
return _OGLRenderer;
return newRenderer;
}
// Create new OpenGL rendering object
@ -642,7 +637,7 @@ static Render3D* OGLInit()
else
{
if(require_profile)
return _OGLRenderer;
return newRenderer;
}
}
@ -688,7 +683,7 @@ static Render3D* OGLInit()
{
INFO("OpenGL: Renderer did not initialize. Disabling 3D renderer.\n[ Driver Info -\n Version: %s\n Vendor: %s\n Renderer: %s ]\n",
oglVersionString, oglVendorString, oglRendererString);
return _OGLRenderer;
return newRenderer;
}
// Initialize OpenGL extensions
@ -702,21 +697,25 @@ static Render3D* OGLInit()
{
INFO("OpenGL: Shaders are not working, even though they should be. Disabling 3D renderer.\n");
delete newRenderer;
return _OGLRenderer;
newRenderer = NULL;
return newRenderer;
}
else if (IsVersionSupported(3, 0, 0) && error == OGLERROR_FBO_CREATE_ERROR && OGLLoadEntryPoints_3_2_Func != NULL)
{
INFO("OpenGL: FBOs are not working, even though they should be. Disabling 3D renderer.\n");
delete newRenderer;
return _OGLRenderer;
newRenderer = NULL;
return newRenderer;
}
}
ENDGL();
// Initialization finished -- reset the renderer
newRenderer->Reset();
ENDGL();
unsigned int major = 0;
unsigned int minor = 0;
unsigned int revision = 0;
@ -725,97 +724,42 @@ static Render3D* OGLInit()
INFO("OpenGL: Renderer initialized successfully (v%u.%u.%u).\n[ Driver Info -\n Version: %s\n Vendor: %s\n Renderer: %s ]\n",
major, minor, revision, oglVersionString, oglVendorString, oglRendererString);
_OGLRenderer = newRenderer;
return _OGLRenderer;
return newRenderer;
}
static void OGLClose()
static void OpenGLRendererDestroy()
{
if(!BEGINGL())
return;
if (CurrentRenderer == _OGLRenderer)
if (CurrentRenderer != BaseRenderer)
{
CurrentRenderer = NULL;
delete (OpenGLRenderer *)CurrentRenderer;
CurrentRenderer = BaseRenderer;
}
delete _OGLRenderer;
_OGLRenderer = NULL;
ENDGL();
}
static void OGLReset()
{
if(!BEGINGL())
return;
_OGLRenderer->Reset();
ENDGL();
}
static void OGLRender()
{
if(!BEGINGL())
return;
_OGLRenderer->Render(gfx3d);
ENDGL();
}
static void OGLVramReconfigureSignal()
{
if(!BEGINGL())
return;
_OGLRenderer->VramReconfigureSignal();
ENDGL();
}
static void OGLRenderFinish()
{
if(!BEGINGL())
return;
_OGLRenderer->RenderFinish();
ENDGL();
}
//automatically select 3.2 or old profile depending on whether 3.2 is available
GPU3DInterface gpu3Dgl = {
"OpenGL",
OGLInit<false,true>,
OGLClose,
OGLReset,
OGLRender,
OGLRenderFinish,
OGLVramReconfigureSignal
OpenGLRendererCreate<false,true>,
OpenGLRendererDestroy
};
//forcibly use old profile
GPU3DInterface gpu3DglOld = {
"OpenGL Old",
OGLInit<true,false>,
OGLClose,
OGLReset,
OGLRender,
OGLRenderFinish,
OGLVramReconfigureSignal
OpenGLRendererCreate<true,false>,
OpenGLRendererDestroy
};
//forcibly use new profile
GPU3DInterface gpu3Dgl_3_2 = {
"OpenGL 3.2",
OGLInit<true,true>,
OGLClose,
OGLReset,
OGLRender,
OGLRenderFinish,
OGLVramReconfigureSignal
OpenGLRendererCreate<true,true>,
OpenGLRendererDestroy
};
OpenGLRenderer::OpenGLRenderer()
@ -826,6 +770,28 @@ OpenGLRenderer::OpenGLRenderer()
versionMajor = 0;
versionMinor = 0;
versionRevision = 0;
isVBOSupported = false;
isPBOSupported = false;
isFBOSupported = false;
isMultisampledFBOSupported = false;
isShaderSupported = false;
isVAOSupported = false;
// Init OpenGL rendering states
ref = new OGLRenderRef;
ref->fboRenderID = 0;
ref->fboMSIntermediateRenderID = 0;
ref->fboPostprocessID = 0;
ref->selectedRenderingFBO = 0;
memset(GPU_screen3D, 0, sizeof(GPU_screen3D));
currTexture = NULL;
gpuScreen3DHasNewData[0] = false;
gpuScreen3DHasNewData[1] = false;
doubleBufferIndex = 0;
_currentPolyIndex = 0;
}
bool OpenGLRenderer::IsExtensionPresent(const std::set<std::string> *oglExtensionSet, const std::string extensionName) const
@ -931,23 +897,6 @@ void OpenGLRenderer::ConvertFramebuffer(const u32 *__restrict srcBuffer, u32 *ds
}
}
OpenGLRenderer_1_2::OpenGLRenderer_1_2()
{
isVBOSupported = false;
isPBOSupported = false;
isFBOSupported = false;
isMultisampledFBOSupported = false;
isShaderSupported = false;
isVAOSupported = false;
// Init OpenGL rendering states
ref = new OGLRenderRef;
ref->fboRenderID = 0;
ref->fboMSIntermediateRenderID = 0;
ref->fboPostprocessID = 0;
ref->selectedRenderingFBO = 0;
}
OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
{
if (ref == NULL)
@ -1959,6 +1908,11 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
if (this->isShaderSupported)
{
glUseProgram(OGLRef.programGeometryID);
@ -2203,6 +2157,8 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
this->ReadBackPixels();
ENDGL();
return OGLERROR_NOERR;
}
@ -2450,9 +2406,9 @@ Render3DError OpenGLRenderer_1_2::SetupTexture(const POLY &thePoly, bool enableT
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture?
if(!this->currTexture->deleteCallback)
if(this->currTexture->GetDeleteCallback() == NULL)
{
this->currTexture->deleteCallback = &texDeleteCallback;
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if(OGLRef.freeTextureIDs.empty())
{
@ -2507,16 +2463,13 @@ Render3DError OpenGLRenderer_1_2::Reset()
{
OGLRenderRef &OGLRef = *this->ref;
this->gpuScreen3DHasNewData[0] = false;
this->gpuScreen3DHasNewData[1] = false;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
glFinish();
for (size_t i = 0; i < 2; i++)
{
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
}
if (!this->isShaderSupported)
{
glEnable(GL_NORMALIZE);
@ -2527,6 +2480,16 @@ Render3DError OpenGLRenderer_1_2::Reset()
glEnable(GL_BLEND);
}
ENDGL();
this->gpuScreen3DHasNewData[0] = false;
this->gpuScreen3DHasNewData[1] = false;
for (size_t i = 0; i < 2; i++)
{
memset(this->GPU_screen3D[i], 0, sizeof(this->GPU_screen3D[i]));
}
if (OGLRef.color4fBuffer != NULL)
{
memset(OGLRef.color4fBuffer, 0, VERTLIST_SIZE * 4 * sizeof(GLfloat));
@ -2549,7 +2512,6 @@ Render3DError OpenGLRenderer_1_2::Reset()
memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer));
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
TexCache_Reset();
@ -2567,6 +2529,11 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
OGLRenderRef &OGLRef = *this->ref;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
if (this->isPBOSupported)
{
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]);
@ -2587,6 +2554,8 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen);
}
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
return OGLERROR_NOERR;
@ -2878,6 +2847,11 @@ Render3DError OpenGLRenderer_1_5::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
if (this->isShaderSupported)
{
glUseProgram(OGLRef.programGeometryID);
@ -2970,6 +2944,11 @@ Render3DError OpenGLRenderer_1_5::RenderFinish()
OGLRenderRef &OGLRef = *this->ref;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
if (this->isPBOSupported)
{
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, OGLRef.pboRenderDataID[i]);
@ -2990,6 +2969,8 @@ Render3DError OpenGLRenderer_1_5::RenderFinish()
this->ConvertFramebuffer(workingBuffer, (u32 *)gfx3d_convertedScreen);
}
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
return OGLERROR_NOERR;
@ -3403,6 +3384,11 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
// Setup render states
glUseProgram(OGLRef.programGeometryID);
glUniform1i(OGLRef.uniformStateToonShadingMode, engine.renderState.shading);
@ -3704,9 +3690,9 @@ Render3DError OpenGLRenderer_2_0::SetupTexture(const POLY &thePoly, bool enableT
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture?
if(!this->currTexture->deleteCallback)
if(this->currTexture->GetDeleteCallback() == NULL)
{
this->currTexture->deleteCallback = &texDeleteCallback;
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if(OGLRef.freeTextureIDs.empty())
{
@ -3761,6 +3747,11 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
return OGLERROR_NOERR;
}
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
glBindBuffer(GL_PIXEL_PACK_BUFFER, this->ref->pboRenderDataID[i]);
const u32 *__restrict mappedBufferPtr = (u32 *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
@ -3772,6 +3763,8 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
ENDGL();
this->gpuScreen3DHasNewData[i] = false;
return OGLERROR_NOERR;

View File

@ -309,6 +309,8 @@ enum OGLErrorCode
{
OGLERROR_NOERR = RENDER3DERROR_NOERR,
OGLERROR_BEGINGL_FAILED,
OGLERROR_FEATURE_UNSUPPORTED,
OGLERROR_VBO_UNSUPPORTED,
OGLERROR_PBO_UNSUPPORTED,
@ -504,7 +506,7 @@ extern CACHE_ALIGN const GLfloat divide5bitBy31_LUT[32];
extern const GLfloat PostprocessVtxBuffer[16];
extern const GLubyte PostprocessElementBuffer[6];
extern void texDeleteCallback(TexCacheItem *item);
extern void texDeleteCallback(TexCacheItem *texItem, void *param1, void *param2);
//This is called by OGLRender whenever it initializes.
//Platforms, please be sure to set this up.
@ -518,6 +520,11 @@ extern bool (*oglrender_beginOpenGL)();
//This is called by OGLRender after it is done using opengl.
extern void (*oglrender_endOpenGL)();
// Helper functions for calling the above function pointers at the
// beginning and ending of OpenGL commands.
bool BEGINGL();
void ENDGL();
// These functions need to be assigned by ports that support using an
// OpenGL 3.2 Core Profile context. The OGLRender_3_2.cpp file includes
// the corresponding functions to assign to each function pointer.
@ -668,7 +675,6 @@ protected:
virtual Render3DError SetupViewport(const u32 viewportValue);
public:
OpenGLRenderer_1_2();
~OpenGLRenderer_1_2();
virtual Render3DError InitExtensions();

View File

@ -1045,6 +1045,11 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D &engine)
OGLRenderRef &OGLRef = *this->ref;
this->doubleBufferIndex = (this->doubleBufferIndex + 1) & 0x01;
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
// Since glReadPixels() is called at the end of every render, we know that rendering
// must be synchronized at that time. Therefore, GL_MAP_UNSYNCHRONIZED_BIT should be
// safe to use.
@ -1384,9 +1389,9 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, bool enableT
{
this->currTexture = newTexture;
//has the ogl renderer initialized the texture?
if(!this->currTexture->deleteCallback)
if(this->currTexture->GetDeleteCallback() == NULL)
{
this->currTexture->deleteCallback = &texDeleteCallback;
this->currTexture->SetDeleteCallback(&texDeleteCallback, this, NULL);
if(OGLRef.freeTextureIDs.empty())
{

View File

@ -546,7 +546,7 @@ void gfx3d_init()
void gfx3d_reset()
{
gpu3D->NDS_3D_RenderFinish();
CurrentRenderer->RenderFinish();
#ifdef _SHOW_VTX_COUNTERS
max_polys = max_verts = 0;
@ -625,6 +625,8 @@ void gfx3d_reset()
GFX_PIPEclear();
GFX_FIFOclear();
CurrentRenderer->Reset();
}
@ -2284,7 +2286,7 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
return;
}
gpu3D->NDS_3D_Render();
CurrentRenderer->Render(gfx3d);
}
//#define _3D_LOG
@ -2395,7 +2397,7 @@ void gfx3d_glGetLightColor(unsigned int index, unsigned int* dest)
void gfx3d_GetLineData(int line, u8** dst)
{
gpu3D->NDS_3D_RenderFinish();
CurrentRenderer->RenderFinish();
*dst = gfx3d_convertedScreen+((line)<<(8+2));
}
@ -2511,7 +2513,7 @@ SFORMAT SF_GFX3D[]={
//-------------savestate
void gfx3d_savestate(EMUFILE* os)
{
gpu3D->NDS_3D_RenderFinish();
CurrentRenderer->RenderFinish();
//version
write32le(4,os);

View File

@ -1116,19 +1116,15 @@ void _HACK_Viewer_ExecUnit()
_HACK_viewer_rasterizerUnit.mainLoop<false>();
}
static Render3D* SoftRastInit()
static Render3D* SoftRasterizerRendererCreate()
{
return new SoftRasterizerRenderer;
}
GPU3DInterface gpu3DRasterize = {
"SoftRasterizer",
SoftRastInit,
Default3D_Close,
Default3D_Reset,
Default3D_Render,
Default3D_RenderFinish,
Default3D_VramReconfigureSignal
SoftRasterizerRendererCreate,
Render3DBaseDestroy
};
SoftRasterizerRenderer::SoftRasterizerRenderer()
@ -1779,7 +1775,6 @@ Render3DError SoftRasterizerRenderer::Reset()
memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer));
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
TexCache_Reset();

View File

@ -30,38 +30,34 @@ int cur3DCore = GPU3D_NULL;
GPU3DInterface gpu3DNull = {
"None",
Default3D_Init,
Default3D_Close,
Default3D_Reset,
Default3D_Render,
Default3D_RenderFinish,
Default3D_VramReconfigureSignal
Render3DBaseCreate,
Render3DBaseDestroy
};
GPU3DInterface *gpu3D = &gpu3DNull;
static Render3D *_baseRenderer = NULL;
Render3D *BaseRenderer = NULL;
Render3D *CurrentRenderer = NULL;
void Render3D_Init()
{
if (_baseRenderer == NULL)
if (BaseRenderer == NULL)
{
_baseRenderer = new Render3D;
BaseRenderer = new Render3D;
}
if (CurrentRenderer == NULL)
{
gpu3D = &gpu3DNull;
cur3DCore = GPU3D_NULL;
CurrentRenderer = _baseRenderer;
CurrentRenderer = BaseRenderer;
}
}
void Render3D_DeInit()
{
gpu3D->NDS_3D_Close();
delete _baseRenderer;
_baseRenderer = NULL;
delete BaseRenderer;
BaseRenderer = NULL;
}
bool NDS_3D_ChangeCore(int newCore)
@ -87,7 +83,7 @@ bool NDS_3D_ChangeCore(int newCore)
gpu3D->NDS_3D_Close();
gpu3D = &gpu3DNull;
cur3DCore = GPU3D_NULL;
CurrentRenderer = _baseRenderer;
CurrentRenderer = BaseRenderer;
Render3D *newRenderer = newRenderInterface->NDS_3D_Init();
if (newRenderer == NULL)
@ -103,41 +99,21 @@ bool NDS_3D_ChangeCore(int newCore)
return result;
}
Render3D* Default3D_Init()
Render3D* Render3DBaseCreate()
{
_baseRenderer->Reset();
return _baseRenderer;
BaseRenderer->Reset();
return BaseRenderer;
}
void Default3D_Close()
void Render3DBaseDestroy()
{
if (CurrentRenderer != _baseRenderer)
if (CurrentRenderer != BaseRenderer)
{
delete CurrentRenderer;
CurrentRenderer = NULL;
CurrentRenderer = BaseRenderer;
}
}
void Default3D_Reset()
{
CurrentRenderer->Reset();
}
void Default3D_Render()
{
CurrentRenderer->Render(gfx3d);
}
void Default3D_RenderFinish()
{
CurrentRenderer->RenderFinish();
}
void Default3D_VramReconfigureSignal()
{
CurrentRenderer->VramReconfigureSignal();
}
Render3D::Render3D()
{
_renderID = RENDERID_NULL;
@ -160,7 +136,6 @@ Render3D::Render3D()
Render3D::~Render3D()
{
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
TexCache_Reset();
}
@ -309,7 +284,6 @@ Render3DError Render3D::Reset()
memset(this->clearImageDepthBuffer, 0, sizeof(this->clearImageDepthBuffer));
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_convertedScreen));
TexCache_Reset();

View File

@ -28,28 +28,9 @@ class Render3D;
typedef struct Render3DInterface
{
// The name of the plugin, this name will appear in the plugins list
const char *name;
//called once when the plugin starts up
Render3D* (*NDS_3D_Init)();
//called when the plugin shuts down
void (*NDS_3D_Close)();
//called when the emulator resets
void (*NDS_3D_Reset)();
//called when the renderer should do its job and render the current display lists
void (*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 (*NDS_3D_RenderFinish)();
//called when the emulator reconfigures its vram. you may need to invalidate your texture cache.
void (*NDS_3D_VramReconfigureSignal)();
const char *name; // The name of the renderer.
Render3D* (*NDS_3D_Init)(); // Called when the renderer is created.
void (*NDS_3D_Close)(); // Called when the renderer is destroyed.
} GPU3DInterface;
@ -63,15 +44,12 @@ extern GPU3DInterface *core3DList[];
extern GPU3DInterface gpu3DNull;
// Extern pointer
extern Render3D *BaseRenderer;
extern Render3D *CurrentRenderer;
extern GPU3DInterface *gpu3D;
Render3D* Default3D_Init();
void Default3D_Close();
void Default3D_Reset();
void Default3D_Render();
void Default3D_RenderFinish();
void Default3D_VramReconfigureSignal();
Render3D* Render3DBaseCreate();
void Render3DBaseDestroy();
void Render3D_Init();
void Render3D_DeInit();
@ -153,10 +131,15 @@ public:
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
virtual Render3DError ClearFramebuffer(const GFX3D_State &renderState);
virtual Render3DError Reset();
virtual Render3DError Render(const GFX3D &engine);
virtual Render3DError RenderFinish();
virtual Render3DError VramReconfigureSignal();
virtual Render3DError Reset(); // Called when the emulator resets.
virtual Render3DError Render(const GFX3D &engine); // Called when the renderer should do its job and render the current display lists.
virtual Render3DError RenderFinish(); // 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.)
virtual Render3DError VramReconfigureSignal(); // Called when the emulator reconfigures its VRAM. Ypu may need to invalidate your texture cache.
};
#endif

View File

@ -34,21 +34,31 @@ enum TexCache_TexFormat
class TexCacheItem;
typedef std::multimap<u32,TexCacheItem*> TTexCacheItemMultimap;
typedef void (*TexCacheItemDeleteCallback)(TexCacheItem *texItem, void *param1, void *param2);
class TexCacheItem
{
private:
TexCacheItemDeleteCallback _deleteCallback;
void *_deleteCallbackParam1;
void *_deleteCallbackParam2;
public:
TexCacheItem()
: decode_len(0)
, decoded(NULL)
, suspectedInvalid(false)
, assumedInvalid(false)
, deleteCallback(NULL)
, _deleteCallback(NULL)
, _deleteCallbackParam1(NULL)
, _deleteCallbackParam2(NULL)
, cacheFormat(TexFormat_None)
{}
~TexCacheItem() {
~TexCacheItem()
{
delete[] decoded;
if(deleteCallback) deleteCallback(this);
if(_deleteCallback != NULL) _deleteCallback(this, this->_deleteCallbackParam1, this->_deleteCallbackParam2);
}
u32 decode_len;
u32 mode;
@ -64,8 +74,6 @@ public:
float invSizeX, invSizeY;
u64 texid; //used by ogl renderer for the texid
void (*deleteCallback)(TexCacheItem*);
TexCache_TexFormat cacheFormat;
struct Dump {
@ -77,6 +85,18 @@ public:
u8* texture;
u8 palette[256*2];
} dump;
TexCacheItemDeleteCallback GetDeleteCallback()
{
return this->_deleteCallback;
}
void SetDeleteCallback(TexCacheItemDeleteCallback callbackFunc, void *inParam1, void *inParam2)
{
this->_deleteCallback = callbackFunc;
this->_deleteCallbackParam1 = inParam1;
this->_deleteCallbackParam2 = inParam2;
}
};
void TexCache_Invalidate();