GPU: Finishing 3D rendering and flushing the 3D framebuffers are now split into separate operations.

- Fixes the background appearance when receiving items in Pokemon
Black/White 2. (Fixes SF bug #1624.)
This commit is contained in:
rogerman 2017-07-15 16:00:26 -07:00
parent 0f05656a17
commit eaa5210fb0
11 changed files with 221 additions and 163 deletions

View File

@ -5106,17 +5106,17 @@ GPUEngineA::GPUEngineA()
isLineCaptureNative[3][l] = true;
}
_3DFramebufferRGBA6665 = (FragmentColor *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(FragmentColor));
_3DFramebufferRGBA5551 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16));
_3DFramebufferMain = (FragmentColor *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(FragmentColor));
_3DFramebuffer16 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16));
_captureWorkingA16 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16));
_captureWorkingB16 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16));
gfx3d_Update3DFramebuffers(_3DFramebufferRGBA6665, _3DFramebufferRGBA5551);
gfx3d_Update3DFramebuffers(_3DFramebufferMain, _3DFramebuffer16);
}
GPUEngineA::~GPUEngineA()
{
free_aligned(this->_3DFramebufferRGBA6665);
free_aligned(this->_3DFramebufferRGBA5551);
free_aligned(this->_3DFramebufferMain);
free_aligned(this->_3DFramebuffer16);
free_aligned(this->_captureWorkingA16);
free_aligned(this->_captureWorkingB16);
gfx3d_Update3DFramebuffers(NULL, NULL);
@ -5166,8 +5166,8 @@ void GPUEngineA::Reset()
this->ResetCaptureLineStates();
this->SetDisplayByID(NDSDisplayID_Main);
memset(this->_3DFramebufferRGBA6665, 0, dispInfo.customWidth * dispInfo.customHeight * sizeof(FragmentColor));
memset(this->_3DFramebufferRGBA5551, 0, dispInfo.customWidth * dispInfo.customHeight * sizeof(u16));
memset(this->_3DFramebufferMain, 0, dispInfo.customWidth * dispInfo.customHeight * sizeof(FragmentColor));
memset(this->_3DFramebuffer16, 0, dispInfo.customWidth * dispInfo.customHeight * sizeof(u16));
memset(this->_captureWorkingA16, 0, dispInfo.customWidth * _gpuLargestDstLineCount * sizeof(u16));
memset(this->_captureWorkingB16, 0, dispInfo.customWidth * _gpuLargestDstLineCount * sizeof(u16));
}
@ -5226,14 +5226,14 @@ void GPUEngineA::ParseReg_DISPCAPCNT()
this->_dispCapCnt.srcA, this->_dispCapCnt.srcB);*/
}
FragmentColor* GPUEngineA::Get3DFramebufferRGBA6665() const
FragmentColor* GPUEngineA::Get3DFramebufferMain() const
{
return this->_3DFramebufferRGBA6665;
return this->_3DFramebufferMain;
}
u16* GPUEngineA::Get3DFramebufferRGBA5551() const
u16* GPUEngineA::Get3DFramebuffer16() const
{
return this->_3DFramebufferRGBA5551;
return this->_3DFramebuffer16;
}
void* GPUEngineA::GetCustomVRAMBlockPtr(const size_t blockID)
@ -5245,29 +5245,29 @@ void GPUEngineA::SetCustomFramebufferSize(size_t w, size_t h)
{
this->GPUEngineBase::SetCustomFramebufferSize(w, h);
FragmentColor *oldColorRGBA6665Buffer = this->_3DFramebufferRGBA6665;
u16 *oldColorRGBA5551Buffer = this->_3DFramebufferRGBA5551;
FragmentColor *old3DFramebufferMain = this->_3DFramebufferMain;
u16 *old3DFramebuffer16 = this->_3DFramebuffer16;
u16 *oldCaptureWorkingA16 = this->_captureWorkingA16;
u16 *oldCaptureWorkingB16 = this->_captureWorkingB16;
FragmentColor *newColorRGBA6665Buffer = (FragmentColor *)malloc_alignedCacheLine(w * h * sizeof(FragmentColor));
u16 *newColorRGBA5551 = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16));
FragmentColor *new3DFramebufferMain = (FragmentColor *)malloc_alignedCacheLine(w * h * sizeof(FragmentColor));
u16 *new3DFramebuffer16 = (u16 *)malloc_alignedCacheLine(w * h * sizeof(u16));
u16 *newCaptureWorkingA16 = (u16 *)malloc_alignedCacheLine(w * _gpuLargestDstLineCount * sizeof(u16));
u16 *newCaptureWorkingB16 = (u16 *)malloc_alignedCacheLine(w * _gpuLargestDstLineCount * sizeof(u16));
this->_3DFramebufferRGBA6665 = newColorRGBA6665Buffer;
this->_3DFramebufferRGBA5551 = newColorRGBA5551;
this->_3DFramebufferMain = new3DFramebufferMain;
this->_3DFramebuffer16 = new3DFramebuffer16;
this->_captureWorkingA16 = newCaptureWorkingA16;
this->_captureWorkingB16 = newCaptureWorkingB16;
gfx3d_Update3DFramebuffers(this->_3DFramebufferRGBA6665, this->_3DFramebufferRGBA5551);
gfx3d_Update3DFramebuffers(this->_3DFramebufferMain, this->_3DFramebuffer16);
this->_VRAMCustomBlockPtr[0] = (u16 *)GPU->GetCustomVRAMBuffer();
this->_VRAMCustomBlockPtr[1] = (u16 *)this->_VRAMCustomBlockPtr[0] + (1 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->_VRAMCustomBlockPtr[2] = (u16 *)this->_VRAMCustomBlockPtr[0] + (2 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
this->_VRAMCustomBlockPtr[3] = (u16 *)this->_VRAMCustomBlockPtr[0] + (3 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w);
free_aligned(oldColorRGBA6665Buffer);
free_aligned(oldColorRGBA5551Buffer);
free_aligned(old3DFramebufferMain);
free_aligned(old3DFramebuffer16);
free_aligned(oldCaptureWorkingA16);
free_aligned(oldCaptureWorkingB16);
}
@ -5641,7 +5641,7 @@ void GPUEngineA::_RenderLine_DisplayCapture(const u16 l)
}
static CACHE_ALIGN u16 fifoLine16[GPU_FRAMEBUFFER_NATIVE_WIDTH];
const u16 *srcA16 = (DISPCAPCNT.SrcA == 0) ? ((OUTPUTFORMAT != NDSColorFormat_BGR555_Rev) ? this->_captureWorkingA16 : (u16 *)compInfo.target.lineColorHead) : this->_3DFramebufferRGBA5551 + compInfo.line.blockOffsetCustom;
const u16 *srcA16 = (DISPCAPCNT.SrcA == 0) ? ((OUTPUTFORMAT != NDSColorFormat_BGR555_Rev) ? this->_captureWorkingA16 : (u16 *)compInfo.target.lineColorHead) : this->_3DFramebuffer16 + compInfo.line.blockOffsetCustom;
const u16 *srcB16 = (DISPCAPCNT.SrcB == 0) ? vram16 : fifoLine16;
switch (DISPCAPCNT.CaptureSrc)
@ -6923,13 +6923,8 @@ void GPUSubsystem::Reset()
void GPUSubsystem::ForceRender3DFinishAndFlush(bool willFlush)
{
bool need3DDisplayFramebuffer;
bool need3DCaptureFramebuffer;
CurrentRenderer->GetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer);
CurrentRenderer->SetFramebufferFlushStates(willFlush, willFlush);
CurrentRenderer->RenderFinish();
CurrentRenderer->SetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer);
CurrentRenderer->RenderFlush(willFlush, willFlush);
}
void GPUSubsystem::ForceFrameStop()
@ -7463,18 +7458,20 @@ void GPUSubsystem::RenderLine(const size_t l)
// means that we need to check the states at that particular time to ensure that the 3D renderer
// finishes before we read the 3D framebuffer. Otherwise, the map will render incorrectly.
if (CurrentRenderer->GetRenderNeedsFinish())
const bool need3DDisplayFramebuffer = this->_engineMain->WillRender3DLayer();
const bool need3DCaptureFramebuffer = this->_engineMain->WillCapture3DLayerDirect(l);
if (need3DCaptureFramebuffer || need3DDisplayFramebuffer)
{
const bool need3DDisplayFramebuffer = this->_engineMain->WillRender3DLayer();
const bool need3DCaptureFramebuffer = this->_engineMain->WillCapture3DLayerDirect(l);
if (need3DDisplayFramebuffer || need3DCaptureFramebuffer)
if (CurrentRenderer->GetRenderNeedsFinish())
{
CurrentRenderer->SetFramebufferFlushStates(need3DDisplayFramebuffer, need3DCaptureFramebuffer);
CurrentRenderer->RenderFinish();
CurrentRenderer->SetRenderNeedsFinish(false);
this->_event->DidRender3DEnd();
}
CurrentRenderer->RenderFlush(need3DDisplayFramebuffer && CurrentRenderer->GetRenderNeedsFlushMain(),
need3DCaptureFramebuffer && CurrentRenderer->GetRenderNeedsFlush16());
}
this->_engineMain->RenderLine<OUTPUTFORMAT>(l);

