diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index fe0fc72a75..f423d6b6e6 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -332,6 +332,9 @@ void FramebufferManagerGLES::MakePixelTexture(const u8 *srcPixels, GEBufferForma } void FramebufferManagerGLES::DrawPixels(VirtualFramebuffer *vfb, int dstX, int dstY, const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, int width, int height) { + shaderManager_->DirtyLastShader(); + textureCacheGL_->ForgetLastTexture(); + float v0 = 0.0f, v1 = 1.0f; if (useBufferedRendering_ && vfb && vfb->fbo) { draw_->BindFramebufferAsRenderTarget(vfb->fbo); @@ -349,8 +352,8 @@ void FramebufferManagerGLES::DrawPixels(VirtualFramebuffer *vfb, int dstX, int d DisableState(); bool linearFilter = vfb || g_Config.iBufFilter == SCALE_LINEAR; - DrawActiveTexture(dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, v0, 1.0f, v1, draw2dprogram_, ROTATION_LOCKED_HORIZONTAL, linearFilter); - textureCacheGL_->ForgetLastTexture(); + glsl_bind(draw2dprogram_); + DrawActiveTexture(dstX, dstY, width, height, vfb->bufferWidth, vfb->bufferHeight, 0.0f, v0, 1.0f, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) { @@ -377,7 +380,11 @@ void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBuff PostShaderUniforms uniforms{}; CalculatePostShaderUniforms(480, 272, renderWidth_, renderHeight_, &uniforms); BindPostShader(uniforms); + } else { + glsl_bind(draw2dprogram_); } + } else { + glsl_bind(draw2dprogram_); } float u0 = 0.0f, u1 = 480.0f / 512.0f; float v0 = 0.0f, v1 = 1.0f; @@ -386,31 +393,23 @@ void FramebufferManagerGLES::DrawFramebufferToOutput(const u8 *srcPixels, GEBuff std::swap(v0, v1); bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; - GLSLProgram *program = draw2dprogram_; - if (applyPostShader && usePostShader_ && useBufferedRendering_) - program = postShaderProgram_; if (cardboardSettings.enabled) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, uvRotation, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } // x, y, w, h are relative coordinates against destW/destH, which is not very intuitive. -// TODO: This could totally use fbo_blit. -void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation, bool linearFilter) { - if (program != postShaderProgram_) { - shaderManager_->DirtyLastShader(); // dirty lastShader_ - glsl_bind(program); - } - +// TODO: This could totally use fbo_blit in many cases. +void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter) { float texCoords[8] = { u0,v0, u1,v0, @@ -458,6 +457,7 @@ void FramebufferManagerGLES::DrawActiveTexture(float x, float y, float w, float glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } + const GLSLProgram *program = glsl_get_program(); glEnableVertexAttribArray(program->a_position); glEnableVertexAttribArray(program->a_texcoord0); if (gstate_c.Supports(GPU_SUPPORTS_VAO)) { @@ -747,19 +747,20 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { // We are doing the DrawActiveTexture call directly to the backbuffer here. Hence, we must // flip V. GLSLProgram *program = draw2dprogram_; + glsl_bind(program); std::swap(v0, v1); if (cardboardSettings.enabled) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, uvRotation, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } else if (usePostShader_ && extraFBOs_.size() == 1 && !postShaderAtOutputResolution_) { // An additional pass, post-processing shader to the extra FBO. @@ -772,7 +773,7 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { CalculatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, renderWidth_, renderHeight_, &uniforms); BindPostShader(uniforms); bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; - DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, postShaderProgram_, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(0, 0, fbo_w, fbo_h, fbo_w, fbo_h, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, linearFilter); draw_->BindBackbufferAsRenderTarget(); @@ -787,20 +788,20 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { // We are doing the DrawActiveTexture call directly to the backbuffer after here. Hence, we must // flip V. std::swap(v0, v1); - GLSLProgram *program = draw2dprogram_; + glsl_bind(draw2dprogram_); linearFilter = !postShaderIsUpscalingFilter_ && g_Config.iBufFilter == SCALE_LINEAR; if (g_Config.bEnableCardboard) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, uvRotation, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } if (gl_extensions.GLES3 && glInvalidateFramebuffer != nullptr) { @@ -814,7 +815,6 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { std::swap(v0, v1); bool linearFilter = g_Config.iBufFilter == SCALE_LINEAR; - GLSLProgram *program = postShaderProgram_; shaderManager_->DirtyLastShader(); // dirty lastShader_ PostShaderUniforms uniforms{}; CalculatePostShaderUniforms(vfb->bufferWidth, vfb->bufferHeight, vfb->renderWidth, vfb->renderHeight, &uniforms); @@ -822,15 +822,15 @@ void FramebufferManagerGLES::CopyDisplayToOutput() { if (g_Config.bEnableCardboard) { // Left Eye Image glstate.viewport.set(cardboardSettings.leftEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); // Right Eye Image glstate.viewport.set(cardboardSettings.rightEyeXPosition, cardboardSettings.screenYPosition, cardboardSettings.screenWidth, cardboardSettings.screenHeight); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, ROTATION_LOCKED_HORIZONTAL, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, ROTATION_LOCKED_HORIZONTAL, linearFilter); } else { // Fullscreen Image glstate.viewport.set(0, 0, pixelWidth_, pixelHeight_); - DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, program, uvRotation, linearFilter); + DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, linearFilter); } } } @@ -1034,7 +1034,8 @@ void FramebufferManagerGLES::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, // Should maybe revamp that interface. float srcW = src->bufferWidth; float srcH = src->bufferHeight; - DrawActiveTexture(dstX1, dstY1, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, draw2dprogram_, ROTATION_LOCKED_HORIZONTAL, false); + glsl_bind(draw2dprogram_); + DrawActiveTexture(dstX1, dstY1, w * dstXFactor, h, dst->bufferWidth, dst->bufferHeight, srcX1 / srcW, srcY1 / srcH, srcX2 / srcW, srcY2 / srcH, ROTATION_LOCKED_HORIZONTAL, false); glBindTexture(GL_TEXTURE_2D, 0); textureCacheGL_->ForgetLastTexture(); glstate.viewport.restore(); diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 4df10c791a..3cda24600b 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -68,7 +68,7 @@ public: void DrawFramebufferToOutput(const u8 *srcPixels, GEBufferFormat srcPixelFormat, int srcStride, bool applyPostShader) override; // x,y,w,h are relative to destW, destH which fill out the target completely. - void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, GLSLProgram *program, int uvRotation, bool linearFilter); + void DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, bool linearFilter); void DestroyAllFBOs(bool forceDelete); diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index 7fbedd23e9..76dde4465d 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -215,7 +215,7 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe glstate.stencilMask.set(i); glUniform1f(u_stencilValue, i * (1.0f / 255.0f)); } - DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, stencilUploadProgram_, ROTATION_LOCKED_HORIZONTAL, false); + DrawActiveTexture(0, 0, dstBuffer->width, dstBuffer->height, dstBuffer->bufferWidth, dstBuffer->bufferHeight, 0.0f, 0.0f, 1.0f, 1.0f, ROTATION_LOCKED_HORIZONTAL, false); } glstate.stencilMask.set(0xFF); diff --git a/ext/native/gfx_es2/glsl_program.cpp b/ext/native/gfx_es2/glsl_program.cpp index 274afa396c..c0c08a7cd8 100644 --- a/ext/native/gfx_es2/glsl_program.cpp +++ b/ext/native/gfx_es2/glsl_program.cpp @@ -262,13 +262,21 @@ void glsl_destroy(GLSLProgram *program) { delete program; } +static const GLSLProgram *curProgram; + void glsl_bind(const GLSLProgram *program) { if (program) glUseProgram(program->program_); else glUseProgram(0); + curProgram = program; } void glsl_unbind() { glUseProgram(0); + curProgram = nullptr; } + +const GLSLProgram *glsl_get_program() { + return curProgram; +} \ No newline at end of file diff --git a/ext/native/gfx_es2/glsl_program.h b/ext/native/gfx_es2/glsl_program.h index c3fa909918..5db3c37d3b 100644 --- a/ext/native/gfx_es2/glsl_program.h +++ b/ext/native/gfx_es2/glsl_program.h @@ -59,6 +59,7 @@ void glsl_destroy(GLSLProgram *program); // are logged and the function returns false. bool glsl_recompile(GLSLProgram *program, std::string *error_message = 0); void glsl_bind(const GLSLProgram *program); +const GLSLProgram *glsl_get_program(); void glsl_unbind(); int glsl_attrib_loc(const GLSLProgram *program, const char *name); int glsl_uniform_loc(const GLSLProgram *program, const char *name);