OpenGL Renderer: Eliminate two extraneous framebuffers, especially saving VRAM at the larger custom framebuffer sizes.

This commit is contained in:
rogerman 2017-07-29 17:47:53 -07:00
parent 353dcef3ec
commit 5deec25409
3 changed files with 195 additions and 146 deletions

View File

@ -1060,11 +1060,13 @@ OpenGLRenderer::OpenGLRenderer()
ref->fboMSIntermediateRenderID = 0;
ref->fboPostprocessID = 0;
ref->selectedRenderingFBO = 0;
ref->texFinalColorID = 0;
_mappedFramebuffer = NULL;
_workingTextureUnpackBuffer = (FragmentColor *)malloc_alignedCacheLine(1024 * 1024 * sizeof(FragmentColor));
_pixelReadNeedsFinish = false;
_currentPolyIndex = 0;
_lastTextureDrawTarget = OGLTextureUnitID_GColor;
}
OpenGLRenderer::~OpenGLRenderer()
@ -1532,11 +1534,15 @@ OpenGLRenderer_1_2::~OpenGLRenderer_1_2()
// Kill the texture cache now before all of our texture IDs disappear.
texCache.Reset();
glDeleteTextures(1, &ref->texFinalColorID);
ref->texFinalColorID = 0;
glFinish();
}
Render3DError OpenGLRenderer_1_2::InitExtensions()
{
OGLRenderRef &OGLRef = *this->ref;
Render3DError error = OGLERROR_NOERR;
// Get OpenGL extensions
@ -1622,7 +1628,19 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
}
}
if (!this->isShaderSupported)
if (this->isShaderSupported)
{
glGenTextures(1, &OGLRef.texFinalColorID);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB);
}
else
{
INFO("OpenGL: Shaders are unsupported. Disabling shaders and using fixed-function pipeline. Some emulation features will be disabled.\n");
}
@ -1665,10 +1683,35 @@ Render3DError OpenGLRenderer_1_2::InitExtensions()
this->willFlipFramebufferOnGPU = this->isPBOSupported;
this->willConvertFramebufferOnGPU = (this->isShaderSupported && this->isPBOSupported);
// This texture will be used as an FBO color attachment.
// If this texture wasn't already created by passing the shader support check,
// then create the texture now.
bool createdTextureForFBO = false;
if (OGLRef.texFinalColorID == 0)
{
glGenTextures(1, &OGLRef.texFinalColorID);
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB);
createdTextureForFBO = true;
}
error = this->CreateFBOs();
if (error != OGLERROR_NOERR)
{
this->isFBOSupported = false;
if (createdTextureForFBO)
{
glDeleteTextures(1, &OGLRef.texFinalColorID);
OGLRef.texFinalColorID = 0;
}
}
}
else
@ -2017,25 +2060,12 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glGenTextures(1, &OGLRef.texCIPolyID);
glGenTextures(1, &OGLRef.texCIDepthStencilID);
glGenTextures(1, &OGLRef.texFinalColorID);
glGenTextures(1, &OGLRef.texGColorID);
glGenTextures(1, &OGLRef.texGDepthID);
glGenTextures(1, &OGLRef.texGFogAttrID);
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGDepthStencilID);
glGenTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glGenTextures(1, &OGLRef.texPostprocessFogID);
if (this->willFlipFramebufferOnGPU)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
@ -2087,13 +2117,6 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -2132,14 +2155,6 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glBindTexture(GL_TEXTURE_2D, 0);
// Set up RBOs
if (this->willConvertFramebufferOnGPU)
{
glGenRenderbuffersEXT(1, &OGLRef.rboFramebufferRGBA6665ID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboFramebufferRGBA6665ID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
}
// Set up FBOs
glGenFramebuffersEXT(1, &OGLRef.fboClearImageID);
glGenFramebuffersEXT(1, &OGLRef.fboRenderID);
@ -2155,7 +2170,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to created FBOs!\n");
INFO("OpenGL: Failed to create FBOs!\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
@ -2172,9 +2187,6 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -2200,13 +2212,12 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texGDepthID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, OGLRef.texGPolyID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_TEXTURE_2D, OGLRef.texGFogAttrID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT4_EXT, GL_TEXTURE_2D, OGLRef.texZeroAlphaPixelMaskID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, OGLRef.texGDepthStencilID, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
INFO("OpenGL: Failed to created FBOs!\n");
INFO("OpenGL: Failed to create FBOs!\n");
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &OGLRef.fboClearImageID);
@ -2223,9 +2234,6 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -2247,17 +2255,9 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texPostprocessFogID, 0);
if (this->willFlipFramebufferOnGPU)
{
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
}
if (this->willConvertFramebufferOnGPU)
{
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, OGLRef.rboFramebufferRGBA6665ID);
}
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, OGLRef.texZeroAlphaPixelMaskID, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
{
@ -2278,9 +2278,6 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -2324,9 +2321,6 @@ void OpenGLRenderer_1_2::DestroyFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffersEXT(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -2988,12 +2982,12 @@ Render3DError OpenGLRenderer_1_2::InitFramebufferOutputShaderLocations()
OGLRenderRef &OGLRef = *this->ref;
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
const GLint uniformTexFinalColorRGBA6665 = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(uniformTexFinalColorRGBA6665, OGLTextureUnitID_FinalColor);
OGLRef.uniformTexInFragColor_ConvertRGBA6665 = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_FinalColor);
glUseProgram(OGLRef.programFramebufferRGBA8888OutputID);
const GLint uniformTexFinalColorRGBA8888 = glGetUniformLocation(OGLRef.programFramebufferRGBA8888OutputID, "texInFragColor");
glUniform1i(uniformTexFinalColorRGBA8888, OGLTextureUnitID_FinalColor);
OGLRef.uniformTexInFragColor_ConvertRGBA8888 = glGetUniformLocation(OGLRef.programFramebufferRGBA8888OutputID, "texInFragColor");
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA8888, OGLTextureUnitID_FinalColor);
return OGLERROR_NOERR;
}
@ -3136,8 +3130,6 @@ Render3DError OpenGLRenderer_1_2::EnableVertexAttributes()
}
}
glActiveTextureARB(GL_TEXTURE0_ARB);
return OGLERROR_NOERR;
}
@ -3235,10 +3227,29 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
if (this->willFlipFramebufferOnGPU)
{
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
}
else
{
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
}
glBlitFramebufferEXT(0, this->_framebufferHeight, this->_framebufferWidth, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
else
{
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
}
}
if (this->willConvertFramebufferOnGPU)
@ -3246,9 +3257,22 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
// Perform the color space conversion while we're still on the GPU so
// that we can avoid having to do it on the CPU.
const GLuint convertProgramID = (this->_outputFormat == NDSColorFormat_BGR666_Rev) ? OGLRef.programFramebufferRGBA6665OutputID : OGLRef.programFramebufferRGBA8888OutputID;
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
glUseProgram(convertProgramID);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_GColor);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
}
else
{
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_FinalColor);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
}
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
@ -3282,8 +3306,14 @@ Render3DError OpenGLRenderer_1_2::ReadBackPixels()
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
// Read back the pixels.
glReadBuffer(GL_COLOR_ATTACHMENT2_EXT);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
else
{
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
}
}
// Read back the pixels in BGRA format, since legacy OpenGL devices may experience a performance
@ -3459,6 +3489,8 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
glDisable(GL_BLEND);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
this->EnableVertexAttributes();
const POLY &firstPoly = polyList->list[indexList->list[0]];
@ -3559,6 +3591,8 @@ Render3DError OpenGLRenderer_1_2::RenderGeometry(const GFX3D_State &renderState,
this->DownsampleFBO();
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
return OGLERROR_NOERR;
}
@ -3606,7 +3640,7 @@ Render3DError OpenGLRenderer_1_2::RenderEdgeMarking(const u16 *colorTable, const
alpha};
// Set up the postprocessing states
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboRenderID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
@ -3628,7 +3662,7 @@ Render3DError OpenGLRenderer_1_2::RenderEdgeMarking(const u16 *colorTable, const
}
// Pass 1: Determine the pixels with zero alpha
glDrawBuffer(GL_COLOR_ATTACHMENT4_EXT);
glDrawBuffer(GL_COLOR_ATTACHMENT2_EXT);
glUseProgram(OGLRef.programZeroAlphaPixelMaskID);
glDisable(GL_BLEND);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
@ -3657,8 +3691,11 @@ Render3DError OpenGLRenderer_1_2::RenderEdgeMarking(const u16 *colorTable, const
glDisableVertexAttribArray(OGLVertexAttributeID_Position);
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
return RENDER3DERROR_NOERR;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_1_2::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly)
@ -3685,6 +3722,7 @@ Render3DError OpenGLRenderer_1_2::RenderFog(const u8 *densityTable, const u32 co
const GLfloat oglFogStep = (GLfloat)(0x0400 >> shift) / 32767.0f;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, OGLRef.fboPostprocessID);
glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
glUseProgram(OGLRef.programFogID);
glUniform1i(OGLRef.uniformStateEnableFogAlphaOnly, (alphaOnly) ? GL_TRUE : GL_FALSE);
glUniform4f(OGLRef.uniformStateFogColor, oglColor[0], oglColor[1], oglColor[2], oglColor[3]);
@ -3725,6 +3763,9 @@ Render3DError OpenGLRenderer_1_2::RenderFog(const u8 *densityTable, const u32 co
glDisableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
return OGLERROR_NOERR;
}
@ -3742,8 +3783,11 @@ Render3DError OpenGLRenderer_1_2::EndRender(const u64 frameCount)
Render3DError OpenGLRenderer_1_2::UpdateToonTable(const u16 *toonTableBuffer)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer);
if (this->isShaderSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_ToonTable);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 32, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, toonTableBuffer);
}
return OGLERROR_NOERR;
}
@ -4314,6 +4358,13 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
}
}
if (this->isShaderSupported || this->isFBOSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
if (this->isFBOSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
@ -4333,10 +4384,6 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FogAttr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
if (this->isMultisampledFBOSupported)
@ -4355,18 +4402,7 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, maxSamples, GL_DEPTH24_STENCIL8_EXT, w, h);
}
if (this->willFlipFramebufferOnGPU)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
}
if (this->willConvertFramebufferOnGPU)
{
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, OGLRef.rboFramebufferRGBA6665ID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, w, h);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
const size_t newFramebufferColorSizeBytes = w * h * sizeof(FragmentColor);
@ -4415,8 +4451,6 @@ Render3DError OpenGLRenderer_2_0::EnableVertexAttributes()
glVertexAttribPointer(OGLVertexAttributeID_Color, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(VERT), OGLRef.vtxPtrColor);
}
glActiveTexture(GL_TEXTURE0);
return OGLERROR_NOERR;
}

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
Copyright (C) 2008-2016 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -429,7 +429,6 @@ struct OGLRenderRef
GLuint texGPolyID;
GLuint texZeroAlphaPixelMaskID;
GLuint texGDepthStencilID;
GLuint texPostprocessFogID;
GLuint texFinalColorID;
GLuint rboMSGColorID;
@ -437,7 +436,6 @@ struct OGLRenderRef
GLuint rboMSGPolyID;
GLuint rboMSGFogAttrID;
GLuint rboMSGDepthStencilID;
GLuint rboFramebufferRGBA6665ID;
GLuint fboClearImageID;
GLuint fboRenderID;
@ -466,6 +464,10 @@ struct OGLRenderRef
GLuint programFramebufferRGBA8888OutputID;
GLint uniformFramebufferSize;
GLint uniformFramebufferSize_ConvertRGBA6665;
GLint uniformFramebufferSize_ConvertRGBA8888;
GLint uniformTexInFragColor_ConvertRGBA6665;
GLint uniformTexInFragColor_ConvertRGBA8888;
GLint uniformStateToonShadingMode;
GLint uniformStateEnableAlphaTest;
GLint uniformStateEnableAntialiasing;
@ -622,6 +624,7 @@ protected:
FragmentColor *_workingTextureUnpackBuffer;
bool _pixelReadNeedsFinish;
size_t _currentPolyIndex;
OGLTextureUnitID _lastTextureDrawTarget;
Render3DError FlushFramebuffer(const FragmentColor *__restrict srcFramebuffer, FragmentColor *__restrict dstFramebufferMain, u16 *__restrict dstFramebuffer16);
OpenGLTexture* GetLoadedTextureFromPolygon(const POLY &thePoly, bool enableTexturing);