View File

@ -1517,8 +1517,8 @@ protected:
CACHE_ALIGN u16 _VRAMNativeBlockCaptureCopy[GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_VRAM_BLOCK_LINES * 4];
u16 *_VRAMNativeBlockCaptureCopyPtr[4];
FragmentColor *_3DFramebufferRGBA6665;
u16 *_3DFramebufferRGBA5551;
FragmentColor *_3DFramebufferMain;
u16 *_3DFramebuffer16;
u16 *_VRAMNativeBlockPtr[4];
void *_VRAMCustomBlockPtr[4];
@ -1562,8 +1562,8 @@ public:
void ParseReg_DISPCAPCNT();
void* GetCustomVRAMBlockPtr(const size_t blockID);
FragmentColor* Get3DFramebufferRGBA6665() const;
u16* Get3DFramebufferRGBA5551() const;
FragmentColor* Get3DFramebufferMain() const;
u16* Get3DFramebuffer16() const;
virtual void SetCustomFramebufferSize(size_t w, size_t h);
bool WillRender3DLayer();

View File

@ -1168,9 +1168,9 @@ void OpenGLRenderer::SetVersion(unsigned int major, unsigned int minor, unsigned
this->versionRevision = revision;
}
Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551)
Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16)
{
if ( ((dstFramebuffer == NULL) && (dstRGBA5551 == NULL)) || (srcFramebuffer == NULL) )
if ( ((dstFramebufferMain == NULL) && (dstFramebuffer16 == NULL)) || (srcFramebuffer == NULL) )
{
return RENDER3DERROR_NOERR;
}
@ -1187,7 +1187,7 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
{
if ( (dstFramebuffer != NULL) && (dstRGBA5551 != NULL) )
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
{
#ifdef ENABLE_SSE2
const size_t ssePixCount = pixCount - (pixCount % 8);
@ -1196,9 +1196,9 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
_mm_store_si128( (__m128i *)(dstFramebuffer + i + 0), ColorspaceConvert8888To6665_SSE2<true>(srcColorLo) );
_mm_store_si128( (__m128i *)(dstFramebuffer + i + 4), ColorspaceConvert8888To6665_SSE2<true>(srcColorHi) );
_mm_store_si128( (__m128i *)(dstRGBA5551 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 0), ColorspaceConvert8888To6665_SSE2<true>(srcColorLo) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 4), ColorspaceConvert8888To6665_SSE2<true>(srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
}
#endif
@ -1207,22 +1207,27 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
#endif
for (; i < pixCount; i++)
{
dstFramebuffer[i].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[i]);
dstRGBA5551[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
dstFramebufferMain[i].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[i]);
dstFramebuffer16[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
}
this->_renderNeedsFlushMain = false;
this->_renderNeedsFlush16 = false;
}
else if (dstFramebuffer != NULL)
else if (dstFramebufferMain != NULL)
{
ColorspaceConvertBuffer8888To6665<true, false>((u32 *)srcFramebuffer, (u32 *)dstFramebuffer, pixCount);
ColorspaceConvertBuffer8888To6665<true, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, pixCount);
this->_renderNeedsFlushMain = false;
}
else
{
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstRGBA5551, pixCount);
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstFramebuffer16, pixCount);
this->_renderNeedsFlush16 = false;
}
}
else if (this->_outputFormat == NDSColorFormat_BGR888_Rev)
{
if ( (dstFramebuffer != NULL) && (dstRGBA5551 != NULL) )
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
{
#ifdef ENABLE_SSE2
const size_t ssePixCount = pixCount - (pixCount % 8);
@ -1231,9 +1236,9 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
_mm_store_si128( (__m128i *)(dstFramebuffer + i + 0), srcColorLo );
_mm_store_si128( (__m128i *)(dstFramebuffer + i + 4), srcColorHi );
_mm_store_si128( (__m128i *)(dstRGBA5551 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 0), srcColorLo );
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 4), srcColorHi );
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
}
#endif
@ -1242,17 +1247,22 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
#endif
for (; i < pixCount; i++)
{
dstFramebuffer[i].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[i]);
dstRGBA5551[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
dstFramebufferMain[i].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[i]);
dstFramebuffer16[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
}
this->_renderNeedsFlushMain = false;
this->_renderNeedsFlush16 = false;
}
else if (dstFramebuffer != NULL)
else if (dstFramebufferMain != NULL)
{
memcpy(dstFramebuffer, srcFramebuffer, this->_framebufferWidth * this->_framebufferHeight * sizeof(FragmentColor));
memcpy(dstFramebufferMain, srcFramebuffer, this->_framebufferWidth * this->_framebufferHeight * sizeof(FragmentColor));
this->_renderNeedsFlushMain = false;
}
else
{
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstRGBA5551, pixCount);
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstFramebuffer16, pixCount);
this->_renderNeedsFlush16 = false;
}
}
}
@ -1262,7 +1272,7 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
{
if ( (dstFramebuffer != NULL) && (dstRGBA5551 != NULL) )
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
{
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir += this->_framebufferWidth, iw -= this->_framebufferWidth)
{
@ -1274,9 +1284,9 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 0));
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 4));
_mm_store_si128( (__m128i *)(dstFramebuffer + iw + 0), ColorspaceConvert8888To6665_SSE2<true>(srcColorLo) );
_mm_store_si128( (__m128i *)(dstFramebuffer + iw + 4), ColorspaceConvert8888To6665_SSE2<true>(srcColorHi) );
_mm_store_si128( (__m128i *)(dstRGBA5551 + iw), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 0), ColorspaceConvert8888To6665_SSE2<true>(srcColorLo) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 4), ColorspaceConvert8888To6665_SSE2<true>(srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebuffer16 + iw), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
}
#endif
@ -1285,29 +1295,36 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
#endif
for (; x < pixCount; x++, ir++, iw++)
{
dstFramebuffer[iw].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[ir]);
dstRGBA5551[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
dstFramebufferMain[iw].color = ColorspaceConvert8888To6665<true>(srcFramebuffer[ir]);
dstFramebuffer16[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
}
}
this->_renderNeedsFlushMain = false;
this->_renderNeedsFlush16 = false;
}
else if (dstFramebuffer != NULL)
else if (dstFramebufferMain != NULL)
{
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir += this->_framebufferWidth, iw -= this->_framebufferWidth)
{
ColorspaceConvertBuffer8888To6665<true, false>((u32 *)srcFramebuffer + ir, (u32 *)dstFramebuffer + iw, pixCount);
ColorspaceConvertBuffer8888To6665<true, false>((u32 *)srcFramebuffer + ir, (u32 *)dstFramebufferMain + iw, pixCount);
}
this->_renderNeedsFlushMain = false;
}
else
{
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir += this->_framebufferWidth, iw -= this->_framebufferWidth)
{
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer + ir, dstRGBA5551 + iw, pixCount);
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer + ir, dstFramebuffer16 + iw, pixCount);
}
this->_renderNeedsFlush16 = false;
}
}
else if (this->_outputFormat == NDSColorFormat_BGR888_Rev)
{
if ( (dstFramebuffer != NULL) && (dstRGBA5551 != NULL) )
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
{
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir += this->_framebufferWidth, iw -= this->_framebufferWidth)
{
@ -1319,9 +1336,9 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 0));
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 4));
_mm_store_si128( (__m128i *)(dstFramebuffer + iw + 0), srcColorLo );
_mm_store_si128( (__m128i *)(dstFramebuffer + iw + 4), srcColorHi );
_mm_store_si128( (__m128i *)(dstRGBA5551 + iw), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 0), srcColorLo );
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 4), srcColorHi );
_mm_store_si128( (__m128i *)(dstFramebuffer16 + iw), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
}
#endif
@ -1330,16 +1347,19 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
#endif
for (; x < pixCount; x++, ir++, iw++)
{
dstFramebuffer[iw] = srcFramebuffer[ir];
dstRGBA5551[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
dstFramebufferMain[iw] = srcFramebuffer[ir];
dstFramebuffer16[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
}
}
this->_renderNeedsFlushMain = false;
this->_renderNeedsFlush16 = false;
}
else if (dstFramebuffer != NULL)
else if (dstFramebufferMain != NULL)
{
const size_t lineBytes = this->_framebufferWidth * sizeof(FragmentColor);
const FragmentColor *__restrict srcPtr = srcFramebuffer;
FragmentColor *__restrict dstPtr = dstFramebuffer + ((this->_framebufferHeight - 1) * this->_framebufferWidth);
FragmentColor *__restrict dstPtr = dstFramebufferMain + ((this->_framebufferHeight - 1) * this->_framebufferWidth);
for (size_t y = 0; y < this->_framebufferHeight; y++)
{
@ -1347,13 +1367,17 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
srcPtr += this->_framebufferWidth;
dstPtr -= this->_framebufferWidth;
}
this->_renderNeedsFlushMain = false;
}
else
{
for (size_t y = 0, ir = 0, iw = ((this->_framebufferHeight - 1) * this->_framebufferWidth); y < this->_framebufferHeight; y++, ir += this->_framebufferWidth, iw -= this->_framebufferWidth)
{
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer + ir, dstRGBA5551 + iw, pixCount);
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer + ir, dstFramebuffer16 + iw, pixCount);
}
this->_renderNeedsFlush16 = false;
}
}
}
@ -1361,15 +1385,16 @@ Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const FragmentColor
return RENDER3DERROR_NOERR;
}
Render3DError OpenGLRenderer::FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551)
Render3DError OpenGLRenderer::FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16)
{
if (this->willConvertFramebufferOnGPU)
{
return Render3D::FlushFramebuffer(srcFramebuffer, NULL, dstRGBA5551);
this->_renderNeedsFlushMain = false;
return Render3D::FlushFramebuffer(srcFramebuffer, NULL, dstFramebuffer16);
}
else
{
return this->_FlushFramebufferConvertOnCPU(srcFramebuffer, dstFramebuffer, dstRGBA5551);
return this->_FlushFramebufferConvertOnCPU(srcFramebuffer, dstFramebufferMain, dstFramebuffer16);
}
return RENDER3DERROR_NOERR;
@ -1377,7 +1402,7 @@ Render3DError OpenGLRenderer::FlushFramebuffer(const FragmentColor *__restrict s
FragmentColor* OpenGLRenderer::GetFramebuffer()
{
return (this->willConvertFramebufferOnGPU) ? this->_mappedFramebuffer : GPU->GetEngineMain()->Get3DFramebufferRGBA6665();
return (this->willConvertFramebufferOnGPU) ? this->_mappedFramebuffer : GPU->GetEngineMain()->Get3DFramebufferMain();
}
OpenGLTexture* OpenGLRenderer::GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing)
@ -3427,35 +3452,46 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
return OGLERROR_NOERR;
}
FragmentColor *framebufferMain = (this->_willFlushFramebufferRGBA6665) ? GPU->GetEngineMain()->Get3DFramebufferRGBA6665() : NULL;
u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL;
if ( (framebufferMain != NULL) || (framebufferRGBA5551 != NULL) )
if(!BEGINGL())
{
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
if (this->isPBOSupported)
{
this->_mappedFramebuffer = (FragmentColor *__restrict)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
this->FlushFramebuffer(this->_mappedFramebuffer, framebufferMain, framebufferRGBA5551);
}
else
{
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, this->_framebufferColor);
this->FlushFramebuffer(this->_framebufferColor, framebufferMain, framebufferRGBA5551);
}
ENDGL();
return OGLERROR_BEGINGL_FAILED;
}
if (this->isPBOSupported)
{
this->_mappedFramebuffer = (FragmentColor *__restrict)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
}
else
{
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_BGRA, GL_UNSIGNED_BYTE, this->_framebufferColor);
}
ENDGL();
this->_pixelReadNeedsFinish = false;
this->_renderNeedsFlushMain = true;
this->_renderNeedsFlush16 = true;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16)
{
FragmentColor *framebufferMain = (willFlushBuffer32) ? GPU->GetEngineMain()->Get3DFramebufferMain() : NULL;
u16 *framebuffer16 = (willFlushBuffer16) ? GPU->GetEngineMain()->Get3DFramebuffer16() : NULL;
if (this->isPBOSupported)
{
this->FlushFramebuffer(this->_mappedFramebuffer, framebufferMain, framebuffer16);
}
else
{
this->FlushFramebuffer(this->_framebufferColor, framebufferMain, framebuffer16);
}
return RENDER3DERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
{
OGLRenderRef &OGLRef = *this->ref;
@ -5059,23 +5095,28 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
return OGLERROR_NOERR;
}
FragmentColor *framebufferMain = (this->_willFlushFramebufferRGBA6665) ? GPU->GetEngineMain()->Get3DFramebufferRGBA6665() : NULL;
u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL;
if ( (framebufferMain != NULL) || (framebufferRGBA5551 != NULL) )
if(!BEGINGL())
{
if(!BEGINGL())
{
return OGLERROR_BEGINGL_FAILED;
}
this->_mappedFramebuffer = (FragmentColor *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
this->FlushFramebuffer(this->_mappedFramebuffer, framebufferMain, framebufferRGBA5551);
ENDGL();
return OGLERROR_BEGINGL_FAILED;
}
this->_mappedFramebuffer = (FragmentColor *__restrict)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
ENDGL();
this->_pixelReadNeedsFinish = false;
this->_renderNeedsFlushMain = true;
this->_renderNeedsFlush16 = true;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_2_1::RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16)
{
FragmentColor *framebufferMain = (willFlushBuffer32) ? GPU->GetEngineMain()->Get3DFramebufferMain() : NULL;
u16 *framebuffer16 = (willFlushBuffer16) ? GPU->GetEngineMain()->Get3DFramebuffer16() : NULL;
this->FlushFramebuffer(this->_mappedFramebuffer, framebufferMain, framebuffer16);
return RENDER3DERROR_NOERR;
}

View File

@ -598,7 +598,7 @@ private:
unsigned int versionRevision;
private:
Render3DError _FlushFramebufferConvertOnCPU(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551);
Render3DError _FlushFramebufferConvertOnCPU(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
protected:
// OpenGL-specific References
@ -619,7 +619,7 @@ protected:
bool _pixelReadNeedsFinish;
size_t _currentPolyIndex;
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551);
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing);
// OpenGL-specific methods
@ -762,6 +762,7 @@ public:
virtual Render3DError UpdateToonTable(const u16 *toonTableBuffer);
virtual Render3DError Reset();
virtual Render3DError RenderFinish();
virtual Render3DError RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
};
@ -838,6 +839,7 @@ protected:
public:
virtual Render3DError RenderFinish();
virtual Render3DError RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16);
};
#endif

