OpenGL Renderer: Rework how the output framebuffers work.
- The output framebuffers now bind their own FBOs rather than changing draw targets with glDrawBuffer(). - Rework the general FBO management. - Legacy OpenGL now outputs native RGBA color if FBOs are supported. This should give a minor performance increase on older GPUs. - The fixed-function pipeline can now flip the framebuffer on GPU. This greatly reduces the CPU usage when doing the final color conversion and gives a significant performance increase on ancient GPUs.
This commit is contained in:
parent
811e1de45e
commit
60385bd099
|
@ -692,8 +692,8 @@ void main()\n\
|
||||||
}\n\
|
}\n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
// Fragment shader for the final RGBA6665 formatted framebuffer, GLSL 1.00
|
// Fragment shader for the final BGRA6665 formatted framebuffer, GLSL 1.00
|
||||||
static const char *FramebufferOutputRGBA6665FragShader_100 = {"\
|
static const char *FramebufferOutputBGRA6665FragShader_100 = {"\
|
||||||
varying vec2 texCoord;\n\
|
varying vec2 texCoord;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform sampler2D texInFragColor;\n\
|
uniform sampler2D texInFragColor;\n\
|
||||||
|
@ -711,8 +711,8 @@ void main()\n\
|
||||||
}\n\
|
}\n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
// Fragment shader for the final RGBA8888 formatted framebuffer, GLSL 1.00
|
// Fragment shader for the final BGRA8888 formatted framebuffer, GLSL 1.00
|
||||||
static const char *FramebufferOutputRGBA8888FragShader_100 = {"\
|
static const char *FramebufferOutputBGRA8888FragShader_100 = {"\
|
||||||
varying vec2 texCoord;\n\
|
varying vec2 texCoord;\n\
|
||||||
\n\
|
\n\
|
||||||
uniform sampler2D texInFragColor;\n\
|
uniform sampler2D texInFragColor;\n\
|
||||||
|
@ -725,6 +725,35 @@ void main()\n\
|
||||||
}\n\
|
}\n\
|
||||||
"};
|
"};
|
||||||
|
|
||||||
|
// Fragment shader for the final RGBA6665 formatted framebuffer, GLSL 1.00
|
||||||
|
static const char *FramebufferOutputRGBA6665FragShader_100 = {"\
|
||||||
|
varying vec2 texCoord;\n\
|
||||||
|
\n\
|
||||||
|
uniform sampler2D texInFragColor;\n\
|
||||||
|
\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
vec4 colorRGBA6665 = texture2D(texInFragColor, texCoord);\n\
|
||||||
|
colorRGBA6665 = floor((colorRGBA6665 * 255.0) + 0.5);\n\
|
||||||
|
colorRGBA6665.rgb = floor(colorRGBA6665.rgb / 4.0);\n\
|
||||||
|
colorRGBA6665.a = floor(colorRGBA6665.a / 8.0);\n\
|
||||||
|
\n\
|
||||||
|
gl_FragColor = (colorRGBA6665 / 255.0);\n\
|
||||||
|
}\n\
|
||||||
|
"};
|
||||||
|
|
||||||
|
// Fragment shader for the final RGBA8888 formatted framebuffer, GLSL 1.00
|
||||||
|
static const char *FramebufferOutputRGBA8888FragShader_100 = {"\
|
||||||
|
varying vec2 texCoord;\n\
|
||||||
|
\n\
|
||||||
|
uniform sampler2D texInFragColor;\n\
|
||||||
|
\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
gl_FragColor = texture2D(texInFragColor, texCoord);\n\
|
||||||
|
}\n\
|
||||||
|
"};
|
||||||
|
|
||||||
bool IsOpenGLDriverVersionSupported(unsigned int checkVersionMajor, unsigned int checkVersionMinor, unsigned int checkVersionRevision)
|
bool IsOpenGLDriverVersionSupported(unsigned int checkVersionMajor, unsigned int checkVersionMinor, unsigned int checkVersionRevision)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
@ -1273,7 +1302,6 @@ OpenGLRenderer::OpenGLRenderer()
|
||||||
isShaderSupported = false;
|
isShaderSupported = false;
|
||||||
isVAOSupported = false;
|
isVAOSupported = false;
|
||||||
_isDepthLEqualPolygonFacingSupported = false;
|
_isDepthLEqualPolygonFacingSupported = false;
|
||||||
willFlipOnlyFramebufferOnGPU = false;
|
|
||||||
willFlipAndConvertFramebufferOnGPU = false;
|
willFlipAndConvertFramebufferOnGPU = false;
|
||||||
willUsePerSampleZeroDstPass = false;
|
willUsePerSampleZeroDstPass = false;
|
||||||
|
|
||||||
|
@ -1476,24 +1504,19 @@ bool OpenGLRenderer::IsVersionSupported(unsigned int checkVersionMajor, unsigned
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer::_FlushFramebufferFlipAndConvertOnCPU(const Color4u8 *__restrict srcFramebuffer,
|
template <bool SWAP_RB>
|
||||||
|
Render3DError OpenGLRenderer::_FlushFramebufferConvertOnCPU(const Color4u8 *__restrict srcFramebuffer,
|
||||||
Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16,
|
Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16,
|
||||||
bool doFramebufferFlip, bool doFramebufferConvert)
|
bool doFramebufferConvert)
|
||||||
{
|
{
|
||||||
if ( ((dstFramebufferMain == NULL) && (dstFramebuffer16 == NULL)) || (srcFramebuffer == NULL) )
|
if ( ((dstFramebufferMain == NULL) && (dstFramebuffer16 == NULL)) || (srcFramebuffer == NULL) )
|
||||||
{
|
{
|
||||||
return RENDER3DERROR_NOERR;
|
return RENDER3DERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert from 32-bit BGRA8888 format to 32-bit RGBA6665 reversed format. OpenGL
|
|
||||||
// stores pixels using a flipped Y-coordinate, so this needs to be flipped back
|
|
||||||
// to the DS Y-coordinate.
|
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
if (!doFramebufferFlip)
|
if ( !doFramebufferConvert || (this->_outputFormat == NDSColorFormat_BGR888_Rev) )
|
||||||
{
|
|
||||||
if (!doFramebufferConvert)
|
|
||||||
{
|
{
|
||||||
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
|
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
|
||||||
{
|
{
|
||||||
|
@ -1504,17 +1527,17 @@ Render3DError OpenGLRenderer::_FlushFramebufferFlipAndConvertOnCPU(const Color4u
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
|
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
|
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
|
||||||
|
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 0), ColorspaceCopy32_SSE2<false>(srcColorLo));
|
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 0), ColorspaceCopy32_SSE2<SWAP_RB>(srcColorLo));
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 4), ColorspaceCopy32_SSE2<false>(srcColorHi));
|
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 4), ColorspaceCopy32_SSE2<SWAP_RB>(srcColorHi));
|
||||||
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<false>(srcColorLo, srcColorHi) );
|
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<SWAP_RB>(srcColorLo, srcColorHi) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
#pragma LOOPVECTORIZE_DISABLE
|
||||||
#endif
|
#endif
|
||||||
for (; i < this->_framebufferPixCount; i++)
|
for (; i < this->_framebufferPixCount; i++)
|
||||||
{
|
{
|
||||||
dstFramebufferMain[i].value = ColorspaceCopy32<false>(srcFramebuffer[i]);
|
dstFramebufferMain[i].value = ColorspaceCopy32<SWAP_RB>(srcFramebuffer[i]);
|
||||||
dstFramebuffer16[i] = ColorspaceConvert8888To5551<false>(srcFramebuffer[i]);
|
dstFramebuffer16[i] = ColorspaceConvert8888To5551<SWAP_RB>(srcFramebuffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
this->_renderNeedsFlushMain = false;
|
||||||
|
@ -1522,18 +1545,16 @@ Render3DError OpenGLRenderer::_FlushFramebufferFlipAndConvertOnCPU(const Color4u
|
||||||
}
|
}
|
||||||
else if (dstFramebufferMain != NULL)
|
else if (dstFramebufferMain != NULL)
|
||||||
{
|
{
|
||||||
ColorspaceCopyBuffer32<false, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, this->_framebufferPixCount);
|
ColorspaceCopyBuffer32<SWAP_RB, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, this->_framebufferPixCount);
|
||||||
this->_renderNeedsFlushMain = false;
|
this->_renderNeedsFlushMain = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ColorspaceConvertBuffer8888To5551<false, false>((u32 *)srcFramebuffer, dstFramebuffer16, this->_framebufferPixCount);
|
ColorspaceConvertBuffer8888To5551<SWAP_RB, false>((u32 *)srcFramebuffer, dstFramebuffer16, this->_framebufferPixCount);
|
||||||
this->_renderNeedsFlush16 = false;
|
this->_renderNeedsFlush16 = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
|
||||||
{
|
|
||||||
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
|
|
||||||
{
|
{
|
||||||
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
|
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
|
||||||
{
|
{
|
||||||
|
@ -1544,17 +1565,17 @@ Render3DError OpenGLRenderer::_FlushFramebufferFlipAndConvertOnCPU(const Color4u
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
|
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
|
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
|
||||||
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 0), ColorspaceConvert8888To6665_SSE2<true>(srcColorLo) );
|
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 0), ColorspaceConvert8888To6665_SSE2<SWAP_RB>(srcColorLo) );
|
||||||
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 4), ColorspaceConvert8888To6665_SSE2<true>(srcColorHi) );
|
_mm_store_si128( (__m128i *)(dstFramebufferMain + i + 4), ColorspaceConvert8888To6665_SSE2<SWAP_RB>(srcColorHi) );
|
||||||
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
|
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<SWAP_RB>(srcColorLo, srcColorHi) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
#pragma LOOPVECTORIZE_DISABLE
|
||||||
#endif
|
#endif
|
||||||
for (; i < this->_framebufferPixCount; i++)
|
for (; i < this->_framebufferPixCount; i++)
|
||||||
{
|
{
|
||||||
dstFramebufferMain[i].value = ColorspaceConvert8888To6665<true>(srcFramebuffer[i]);
|
dstFramebufferMain[i].value = ColorspaceConvert8888To6665<SWAP_RB>(srcFramebuffer[i]);
|
||||||
dstFramebuffer16[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
|
dstFramebuffer16[i] = ColorspaceConvert8888To5551<SWAP_RB>(srcFramebuffer[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
this->_renderNeedsFlushMain = false;
|
||||||
|
@ -1562,219 +1583,23 @@ Render3DError OpenGLRenderer::_FlushFramebufferFlipAndConvertOnCPU(const Color4u
|
||||||
}
|
}
|
||||||
else if (dstFramebufferMain != NULL)
|
else if (dstFramebufferMain != NULL)
|
||||||
{
|
{
|
||||||
ColorspaceConvertBuffer8888To6665<true, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, this->_framebufferPixCount);
|
ColorspaceConvertBuffer8888To6665<SWAP_RB, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, this->_framebufferPixCount);
|
||||||
this->_renderNeedsFlushMain = false;
|
this->_renderNeedsFlushMain = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstFramebuffer16, this->_framebufferPixCount);
|
ColorspaceConvertBuffer8888To5551<SWAP_RB, false>((u32 *)srcFramebuffer, dstFramebuffer16, this->_framebufferPixCount);
|
||||||
this->_renderNeedsFlush16 = false;
|
this->_renderNeedsFlush16 = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this->_outputFormat == NDSColorFormat_BGR888_Rev)
|
|
||||||
{
|
|
||||||
if ( (dstFramebufferMain != NULL) && (dstFramebuffer16 != NULL) )
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_SSE2
|
|
||||||
const size_t ssePixCount = this->_framebufferPixCount - (this->_framebufferPixCount % 8);
|
|
||||||
for (; i < ssePixCount; i += 8)
|
|
||||||
{
|
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + i + 0));
|
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + i + 4));
|
|
||||||
|
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 0), ColorspaceCopy32_SSE2<true>(srcColorLo));
|
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + i + 4), ColorspaceCopy32_SSE2<true>(srcColorHi));
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebuffer16 + i), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
|
||||||
#endif
|
|
||||||
for (; i < this->_framebufferPixCount; i++)
|
|
||||||
{
|
|
||||||
dstFramebufferMain[i].value = ColorspaceCopy32<true>(srcFramebuffer[i]);
|
|
||||||
dstFramebuffer16[i] = ColorspaceConvert8888To5551<true>(srcFramebuffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
else if (dstFramebufferMain != NULL)
|
|
||||||
{
|
|
||||||
ColorspaceCopyBuffer32<true, false>((u32 *)srcFramebuffer, (u32 *)dstFramebufferMain, this->_framebufferPixCount);
|
|
||||||
this->_renderNeedsFlushMain = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ColorspaceConvertBuffer8888To5551<true, false>((u32 *)srcFramebuffer, dstFramebuffer16, this->_framebufferPixCount);
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // In the case where OpenGL couldn't flip the framebuffer on the GPU, we'll instead need to flip the framebuffer during conversion.
|
|
||||||
{
|
|
||||||
const size_t pixCount = this->_framebufferWidth;
|
|
||||||
|
|
||||||
if (!doFramebufferConvert)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
size_t x = 0;
|
|
||||||
#ifdef ENABLE_SSE2
|
|
||||||
const size_t ssePixCount = pixCount - (pixCount % 8);
|
|
||||||
for (; x < ssePixCount; x += 8, ir += 8, iw += 8)
|
|
||||||
{
|
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 0));
|
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 4));
|
|
||||||
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 0), ColorspaceCopy32_SSE2<false>(srcColorLo) );
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebufferMain + iw + 4), ColorspaceCopy32_SSE2<false>(srcColorHi) );
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebuffer16 + iw), ColorspaceConvert8888To5551_SSE2<false>(srcColorLo, srcColorHi) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
|
||||||
#endif
|
|
||||||
for (; x < pixCount; x++, ir++, iw++)
|
|
||||||
{
|
|
||||||
dstFramebufferMain[iw].value = ColorspaceCopy32<false>(srcFramebuffer[ir]);
|
|
||||||
dstFramebuffer16[iw] = ColorspaceConvert8888To5551<false>(srcFramebuffer[ir]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
ColorspaceCopyBuffer32<false, 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<false, false>((u32 *)srcFramebuffer + ir, dstFramebuffer16 + iw, pixCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
size_t x = 0;
|
|
||||||
#ifdef ENABLE_SSE2
|
|
||||||
const size_t ssePixCount = pixCount - (pixCount % 8);
|
|
||||||
for (; x < ssePixCount; x += 8, ir += 8, iw += 8)
|
|
||||||
{
|
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 0));
|
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 4));
|
|
||||||
|
|
||||||
_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) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
|
||||||
#endif
|
|
||||||
for (; x < pixCount; x++, ir++, iw++)
|
|
||||||
{
|
|
||||||
dstFramebufferMain[iw].value = ColorspaceConvert8888To6665<true>(srcFramebuffer[ir]);
|
|
||||||
dstFramebuffer16[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
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 *)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, dstFramebuffer16 + iw, pixCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (this->_outputFormat == NDSColorFormat_BGR888_Rev)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
size_t x = 0;
|
|
||||||
#ifdef ENABLE_SSE2
|
|
||||||
const size_t ssePixCount = pixCount - (pixCount % 8);
|
|
||||||
for (; x < ssePixCount; x += 8, ir += 8, iw += 8)
|
|
||||||
{
|
|
||||||
const __m128i srcColorLo = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 0));
|
|
||||||
const __m128i srcColorHi = _mm_load_si128((__m128i *)(srcFramebuffer + ir + 4));
|
|
||||||
|
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + iw + 0), ColorspaceCopy32_SSE2<true>(srcColorLo));
|
|
||||||
_mm_store_si128((__m128i *)(dstFramebufferMain + iw + 4), ColorspaceCopy32_SSE2<true>(srcColorHi));
|
|
||||||
_mm_store_si128( (__m128i *)(dstFramebuffer16 + iw), ColorspaceConvert8888To5551_SSE2<true>(srcColorLo, srcColorHi) );
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma LOOPVECTORIZE_DISABLE
|
|
||||||
#endif
|
|
||||||
for (; x < pixCount; x++, ir++, iw++)
|
|
||||||
{
|
|
||||||
dstFramebufferMain[iw].value = ColorspaceCopy32<true>(srcFramebuffer[ir]);
|
|
||||||
dstFramebuffer16[iw] = ColorspaceConvert8888To5551<true>(srcFramebuffer[ir]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlushMain = false;
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
ColorspaceCopyBuffer32<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, dstFramebuffer16 + iw, pixCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->_renderNeedsFlush16 = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return RENDER3DERROR_NOERR;
|
return RENDER3DERROR_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFramebuffer, Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16)
|
Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFramebuffer, Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16)
|
||||||
{
|
{
|
||||||
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (this->willFlipAndConvertFramebufferOnGPU && this->isPBOSupported)
|
if (this->willFlipAndConvertFramebufferOnGPU && this->isPBOSupported)
|
||||||
{
|
{
|
||||||
this->_renderNeedsFlushMain = false;
|
this->_renderNeedsFlushMain = false;
|
||||||
|
@ -1782,9 +1607,18 @@ Render3DError OpenGLRenderer::FlushFramebuffer(const Color4u8 *__restrict srcFra
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return this->_FlushFramebufferFlipAndConvertOnCPU(srcFramebuffer,
|
if (OGLRef.readPixelsBestFormat == GL_BGRA)
|
||||||
|
{
|
||||||
|
return this->_FlushFramebufferConvertOnCPU<true>(srcFramebuffer,
|
||||||
dstFramebufferMain, dstFramebuffer16,
|
dstFramebufferMain, dstFramebuffer16,
|
||||||
!this->willFlipOnlyFramebufferOnGPU, !this->willFlipAndConvertFramebufferOnGPU);
|
!this->willFlipAndConvertFramebufferOnGPU);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this->_FlushFramebufferConvertOnCPU<false>(srcFramebuffer,
|
||||||
|
dstFramebufferMain, dstFramebuffer16,
|
||||||
|
!this->willFlipAndConvertFramebufferOnGPU);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RENDER3DERROR_NOERR;
|
return RENDER3DERROR_NOERR;
|
||||||
|
@ -2544,10 +2378,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropyOGL);
|
||||||
this->_deviceInfo.maxAnisotropy = maxAnisotropyOGL;
|
this->_deviceInfo.maxAnisotropy = maxAnisotropyOGL;
|
||||||
|
|
||||||
// This is traditionally the fastest format and data type for glReadPixels in legacy mode.
|
|
||||||
OGLRef.readPixelsBestFormat = GL_BGRA;
|
|
||||||
OGLRef.readPixelsBestDataType = GL_UNSIGNED_BYTE;
|
|
||||||
|
|
||||||
// Need to generate this texture first because FBO creation needs it.
|
// Need to generate this texture first because FBO creation needs it.
|
||||||
// This texture is only required by shaders, and so if shader creation
|
// This texture is only required by shaders, and so if shader creation
|
||||||
// fails, then we can immediately delete this texture if an error occurs.
|
// fails, then we can immediately delete this texture if an error occurs.
|
||||||
|
@ -2613,6 +2443,12 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
INFO("OpenGL: FBOs are unsupported. Some emulation features will be disabled.\n");
|
INFO("OpenGL: FBOs are unsupported. Some emulation features will be disabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The internal format of FBOs is GL_RGBA, so we will match that format for glReadPixels.
|
||||||
|
// But the traditional format before FBOs was GL_BGRA, which is also the fastest format
|
||||||
|
// for glReadPixels when using legacy back buffers.
|
||||||
|
OGLRef.readPixelsBestFormat = (this->isFBOSupported) ? GL_RGBA : GL_BGRA;
|
||||||
|
OGLRef.readPixelsBestDataType = GL_UNSIGNED_BYTE;
|
||||||
|
|
||||||
this->_isFBOBlitSupported = this->isFBOSupported &&
|
this->_isFBOBlitSupported = this->isFBOSupported &&
|
||||||
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_framebuffer_blit");
|
this->IsExtensionPresent(&oglExtensionSet, "GL_EXT_framebuffer_blit");
|
||||||
if (!this->_isFBOBlitSupported)
|
if (!this->_isFBOBlitSupported)
|
||||||
|
@ -2698,6 +2534,16 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
{
|
{
|
||||||
INFO("OpenGL: Successfully created geometry shaders.\n");
|
INFO("OpenGL: Successfully created geometry shaders.\n");
|
||||||
|
|
||||||
|
if (OGLRef.readPixelsBestFormat == GL_BGRA)
|
||||||
|
{
|
||||||
|
error = this->InitPostprocessingPrograms(EdgeMarkVtxShader_100,
|
||||||
|
EdgeMarkFragShader_100,
|
||||||
|
FramebufferOutputVtxShader_100,
|
||||||
|
FramebufferOutputBGRA6665FragShader_100,
|
||||||
|
FramebufferOutputBGRA8888FragShader_100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
error = this->InitPostprocessingPrograms(EdgeMarkVtxShader_100,
|
error = this->InitPostprocessingPrograms(EdgeMarkVtxShader_100,
|
||||||
EdgeMarkFragShader_100,
|
EdgeMarkFragShader_100,
|
||||||
FramebufferOutputVtxShader_100,
|
FramebufferOutputVtxShader_100,
|
||||||
|
@ -2705,6 +2551,7 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
FramebufferOutputRGBA8888FragShader_100);
|
FramebufferOutputRGBA8888FragShader_100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (error != OGLERROR_NOERR)
|
if (error != OGLERROR_NOERR)
|
||||||
{
|
{
|
||||||
|
@ -2750,7 +2597,6 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
|
||||||
|
|
||||||
// Set rendering support flags based on driver features.
|
// Set rendering support flags based on driver features.
|
||||||
this->willFlipAndConvertFramebufferOnGPU = this->isShaderSupported && this->isVBOSupported;
|
this->willFlipAndConvertFramebufferOnGPU = this->isShaderSupported && this->isVBOSupported;
|
||||||
this->willFlipOnlyFramebufferOnGPU = this->willFlipAndConvertFramebufferOnGPU || this->_isFBOBlitSupported;
|
|
||||||
this->_deviceInfo.isEdgeMarkSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
|
this->_deviceInfo.isEdgeMarkSupported = this->isShaderSupported && this->isVBOSupported && this->isFBOSupported;
|
||||||
this->_deviceInfo.isFogSupported = this->isShaderSupported && this->isVBOSupported;
|
this->_deviceInfo.isFogSupported = this->isShaderSupported && this->isVBOSupported;
|
||||||
this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported;
|
this->_deviceInfo.isTextureSmoothingSupported = this->isShaderSupported;
|
||||||
|
@ -2988,14 +2834,29 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
||||||
|
|
||||||
// Set up FBOs
|
// Set up FBOs
|
||||||
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
|
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
|
||||||
glGenFramebuffersEXT(1, &OGLRef.fboFramebufferFlipID);
|
|
||||||
glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
|
glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
|
||||||
|
glGenFramebuffersEXT(1, &OGLRef.fboColorOutMainID);
|
||||||
|
glGenFramebuffersEXT(1, &OGLRef.fboColorOutWorkingID);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
|
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
INFO("OpenGL: Failed to create FBOs!\n");
|
||||||
|
this->DestroyFBOs();
|
||||||
|
|
||||||
|
return OGLERROR_FBO_CREATE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the default read/draw buffers.
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutWorkingID);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||||
|
|
||||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
{
|
{
|
||||||
|
@ -3006,12 +2867,14 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the default read/draw buffers.
|
// Assign the default read/draw buffers.
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboClearImageID);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_WORKING_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, OGL_FOGATTRIBUTES_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIFogAttrID, 0);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
|
||||||
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texCIDepthStencilID, 0);
|
||||||
|
|
||||||
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
{
|
{
|
||||||
|
@ -3062,8 +2925,9 @@ void OpenGLRenderer_1_2::DestroyFBOs()
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||||
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
|
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
|
||||||
glDeleteFramebuffersEXT(1, &OGLRef.fboFramebufferFlipID);
|
|
||||||
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
|
glDeleteFramebuffersEXT(1, &OGLRef.fboRenderID);
|
||||||
|
glDeleteFramebuffers(1, &OGLRef.fboColorOutMainID);
|
||||||
|
glDeleteFramebuffers(1, &OGLRef.fboColorOutWorkingID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIColorID);
|
glDeleteTextures(1, &OGLRef.texCIColorID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
|
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
|
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
|
||||||
|
@ -3073,8 +2937,9 @@ void OpenGLRenderer_1_2::DestroyFBOs()
|
||||||
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
|
||||||
|
|
||||||
OGLRef.fboClearImageID = 0;
|
OGLRef.fboClearImageID = 0;
|
||||||
OGLRef.fboFramebufferFlipID = 0;
|
|
||||||
OGLRef.fboRenderID = 0;
|
OGLRef.fboRenderID = 0;
|
||||||
|
OGLRef.fboColorOutMainID = 0;
|
||||||
|
OGLRef.fboColorOutWorkingID = 0;
|
||||||
OGLRef.texCIColorID = 0;
|
OGLRef.texCIColorID = 0;
|
||||||
OGLRef.texCIFogAttrID = 0;
|
OGLRef.texCIFogAttrID = 0;
|
||||||
OGLRef.texCIDepthStencilID = 0;
|
OGLRef.texCIDepthStencilID = 0;
|
||||||
|
@ -3994,10 +3859,6 @@ void OpenGLRenderer_1_2::_SetupGeometryShaders(const OGLGeometryFlags flags)
|
||||||
|
|
||||||
if (!this->isShaderSupported)
|
if (!this->isShaderSupported)
|
||||||
{
|
{
|
||||||
if (this->isFBOSupported)
|
|
||||||
{
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4006,11 +3867,6 @@ void OpenGLRenderer_1_2::_SetupGeometryShaders(const OGLGeometryFlags flags)
|
||||||
glUniform1i(OGLRef.uniformTexDrawOpaque[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformTexDrawOpaque[flags.value], GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformDrawModeDepthEqualsTest[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformDrawModeDepthEqualsTest[flags.value], GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
|
||||||
|
|
||||||
if (this->isFBOSupported)
|
|
||||||
{
|
|
||||||
glDrawBuffers(4, GeometryDrawBuffersEnum[flags.DrawBuffersMode]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
|
Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
|
||||||
|
@ -4162,6 +4018,7 @@ Render3DError OpenGLRenderer_1_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
|
||||||
// Restore OpenGL states back to normal.
|
// Restore OpenGL states back to normal.
|
||||||
this->_geometryProgramFlags = oldGProgramFlags;
|
this->_geometryProgramFlags = oldGProgramFlags;
|
||||||
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
glClear(GL_STENCIL_BUFFER_BIT);
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
@ -4200,7 +4057,6 @@ void OpenGLRenderer_1_2::_ResolveWorkingBackFacing()
|
||||||
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboMSIntermediateRenderID);
|
||||||
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer_1_2::_ResolveGeometry()
|
void OpenGLRenderer_1_2::_ResolveGeometry()
|
||||||
|
@ -4245,9 +4101,8 @@ void OpenGLRenderer_1_2::_ResolveGeometry()
|
||||||
// Blit the color buffer
|
// Blit the color buffer
|
||||||
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
|
// Reset framebuffer targets
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4255,26 +4110,24 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
||||||
{
|
{
|
||||||
OGLRenderRef &OGLRef = *this->ref;
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (this->willFlipAndConvertFramebufferOnGPU)
|
|
||||||
{
|
|
||||||
// Both flips and converts the framebuffer on the GPU. No additional postprocessing
|
// Both flips and converts the framebuffer on the GPU. No additional postprocessing
|
||||||
// should be necessary at this point.
|
// should be necessary at this point.
|
||||||
|
if (this->willFlipAndConvertFramebufferOnGPU)
|
||||||
|
{
|
||||||
if (this->isFBOSupported)
|
if (this->isFBOSupported)
|
||||||
{
|
{
|
||||||
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
|
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
|
||||||
{
|
{
|
||||||
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID[1] : OGLRef.programFramebufferRGBA8888OutputID[1];
|
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID[1] : OGLRef.programFramebufferRGBA8888OutputID[1];
|
||||||
glUseProgram(convertProgramID);
|
glUseProgram(convertProgramID);
|
||||||
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutWorkingID);
|
||||||
glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
|
|
||||||
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
|
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID[0] : OGLRef.programFramebufferRGBA8888OutputID[0];
|
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID[0] : OGLRef.programFramebufferRGBA8888OutputID[0];
|
||||||
glUseProgram(convertProgramID);
|
glUseProgram(convertProgramID);
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
|
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4319,21 +4172,6 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
|
||||||
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (this->willFlipOnlyFramebufferOnGPU)
|
|
||||||
{
|
|
||||||
// Just flips the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
|
|
||||||
// Further colorspace conversion will need to be done in a later step.
|
|
||||||
|
|
||||||
const GLenum flipTarget = (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor) ? OGL_WORKING_ATTACHMENT_ID : OGL_COLOROUT_ATTACHMENT_ID;
|
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
|
|
||||||
glDrawBuffer(flipTarget);
|
|
||||||
|
|
||||||
glBlitFramebufferEXT(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboFramebufferFlipID);
|
|
||||||
glReadBuffer(flipTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->isPBOSupported)
|
if (this->isPBOSupported)
|
||||||
{
|
{
|
||||||
|
@ -4568,17 +4406,11 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
glScalef(1.0f, -1.0f, 1.0f);
|
||||||
if (this->isFBOSupported)
|
|
||||||
{
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (this->isShaderSupported && this->isFBOSupported)
|
|
||||||
{
|
{
|
||||||
// Even with no polygons to draw, we always need to set these 3 flags so that
|
// Even with no polygons to draw, we always need to set these 3 flags so that
|
||||||
// glDrawBuffers() can reference the correct set of FBO attachments using
|
// glDrawBuffers() can reference the correct set of FBO attachments using
|
||||||
|
@ -4587,9 +4419,24 @@ Render3DError OpenGLRenderer_1_2::BeginRender(const GFX3D_State &renderState, co
|
||||||
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0;
|
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0;
|
||||||
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->isFBOSupported)
|
||||||
|
{
|
||||||
|
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
|
||||||
|
|
||||||
|
if (this->isShaderSupported)
|
||||||
|
{
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
@ -4663,6 +4510,10 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry()
|
||||||
glStencilMask(0xFF);
|
glStencilMask(0xFF);
|
||||||
|
|
||||||
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
||||||
|
if (this->isFBOSupported && this->isShaderSupported)
|
||||||
|
{
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->_clippedPolyOpaqueCount == 0)
|
if (this->_clippedPolyOpaqueCount == 0)
|
||||||
|
@ -4813,6 +4664,11 @@ Render3DError OpenGLRenderer_1_2::PostprocessFramebuffer()
|
||||||
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_DST_ALPHA);
|
||||||
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
|
||||||
|
|
||||||
|
if (this->isFBOSupported)
|
||||||
|
{
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->isVAOSupported)
|
if (this->isVAOSupported)
|
||||||
|
@ -4898,8 +4754,6 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
|
||||||
{
|
{
|
||||||
glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebufferEXT(0, GPU_FRAMEBUFFER_NATIVE_HEIGHT, GPU_FRAMEBUFFER_NATIVE_WIDTH, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->isMultisampledFBOSupported)
|
if (this->isMultisampledFBOSupported)
|
||||||
|
@ -4949,10 +4803,7 @@ Render3DError OpenGLRenderer_1_2::ClearUsingImage(const u16 *__restrict colorBuf
|
||||||
{
|
{
|
||||||
// Blit the color and depth buffers.
|
// Blit the color and depth buffers.
|
||||||
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebufferEXT(0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5004,12 +4855,6 @@ Render3DError OpenGLRenderer_1_2::ClearUsingValues(const Color4u8 &clearColor666
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->isFBOSupported)
|
|
||||||
{
|
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
glClearColor(divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]);
|
glClearColor(divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]);
|
||||||
glClearDepth((GLclampd)clearAttributes.depth / (GLclampd)0x00FFFFFF);
|
glClearDepth((GLclampd)clearAttributes.depth / (GLclampd)0x00FFFFFF);
|
||||||
glClearStencil(clearAttributes.opaquePolyID);
|
glClearStencil(clearAttributes.opaquePolyID);
|
||||||
|
@ -5413,9 +5258,7 @@ Render3DError OpenGLRenderer_1_2::RenderPowerOff()
|
||||||
|
|
||||||
if (this->isFBOSupported)
|
if (this->isFBOSupported)
|
||||||
{
|
{
|
||||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboColorOutMainID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
@ -5499,6 +5342,7 @@ Render3DError OpenGLRenderer_1_2::RenderFlush(bool willFlushBuffer32, bool willF
|
||||||
Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
|
Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
|
||||||
{
|
{
|
||||||
Render3DError error = OGLERROR_NOERR;
|
Render3DError error = OGLERROR_NOERR;
|
||||||
|
OGLRenderRef &OGLRef = *this->ref;
|
||||||
|
|
||||||
if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT)
|
if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT)
|
||||||
{
|
{
|
||||||
|
@ -5593,11 +5437,21 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
|
||||||
this->CreateEdgeMarkProgram(EdgeMarkVtxShader_100, EdgeMarkFragShader_100);
|
this->CreateEdgeMarkProgram(EdgeMarkVtxShader_100, EdgeMarkFragShader_100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OGLRef.readPixelsBestFormat == GL_BGRA)
|
||||||
|
{
|
||||||
|
this->CreateFramebufferOutput6665Program(0, FramebufferOutputVtxShader_100, FramebufferOutputBGRA6665FragShader_100);
|
||||||
|
this->CreateFramebufferOutput6665Program(1, FramebufferOutputVtxShader_100, FramebufferOutputBGRA6665FragShader_100);
|
||||||
|
this->CreateFramebufferOutput8888Program(0, FramebufferOutputVtxShader_100, FramebufferOutputBGRA8888FragShader_100);
|
||||||
|
this->CreateFramebufferOutput8888Program(1, FramebufferOutputVtxShader_100, FramebufferOutputBGRA8888FragShader_100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this->CreateFramebufferOutput6665Program(0, FramebufferOutputVtxShader_100, FramebufferOutputRGBA6665FragShader_100);
|
this->CreateFramebufferOutput6665Program(0, FramebufferOutputVtxShader_100, FramebufferOutputRGBA6665FragShader_100);
|
||||||
this->CreateFramebufferOutput6665Program(1, FramebufferOutputVtxShader_100, FramebufferOutputRGBA6665FragShader_100);
|
this->CreateFramebufferOutput6665Program(1, FramebufferOutputVtxShader_100, FramebufferOutputRGBA6665FragShader_100);
|
||||||
this->CreateFramebufferOutput8888Program(0, FramebufferOutputVtxShader_100, FramebufferOutputRGBA8888FragShader_100);
|
this->CreateFramebufferOutput8888Program(0, FramebufferOutputVtxShader_100, FramebufferOutputRGBA8888FragShader_100);
|
||||||
this->CreateFramebufferOutput8888Program(1, FramebufferOutputVtxShader_100, FramebufferOutputRGBA8888FragShader_100);
|
this->CreateFramebufferOutput8888Program(1, FramebufferOutputVtxShader_100, FramebufferOutputRGBA8888FragShader_100);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (oglrender_framebufferDidResizeCallback != NULL)
|
if (oglrender_framebufferDidResizeCallback != NULL)
|
||||||
{
|
{
|
||||||
|
@ -5813,8 +5667,6 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (this->isFBOSupported)
|
|
||||||
{
|
{
|
||||||
// Even with no polygons to draw, we always need to set these 3 flags so that
|
// Even with no polygons to draw, we always need to set these 3 flags so that
|
||||||
// glDrawBuffers() can reference the correct set of FBO attachments using
|
// glDrawBuffers() can reference the correct set of FBO attachments using
|
||||||
|
@ -5823,9 +5675,15 @@ Render3DError OpenGLRenderer_2_0::BeginRender(const GFX3D_State &renderState, co
|
||||||
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0;
|
this->_geometryProgramFlags.EnableEdgeMark = (this->_enableEdgeMark) ? 1 : 0;
|
||||||
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->isFBOSupported)
|
||||||
|
{
|
||||||
|
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||||
|
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.selectedRenderingFBO);
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
|
|
@ -628,7 +628,8 @@ struct OGLRenderRef
|
||||||
|
|
||||||
GLuint fboClearImageID;
|
GLuint fboClearImageID;
|
||||||
GLuint fboRenderID;
|
GLuint fboRenderID;
|
||||||
GLuint fboFramebufferFlipID;
|
GLuint fboColorOutMainID;
|
||||||
|
GLuint fboColorOutWorkingID;
|
||||||
GLuint fboMSIntermediateRenderID;
|
GLuint fboMSIntermediateRenderID;
|
||||||
GLuint selectedRenderingFBO;
|
GLuint selectedRenderingFBO;
|
||||||
|
|
||||||
|
@ -799,9 +800,9 @@ private:
|
||||||
unsigned int versionRevision;
|
unsigned int versionRevision;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Render3DError _FlushFramebufferFlipAndConvertOnCPU(const Color4u8 *__restrict srcFramebuffer,
|
template<bool SWAP_RB> Render3DError _FlushFramebufferConvertOnCPU(const Color4u8 *__restrict srcFramebuffer,
|
||||||
Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16,
|
Color4u8 *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16,
|
||||||
bool doFramebufferFlip, bool doFramebufferConvert);
|
bool doFramebufferConvert);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// OpenGL-specific References
|
// OpenGL-specific References
|
||||||
|
@ -816,7 +817,6 @@ protected:
|
||||||
bool isMultisampledFBOSupported;
|
bool isMultisampledFBOSupported;
|
||||||
bool isShaderSupported;
|
bool isShaderSupported;
|
||||||
bool isVAOSupported;
|
bool isVAOSupported;
|
||||||
bool willFlipOnlyFramebufferOnGPU;
|
|
||||||
bool willFlipAndConvertFramebufferOnGPU;
|
bool willFlipAndConvertFramebufferOnGPU;
|
||||||
bool willUsePerSampleZeroDstPass;
|
bool willUsePerSampleZeroDstPass;
|
||||||
|
|
||||||
|
|
|
@ -695,7 +695,6 @@ Render3DError OpenGLRenderer_3_2::InitExtensions()
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// OpenGL v3.2 Core Profile should have all the necessary features to be able to flip and convert the framebuffer.
|
// OpenGL v3.2 Core Profile should have all the necessary features to be able to flip and convert the framebuffer.
|
||||||
this->willFlipOnlyFramebufferOnGPU = true;
|
|
||||||
this->willFlipAndConvertFramebufferOnGPU = true;
|
this->willFlipAndConvertFramebufferOnGPU = true;
|
||||||
|
|
||||||
this->_isSampleShadingSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_sample_shading");
|
this->_isSampleShadingSupported = this->IsExtensionPresent(&oglExtensionSet, "GL_ARB_sample_shading");
|
||||||
|
@ -925,6 +924,40 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
|
||||||
// Set up FBOs
|
// Set up FBOs
|
||||||
glGenFramebuffers(1, &OGLRef.fboClearImageID);
|
glGenFramebuffers(1, &OGLRef.fboClearImageID);
|
||||||
glGenFramebuffers(1, &OGLRef.fboRenderID);
|
glGenFramebuffers(1, &OGLRef.fboRenderID);
|
||||||
|
glGenFramebuffers(1, &OGLRef.fboColorOutMainID);
|
||||||
|
glGenFramebuffers(1, &OGLRef.fboColorOutWorkingID);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
INFO("OpenGL: Failed to create FBOs!\n");
|
||||||
|
this->DestroyFBOs();
|
||||||
|
|
||||||
|
return OGLERROR_FBO_CREATE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the default read/draw buffers.
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutWorkingID);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
INFO("OpenGL: Failed to create FBOs!\n");
|
||||||
|
this->DestroyFBOs();
|
||||||
|
|
||||||
|
return OGLERROR_FBO_CREATE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the default read/draw buffers.
|
||||||
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboClearImageID);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, OGL_COLOROUT_ATTACHMENT_ID, GL_TEXTURE_2D, OGLRef.texCIColorID, 0);
|
||||||
|
@ -980,6 +1013,8 @@ void OpenGLRenderer_3_2::DestroyFBOs()
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
|
||||||
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
glDeleteFramebuffers(1, &OGLRef.fboRenderID);
|
||||||
|
glDeleteFramebuffers(1, &OGLRef.fboColorOutMainID);
|
||||||
|
glDeleteFramebuffers(1, &OGLRef.fboColorOutWorkingID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIColorID);
|
glDeleteTextures(1, &OGLRef.texCIColorID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
|
glDeleteTextures(1, &OGLRef.texCIFogAttrID);
|
||||||
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
|
glDeleteTextures(1, &OGLRef.texCIDepthStencilID);
|
||||||
|
@ -990,6 +1025,8 @@ void OpenGLRenderer_3_2::DestroyFBOs()
|
||||||
|
|
||||||
OGLRef.fboClearImageID = 0;
|
OGLRef.fboClearImageID = 0;
|
||||||
OGLRef.fboRenderID = 0;
|
OGLRef.fboRenderID = 0;
|
||||||
|
OGLRef.fboColorOutMainID = 0;
|
||||||
|
OGLRef.fboColorOutWorkingID = 0;
|
||||||
OGLRef.texCIColorID = 0;
|
OGLRef.texCIColorID = 0;
|
||||||
OGLRef.texCIFogAttrID = 0;
|
OGLRef.texCIFogAttrID = 0;
|
||||||
OGLRef.texCIDepthStencilID = 0;
|
OGLRef.texCIDepthStencilID = 0;
|
||||||
|
@ -1993,8 +2030,6 @@ void OpenGLRenderer_3_2::_SetupGeometryShaders(const OGLGeometryFlags flags)
|
||||||
glUniform1i(OGLRef.uniformTexDrawOpaque[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformTexDrawOpaque[flags.value], GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformDrawModeDepthEqualsTest[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformDrawModeDepthEqualsTest[flags.value], GL_FALSE);
|
||||||
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
|
glUniform1i(OGLRef.uniformPolyDrawShadow[flags.value], GL_FALSE);
|
||||||
|
|
||||||
glDrawBuffers(4, GeometryDrawBuffersEnum[flags.DrawBuffersMode]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes()
|
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes()
|
||||||
|
@ -2071,6 +2106,7 @@ Render3DError OpenGLRenderer_3_2::ZeroDstAlphaPass(const POLY *rawPolyList, cons
|
||||||
// Restore OpenGL states back to normal.
|
// Restore OpenGL states back to normal.
|
||||||
this->_geometryProgramFlags = oldGProgramFlags;
|
this->_geometryProgramFlags = oldGProgramFlags;
|
||||||
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
this->_SetupGeometryShaders(this->_geometryProgramFlags);
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
|
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
@ -2160,15 +2196,15 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
|
||||||
{
|
{
|
||||||
// Use the alternate program where the output color is not at index 0.
|
// Use the alternate program where the output color is not at index 0.
|
||||||
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID[1]);
|
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID[1]);
|
||||||
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutWorkingID);
|
||||||
glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
|
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use the program where the output color is from index 0.
|
// Use the program where the output color is from index 0.
|
||||||
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID[0]);
|
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID[0]);
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
|
glViewport(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight);
|
||||||
|
@ -2180,31 +2216,17 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
|
||||||
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
if (this->_mappedFramebuffer != NULL)
|
|
||||||
{
|
|
||||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
|
||||||
this->_mappedFramebuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Just flips the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
|
// Just flips the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
|
||||||
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
|
const GLuint fboOut = (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor) ? OGLRef.fboColorOutWorkingID : OGLRef.fboColorOutMainID;
|
||||||
{
|
glBindFramebuffer(GL_FRAMEBUFFER, fboOut);
|
||||||
glDrawBuffer(OGL_WORKING_ATTACHMENT_ID);
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glBlitFramebuffer(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
}
|
|
||||||
else
|
this->_lastTextureDrawTarget = (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor) ? OGLTextureUnitID_FinalColor : OGLTextureUnitID_GColor;
|
||||||
{
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glReadBuffer(OGL_WORKING_ATTACHMENT_ID);
|
|
||||||
glBlitFramebuffer(0, (GLint)this->_framebufferHeight, (GLint)this->_framebufferWidth, 0, 0, 0, (GLint)this->_framebufferWidth, (GLint)this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read back the pixels in RGBA format, since an OpenGL 3.2 device should be able to read back this
|
// Read back the pixels in RGBA format, since an OpenGL 3.2 device should be able to read back this
|
||||||
|
@ -2216,7 +2238,6 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
|
glReadPixels(0, 0, (GLsizei)this->_framebufferWidth, (GLsizei)this->_framebufferHeight, OGLRef.readPixelsBestFormat, OGLRef.readPixelsBestDataType, 0);
|
||||||
}
|
|
||||||
|
|
||||||
this->_pixelReadNeedsFinish = true;
|
this->_pixelReadNeedsFinish = true;
|
||||||
return OGLERROR_NOERR;
|
return OGLERROR_NOERR;
|
||||||
|
@ -2443,7 +2464,10 @@ Render3DError OpenGLRenderer_3_2::BeginRender(const GFX3D_State &renderState, co
|
||||||
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
this->_geometryProgramFlags.OpaqueDrawMode = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
OGLRef.selectedRenderingFBO = (this->_enableMultisampledRendering) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
|
||||||
|
glDrawBuffers(4, GeometryDrawBuffersEnum[this->_geometryProgramFlags.DrawBuffersMode]);
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
@ -2911,9 +2935,7 @@ Render3DError OpenGLRenderer_3_2::RenderPowerOff()
|
||||||
return OGLERROR_BEGINGL_FAILED;
|
return OGLERROR_BEGINGL_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
|
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboColorOutMainID);
|
||||||
glReadBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glDrawBuffer(OGL_COLOROUT_ATTACHMENT_ID);
|
|
||||||
glClearBufferfv(GL_COLOR, 0, oglColor);
|
glClearBufferfv(GL_COLOR, 0, oglColor);
|
||||||
|
|
||||||
if (this->_mappedFramebuffer != NULL)
|
if (this->_mappedFramebuffer != NULL)
|
||||||
|
|
|
@ -321,7 +321,6 @@ Render3DError OpenGLESRenderer_3_0::InitExtensions()
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
// OpenGL ES v3.0 should have all the necessary features to be able to flip and convert the framebuffer.
|
// OpenGL ES v3.0 should have all the necessary features to be able to flip and convert the framebuffer.
|
||||||
this->willFlipOnlyFramebufferOnGPU = true;
|
|
||||||
this->willFlipAndConvertFramebufferOnGPU = true;
|
this->willFlipAndConvertFramebufferOnGPU = true;
|
||||||
|
|
||||||
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
|
this->_enableTextureSmoothing = CommonSettings.GFX3D_Renderer_TextureSmoothing;
|
||||||
|
|
Loading…
Reference in New Issue