View File

@ -1,7 +1,7 @@
/*
Copyright (C) 2006 yopyop
Copyright (C) 2006-2007 shash
Copyright (C) 2008-2016 DeSmuME team
Copyright (C) 2008-2017 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -803,12 +803,12 @@ Render3DError OpenGLRenderer_3_2::InitFramebufferOutputShaderLocations()
OGLRenderRef &OGLRef = *this->ref;
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
const GLint uniformTexFinalColorRGBA6665 = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(uniformTexFinalColorRGBA6665, OGLTextureUnitID_FinalColor);
OGLRef.uniformTexInFragColor_ConvertRGBA6665 = glGetUniformLocation(OGLRef.programFramebufferRGBA6665OutputID, "texInFragColor");
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_FinalColor);
glUseProgram(OGLRef.programFramebufferRGBA8888OutputID);
const GLint uniformTexFinalColorRGBA8888 = glGetUniformLocation(OGLRef.programFramebufferRGBA8888OutputID, "texInFragColor");
glUniform1i(uniformTexFinalColorRGBA8888, OGLTextureUnitID_FinalColor);
OGLRef.uniformTexInFragColor_ConvertRGBA8888 = glGetUniformLocation(OGLRef.programFramebufferRGBA8888OutputID, "texInFragColor");
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA8888, OGLTextureUnitID_FinalColor);
return OGLERROR_NOERR;
}
@ -831,7 +831,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glGenTextures(1, &OGLRef.texGPolyID);
glGenTextures(1, &OGLRef.texGDepthStencilID);
glGenTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glGenTextures(1, &OGLRef.texPostprocessFogID);
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FinalColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texFinalColorID);
@ -891,13 +890,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIColorID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -936,11 +928,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glBindTexture(GL_TEXTURE_2D, 0);
// Set up RBOs
glGenRenderbuffers(1, &OGLRef.rboFramebufferRGBA6665ID);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFramebufferRGBA6665ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, this->_framebufferWidth, this->_framebufferHeight);
// Set up FBOs
glGenFramebuffers(1, &OGLRef.fboClearImageID);
glGenFramebuffers(1, &OGLRef.fboRenderID);
@ -955,7 +942,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
INFO("OpenGL: Failed to create FBOs!\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
@ -972,9 +959,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffers(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -996,7 +980,7 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
INFO("OpenGL: Failed to create FBOs!\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
@ -1013,9 +997,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffers(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -1028,13 +1009,13 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texPostprocessFogID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, OGLRef.texGColorID, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OGLRef.texFinalColorID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, OGLRef.rboFramebufferRGBA6665ID);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, OGLRef.texZeroAlphaPixelMaskID);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
INFO("OpenGL: Failed to created FBOs. Some emulation features will be disabled.\n");
INFO("OpenGL: Failed to create FBOs!\n");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &OGLRef.fboClearImageID);
@ -1051,9 +1032,6 @@ Render3DError OpenGLRenderer_3_2::CreateFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffers(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -1096,9 +1074,6 @@ void OpenGLRenderer_3_2::DestroyFBOs()
glDeleteTextures(1, &OGLRef.texGFogAttrID);
glDeleteTextures(1, &OGLRef.texGDepthStencilID);
glDeleteTextures(1, &OGLRef.texZeroAlphaPixelMaskID);
glDeleteTextures(1, &OGLRef.texPostprocessFogID);
glDeleteTextures(1, &OGLRef.texFinalColorID);
glDeleteRenderbuffers(1, &OGLRef.rboFramebufferRGBA6665ID);
OGLRef.fboClearImageID = 0;
OGLRef.fboRenderID = 0;
@ -1361,7 +1336,6 @@ void OpenGLRenderer_3_2::GetExtensionSet(std::set<std::string> *oglExtensionSet)
Render3DError OpenGLRenderer_3_2::EnableVertexAttributes()
{
glBindVertexArray(this->ref->vaoGeometryStatesID);
glActiveTexture(GL_TEXTURE0);
return OGLERROR_NOERR;
}
@ -1421,18 +1395,50 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
// Flip the framebuffer in Y to match the coordinates of OpenGL and the NDS hardware.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OGLRef.fboPostprocessID);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glDrawBuffer(GL_COLOR_ATTACHMENT1);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
}
else
{
glDrawBuffer(GL_COLOR_ATTACHMENT0);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
}
glBlitFramebuffer(0, this->_framebufferHeight, this->_framebufferWidth, 0, 0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
glReadBuffer(GL_COLOR_ATTACHMENT1);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glReadBuffer(GL_COLOR_ATTACHMENT0);
}
else
{
glReadBuffer(GL_COLOR_ATTACHMENT1);
}
if (this->_outputFormat == NDSColorFormat_BGR666_Rev)
{
// Perform the RGBA6665 color space conversion while we're still on the GPU so
// that we can avoid having to do it on the CPU.
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glUseProgram(OGLRef.programFramebufferRGBA6665OutputID);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_GColor);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
}
else
{
glUniform1i(OGLRef.uniformTexInFragColor_ConvertRGBA6665, OGLTextureUnitID_FinalColor);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
}
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
@ -1445,17 +1451,20 @@ Render3DError OpenGLRenderer_3_2::ReadBackPixels()
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
glBindVertexArray(0);
glReadBuffer(GL_COLOR_ATTACHMENT2);
if (this->_lastTextureDrawTarget == OGLTextureUnitID_GColor)
{
glReadBuffer(GL_COLOR_ATTACHMENT0);
}
else
{
glReadBuffer(GL_COLOR_ATTACHMENT1);
}
}
// Read back the pixels in RGBA format, since an OpenGL 3.2 device should be able to read back this
// format without a performance penalty.
glReadPixels(0, 0, this->_framebufferWidth, this->_framebufferHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);
// Set the read and draw target buffers back to color attachment 0, which is always the default.
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
this->_pixelReadNeedsFinish = true;
return OGLERROR_NOERR;
}
@ -1597,7 +1606,7 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable, const
OGLRenderRef &OGLRef = *this->ref;
// Set up the postprocessing states
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboRenderID);
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
@ -1608,7 +1617,7 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable, const
glBindVertexArray(OGLRef.vaoPostprocessStatesID);
// Pass 1: Determine the pixels with zero alpha
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glUseProgram(OGLRef.programZeroAlphaPixelMaskID);
glDisable(GL_BLEND);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
@ -1628,7 +1637,10 @@ Render3DError OpenGLRenderer_3_2::RenderEdgeMarking(const u16 *colorTable, const
glBindVertexArray(0);
return RENDER3DERROR_NOERR;
glReadBuffer(GL_COLOR_ATTACHMENT0);
this->_lastTextureDrawTarget = OGLTextureUnitID_GColor;
return OGLERROR_NOERR;
}
Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly)
@ -1636,6 +1648,7 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
OGLRenderRef &OGLRef = *this->ref;
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.fboPostprocessID);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glUseProgram(OGLRef.programFogID);
glViewport(0, 0, this->_framebufferWidth, this->_framebufferHeight);
@ -1652,6 +1665,9 @@ Render3DError OpenGLRenderer_3_2::RenderFog(const u8 *densityTable, const u32 co
glBindVertexArray(0);
glReadBuffer(GL_COLOR_ATTACHMENT1);
this->_lastTextureDrawTarget = OGLTextureUnitID_FinalColor;
return OGLERROR_NOERR;
}
@ -1743,6 +1759,7 @@ Render3DError OpenGLRenderer_3_2::ClearUsingValues(const FragmentColor &clearCol
OGLRenderRef &OGLRef = *this->ref;
OGLRef.selectedRenderingFBO = (CommonSettings.GFX3D_Renderer_Multisample) ? OGLRef.fboMSIntermediateRenderID : OGLRef.fboRenderID;
glBindFramebuffer(GL_FRAMEBUFFER, OGLRef.selectedRenderingFBO);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffers(4, RenderDrawList);
const GLfloat oglColor[4] = {divide6bitBy63_LUT[clearColor6665.r], divide6bitBy63_LUT[clearColor6665.g], divide6bitBy63_LUT[clearColor6665.b], divide5bitBy31_LUT[clearColor6665.a]};
@ -1905,13 +1922,6 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_FogAttr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, OGLRef.texPostprocessFogID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glBindRenderbuffer(GL_RENDERBUFFER, OGLRef.rboFramebufferRGBA6665ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, w, h);
if (this->isMultisampledFBOSupported)
{
GLint maxSamples = (GLint)this->_deviceInfo.maxSamples;
@ -1928,6 +1938,8 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
glRenderbufferStorageMultisample(GL_RENDERBUFFER, maxSamples, GL_DEPTH24_STENCIL8, w, h);
}
glActiveTexture(GL_TEXTURE0);
const size_t newFramebufferColorSizeBytes = w * h * sizeof(FragmentColor);
glBufferData(GL_PIXEL_PACK_BUFFER, newFramebufferColorSizeBytes, NULL, GL_STREAM_READ);