View File

@ -283,8 +283,8 @@ static float normalTable[1024];
#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9))
// Color buffer that is filled by the 3D renderer and is read by the GPU engine.
static FragmentColor *_gfx3d_colorRGBA6665 = NULL;
static u16 *_gfx3d_colorRGBA5551 = NULL;
static FragmentColor *_gfx3d_colorMain = NULL;
static u16 *_gfx3d_color16 = NULL;
// Matrix stack handling
//TODO: decouple stack pointers from matrix stack type
@ -2379,8 +2379,8 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
}
else
{
memset(GPU->GetEngineMain()->Get3DFramebufferRGBA6665(), 0, GPU->GetCustomFramebufferWidth() * GPU->GetCustomFramebufferHeight() * sizeof(FragmentColor));
memset(GPU->GetEngineMain()->Get3DFramebufferRGBA5551(), 0, GPU->GetCustomFramebufferWidth() * GPU->GetCustomFramebufferHeight() * sizeof(u16));
memset(GPU->GetEngineMain()->Get3DFramebufferMain(), 0, GPU->GetCustomFramebufferWidth() * GPU->GetCustomFramebufferHeight() * sizeof(FragmentColor));
memset(GPU->GetEngineMain()->Get3DFramebuffer16(), 0, GPU->GetCustomFramebufferWidth() * GPU->GetCustomFramebufferHeight() * sizeof(u16));
CurrentRenderer->SetRenderNeedsFinish(false);
GPU->GetEventHandler()->DidRender3DEnd();
}
@ -2569,14 +2569,14 @@ SFORMAT SF_GFX3D[]={
{ "GTVC", 4, 1, &tempVertInfo.count},
{ "GTVM", 4, 4, tempVertInfo.map},
{ "GTVF", 4, 1, &tempVertInfo.first},
{ "G3CX", 1, 4*GPU_FRAMEBUFFER_NATIVE_WIDTH*GPU_FRAMEBUFFER_NATIVE_HEIGHT, _gfx3d_colorRGBA6665},
{ "G3CX", 1, 4*GPU_FRAMEBUFFER_NATIVE_WIDTH*GPU_FRAMEBUFFER_NATIVE_HEIGHT, _gfx3d_colorMain},
{ 0 }
};
void gfx3d_Update3DFramebuffers(FragmentColor *framebufferRGBA6665, u16 *framebufferRGBA5551)
void gfx3d_Update3DFramebuffers(FragmentColor *framebufferMain, u16 *framebuffer16)
{
_gfx3d_colorRGBA6665 = framebufferRGBA6665;
_gfx3d_colorRGBA5551 = framebufferRGBA5551;
_gfx3d_colorMain = framebufferMain;
_gfx3d_color16 = framebuffer16;
}
//-------------savestate

View File

@ -727,7 +727,7 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst);
struct SFORMAT;
extern SFORMAT SF_GFX3D[];
void gfx3d_Update3DFramebuffers(FragmentColor *framebufferRGBA6665, u16 *framebufferRGBA5551);
void gfx3d_Update3DFramebuffers(FragmentColor *framebufferMain, u16 *framebuffer16);
void gfx3d_savestate(EMUFILE* os);
bool gfx3d_loadstate(EMUFILE* is, int size);

View File

@ -2234,7 +2234,7 @@ public:
char temp [256];
sprintf(temp, " " /*"mismatch at "*/ "byte %d(0x%X at 0x%X): %d(0x%X) != %d(0x%X)\n", i, i, dst, *src,*src, *dst,*dst);
if(ptr == dispInfo.masterNativeBuffer || ptr == dispInfo.masterCustomBuffer || ptr == GPU->GetEngineMain()->Get3DFramebufferRGBA6665()) // ignore screen-only differences since frame skipping can cause them and it's probably ok
if(ptr == dispInfo.masterNativeBuffer || ptr == dispInfo.masterCustomBuffer || ptr == GPU->GetEngineMain()->Get3DFramebufferMain()) // ignore screen-only differences since frame skipping can cause them and it's probably ok
break;
differences.push_back(temp); // <-- probably the best place for a breakpoint

View File

@ -2128,10 +2128,6 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount)
this->RenderEdgeMarkingAndFog(this->postprocessParam[0]);
}
FragmentColor *framebufferMain = (this->_outputFormat == NDSColorFormat_BGR888_Rev) ? GPU->GetEngineMain()->Get3DFramebufferRGBA6665() : NULL;
u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL;
this->FlushFramebuffer(this->_framebufferColor, framebufferMain, framebufferRGBA5551);
}
return RENDER3DERROR_NOERR;
@ -2174,9 +2170,17 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
}
}
FragmentColor *framebufferMain = (this->_outputFormat == NDSColorFormat_BGR888_Rev) ? GPU->GetEngineMain()->Get3DFramebufferRGBA6665() : NULL;
u16 *framebufferRGBA5551 = (this->_willFlushFramebufferRGBA5551) ? GPU->GetEngineMain()->Get3DFramebufferRGBA5551() : NULL;
this->FlushFramebuffer(this->_framebufferColor, framebufferMain, framebufferRGBA5551);
this->_renderNeedsFlushMain = true;
this->_renderNeedsFlush16 = true;
return RENDER3DERROR_NOERR;
}
Render3DError SoftRasterizerRenderer::RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16)
{
FragmentColor *framebufferMain = (this->_outputFormat == NDSColorFormat_BGR888_Rev) ? GPU->GetEngineMain()->Get3DFramebufferMain() : NULL;
u16 *framebuffer16 = (willFlushBuffer16) ? GPU->GetEngineMain()->Get3DFramebuffer16() : NULL;
this->FlushFramebuffer(this->_framebufferColor, framebufferMain, framebuffer16);
return RENDER3DERROR_NOERR;
}

View File

@ -142,6 +142,7 @@ public:
virtual Render3DError Reset();
virtual Render3DError Render(const GFX3D &engine);
virtual Render3DError RenderFinish();
virtual Render3DError RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16);
virtual Render3DError SetFramebufferSize(size_t w, size_t h);
};

View File

@ -293,8 +293,8 @@ Render3D::Render3D()
_internalRenderingFormat = NDSColorFormat_BGR666_Rev;
_outputFormat = NDSColorFormat_BGR666_Rev;
_renderNeedsFinish = false;
_willFlushFramebufferRGBA6665 = true;
_willFlushFramebufferRGBA5551 = true;
_renderNeedsFlushMain = false;
_renderNeedsFlush16 = false;
_textureScalingFactor = 1;
_textureDeposterize = false;
@ -366,7 +366,7 @@ Render3DError Render3D::SetFramebufferSize(size_t w, size_t h)
this->_framebufferWidth = w;
this->_framebufferHeight = h;
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = GPU->GetEngineMain()->Get3DFramebufferRGBA6665(); // Just use the buffer that is already present on the main GPU engine
this->_framebufferColor = GPU->GetEngineMain()->Get3DFramebufferMain(); // Just use the buffer that is already present on the main GPU engine
return RENDER3DERROR_NOERR;
}
@ -382,18 +382,6 @@ NDSColorFormat Render3D::GetColorFormat() const
return this->_outputFormat;
}
void Render3D::GetFramebufferFlushStates(bool &willFlushRGBA6665, bool &willFlushRGBA5551)
{
willFlushRGBA6665 = this->_willFlushFramebufferRGBA6665;
willFlushRGBA5551 = this->_willFlushFramebufferRGBA5551;
}
void Render3D::SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushRGBA5551)
{
this->_willFlushFramebufferRGBA6665 = willFlushRGBA6665;
this->_willFlushFramebufferRGBA5551 = willFlushRGBA5551;
}
bool Render3D::GetRenderNeedsFinish() const
{
return this->_renderNeedsFinish;
@ -404,6 +392,16 @@ void Render3D::SetRenderNeedsFinish(const bool renderNeedsFinish)
this->_renderNeedsFinish = renderNeedsFinish;
}
bool Render3D::GetRenderNeedsFlushMain() const
{
return this->_renderNeedsFlushMain;
}
bool Render3D::GetRenderNeedsFlush16() const
{
return this->_renderNeedsFlush16;
}
void Render3D::SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth)
{
const bool isScaleValid = ( (scalingFactor == 2) || (scalingFactor == 4) );
@ -483,42 +481,46 @@ Render3DError Render3D::EndRender(const u64 frameCount)
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551)
Render3DError Render3D::FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16)
{
if ( (dstFramebuffer == NULL) && (dstRGBA5551 == NULL) )
if ( (dstFramebufferMain == NULL) && (dstFramebuffer16 == NULL) )
{
return RENDER3DERROR_NOERR;
}
const size_t pixCount = this->_framebufferWidth * this->_framebufferHeight;
if (dstFramebuffer != NULL)
if (dstFramebufferMain != NULL)
{
if ( (this->_internalRenderingFormat == NDSColorFormat_BGR888_Rev) && (this->_outputFormat == NDSColorFormat_BGR666_Rev) )
{
ColorspaceConvertBuffer8888To6665<false, false>((u32 *)srcFramebuffer, (u32 *)dstFramebuffer, pixCount);
ColorspaceConvertBuffer8888To6665<false, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, pixCount);
}
else if ( (this->_internalRenderingFormat == NDSColorFormat_BGR666_Rev) && (this->_outputFormat == NDSColorFormat_BGR888_Rev) )
{
ColorspaceConvertBuffer6665To8888<false, false>((u32 *)srcFramebuffer, (u32 *)dstFramebuffer, pixCount);
ColorspaceConvertBuffer6665To8888<false, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, pixCount);
}
else if ( ((this->_internalRenderingFormat == NDSColorFormat_BGR666_Rev) && (this->_outputFormat == NDSColorFormat_BGR666_Rev)) ||
((this->_internalRenderingFormat == NDSColorFormat_BGR888_Rev) && (this->_outputFormat == NDSColorFormat_BGR888_Rev)) )
{
memcpy(dstFramebuffer, srcFramebuffer, pixCount * sizeof(FragmentColor));
memcpy(dstFramebufferMain, srcFramebuffer, pixCount * sizeof(FragmentColor));
}
this->_renderNeedsFlushMain = false;
}
if (dstRGBA5551 != NULL)
if (dstFramebuffer16 != NULL)
{
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
{
ColorspaceConvertBuffer6665To5551<false, false>((u32 *)srcFramebuffer, dstRGBA5551, pixCount);
ColorspaceConvertBuffer6665To5551<false, false>((u32 *)srcFramebuffer, dstFramebuffer16, pixCount);
}
else if (this ->_outputFormat == NDSColorFormat_BGR888_Rev)
{
ColorspaceConvertBuffer8888To5551<false, false>((u32 *)srcFramebuffer, dstRGBA5551, pixCount);
ColorspaceConvertBuffer8888To5551<false, false>((u32 *)srcFramebuffer, dstFramebuffer16, pixCount);
}
this->_renderNeedsFlush16 = false;
}
return RENDER3DERROR_NOERR;
@ -645,8 +647,9 @@ Render3DError Render3D::Reset()
memset(this->clearImagePolyIDBuffer, 0, sizeof(this->clearImagePolyIDBuffer));
memset(this->clearImageFogBuffer, 0, sizeof(this->clearImageFogBuffer));
this->_willFlushFramebufferRGBA6665 = true;
this->_willFlushFramebufferRGBA5551 = true;
this->_renderNeedsFinish = false;
this->_renderNeedsFlushMain = false;
this->_renderNeedsFlush16 = false;
texCache.Reset();
@ -688,6 +691,11 @@ Render3DError Render3D::RenderFinish()
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16)
{
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::VramReconfigureSignal()
{
texCache.Invalidate();

View File

@ -151,8 +151,8 @@ protected:
NDSColorFormat _internalRenderingFormat;
NDSColorFormat _outputFormat;
bool _renderNeedsFinish;
bool _willFlushFramebufferRGBA6665;
bool _willFlushFramebufferRGBA5551;
bool _renderNeedsFlushMain;
bool _renderNeedsFlush16;
size_t _textureScalingFactor;
bool _textureDeposterize;
@ -174,7 +174,7 @@ protected:
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError EndRender(const u64 frameCount);
virtual Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebuffer, u16 *__restrict dstRGBA5551);
virtual Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const u8 *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor6665, const FragmentAttributes &clearAttributes) const;
@ -208,6 +208,10 @@ public:
// and only release the block when 3D rendering is finished. (Before reading the 3D layer, be
// sure to always call this function.)
virtual Render3DError RenderFlush(bool willFlushBuffer32, bool willFlushBuffer16); // Called whenever the emulator needs the flushed results of the 3D renderer. Before calling this,
// the 3D renderer must be finished using RenderFinish() or confirmed already finished using
// GetRenderNeedsFinish().
virtual Render3DError VramReconfigureSignal(); // Called when the emulator reconfigures its VRAM. You may need to invalidate your texture cache.
virtual Render3DError SetFramebufferSize(size_t w, size_t h); // Called whenever the output framebuffer size changes.
@ -224,12 +228,13 @@ public:
virtual NDSColorFormat GetColorFormat() const; // The output color format of the 3D renderer.
virtual FragmentColor* GetFramebuffer();
virtual void GetFramebufferFlushStates(bool &willFlushRGBA6665, bool &willFlushRGBA5551);
virtual void SetFramebufferFlushStates(bool willFlushRGBA6665, bool willFlushRGBA5551);
bool GetRenderNeedsFinish() const;
void SetRenderNeedsFinish(const bool renderNeedsFinish);
bool GetRenderNeedsFlushMain() const;
bool GetRenderNeedsFlush16() const;
void SetTextureProcessingProperties(size_t scalingFactor, bool willDeposterize, bool willSmooth);
Render3DTexture* GetTextureByPolygonRenderIndex(size_t polyRenderIndex) const;
};