From 8a48b42e4c79e1d55e28c4d2f67ed72e39057a14 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 29 Dec 2011 00:32:06 -0600 Subject: [PATCH] Add support for Dual source blending to older ATI cards that don't support 420pack but do support GL_ARB_blend_func_extended. This is more proper as well anyways. --- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 15 ++++-- Source/Core/VideoCommon/Src/VideoConfig.h | 1 + .../Plugin_VideoOGL/Src/PixelShaderCache.cpp | 1 - .../Src/ProgramShaderCache.cpp | 8 +++ Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 51 +++++++++++-------- .../Plugin_VideoOGL/Src/VertexManager.cpp | 2 +- .../Plugin_VideoOGL/Src/VertexShaderCache.cpp | 2 - 7 files changed, 53 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 277cd2e3e4..55a453c9b6 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -568,6 +568,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType if (g_ActiveConfig.backend_info.bSupportsGLSLATTRBind) WRITE(p, "#extension GL_ARB_explicit_attrib_location : enable\n"); + if (g_ActiveConfig.backend_info.bSupportsGLSLBlend) + WRITE(p, "#extension GL_ARB_blend_func_extended : enable\n"); // Silly differences WRITE(p, "#define float2 vec2\n"); WRITE(p, "#define float3 vec3\n"); @@ -693,13 +695,20 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType { // GLSL doesn't do main arguments // Once we switch to GLSL 1.3 we will bind a lot of these. - if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) { // This won't get hit unless we support GL 3.3 - WRITE(p, " layout(location = 0) out float4 ocol0;\n"); - WRITE(p, " layout(location = 0, index = 1) out float4 ocol1;\n"); // Will be supported later + if (g_ActiveConfig.backend_info.bSupportsGLSLBinding) + { + WRITE(p, " layout(location = 0) out float4 ocol0;\n"); + WRITE(p, " layout(location = 0, index = 1) out float4 ocol1;\n"); + } + else + { + WRITE(p, " out float4 ocol0;\n"); + WRITE(p, " out float4 ocol1;\n"); + } } else { diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index b8a7168dfe..d51d99d411 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -170,6 +170,7 @@ struct VideoConfig bool bSupportsGLSL; bool bSupportsGLSLBinding; + bool bSupportsGLSLBlend; bool bSupportsGLSLUBO; bool bSupportsGLSLATTRBind; bool bSupportsGLSLCache; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp index 026d3ec037..202f7dc58e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/PixelShaderCache.cpp @@ -406,7 +406,6 @@ bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) FILE *fp = fopen(szTemp, "wb"); fwrite(pstrprogram, strlen(pstrprogram), 1, fp); fclose(fp); - delete[] infoLog; } // Don't try to use this shader diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index eeb9614070..728e4e8a01 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -91,6 +91,14 @@ void ProgramShaderCache::SetProgramVariables(PCacheEntry &entry) if (entry.UniformLocations[a] != -1) glUniform1i(entry.UniformLocations[a], a); } + if (g_ActiveConfig.backend_info.bSupportsGLSLBlend) + { + // So we don't support binding, but we do support extended blending + // So we need to set a few more things here. + // Bind our out locations + glBindFragDataLocationIndexed(entry.prog_id, 0, 0, "ocol0"); + glBindFragDataLocationIndexed(entry.prog_id, 0, 1, "ocol1"); + } } // Need to get some attribute locations diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 494744a447..5054bf7390 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -316,6 +316,8 @@ Renderer::Renderer() // TODO: Switch over to using glew once 1.6/1.7 becomes more mainstream, seems most people are stuck in 1.5 if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_shading_language_420pack") != NULL) g_Config.backend_info.bSupportsGLSLBinding = true; + if (glewIsSupported("GL_ARB_blend_func_extended")) + g_Config.backend_info.bSupportsGLSLBlend = true; if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_uniform_buffer_object") != NULL) g_Config.backend_info.bSupportsGLSLUBO = true; if ((g_Config.backend_info.bSupportsGLSLBinding || g_Config.backend_info.bSupportsGLSLUBO) && strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_explicit_attrib_location") != NULL) @@ -963,7 +965,7 @@ void Renderer::SetBlendMode(bool forceUpdate) bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; - bool useDualSource = useDstAlpha && g_ActiveConfig.bUseGLSL && g_ActiveConfig.backend_info.bSupportsGLSLBinding; + bool useDualSource = useDstAlpha && g_ActiveConfig.bUseGLSL && g_ActiveConfig.backend_info.bSupportsGLSLBlend; if (changes & 1) // blend enable change @@ -974,33 +976,42 @@ void Renderer::SetBlendMode(bool forceUpdate) // subtract enable change GLenum equation = newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; GLenum equationAlpha = useDualSource ? GL_FUNC_ADD : equation; - glBlendEquationSeparate(equation, equationAlpha); + + if (g_ActiveConfig.backend_info.bSupportsGLSLBlend) + glBlendEquationSeparate(equation, equationAlpha); + else + glBlendEquation(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD); } if (changes & 0x1F8) { - GLenum srcFactor = glSrcFactors[(newval >> 3) & 7]; - GLenum srcFactorAlpha = srcFactor; - GLenum dstFactor = glDestFactors[(newval >> 6) & 7]; - GLenum dstFactorAlpha = dstFactor; - if (useDualSource) + if (g_ActiveConfig.backend_info.bSupportsGLSLBlend) { - srcFactorAlpha = GL_ONE; - dstFactorAlpha = GL_ZERO; + GLenum srcFactor = glSrcFactors[(newval >> 3) & 7]; + GLenum srcFactorAlpha = srcFactor; + GLenum dstFactor = glDestFactors[(newval >> 6) & 7]; + GLenum dstFactorAlpha = dstFactor; + if (useDualSource) + { + srcFactorAlpha = GL_ONE; + dstFactorAlpha = GL_ZERO; - if (srcFactor == GL_SRC_ALPHA) - srcFactor = GL_SRC1_ALPHA; - else if (srcFactor == GL_ONE_MINUS_SRC_ALPHA) - srcFactor = GL_ONE_MINUS_SRC1_ALPHA; + if (srcFactor == GL_SRC_ALPHA) + srcFactor = GL_SRC1_ALPHA; + else if (srcFactor == GL_ONE_MINUS_SRC_ALPHA) + srcFactor = GL_ONE_MINUS_SRC1_ALPHA; - if (dstFactor == GL_SRC_ALPHA) - dstFactor = GL_SRC1_ALPHA; - else if (dstFactor == GL_ONE_MINUS_SRC_ALPHA) - dstFactor = GL_ONE_MINUS_SRC1_ALPHA; + if (dstFactor == GL_SRC_ALPHA) + dstFactor = GL_SRC1_ALPHA; + else if (dstFactor == GL_ONE_MINUS_SRC_ALPHA) + dstFactor = GL_ONE_MINUS_SRC1_ALPHA; + } + + // blend RGB change + glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha); } - - // blend RGB change - glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha); + else + glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]); } s_blendMode = newval; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index f931f50c78..5a76c34d56 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -178,7 +178,7 @@ void VertexManager::vFlush() && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; // Makes sure we can actually do Dual source blending - bool dualSourcePossible = g_ActiveConfig.bUseGLSL && g_ActiveConfig.backend_info.bSupportsGLSLBinding; + bool dualSourcePossible = g_ActiveConfig.bUseGLSL && g_ActiveConfig.backend_info.bSupportsGLSLBlend; // finally bind FRAGMENTSHADER* ps; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp index f396e90078..810cd4c54a 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexShaderCache.cpp @@ -204,14 +204,12 @@ bool CompileGLSLVertexShader(VERTEXSHADER& vs, const char* pstrprogram) FILE *fp = fopen(szTemp, "wb"); fwrite(pstrprogram, strlen(pstrprogram), 1, fp); fclose(fp); - delete[] infoLog; } // Don't try to use this shader glDeleteShader(result); return false; } - (void)GL_REPORT_ERROR(); vs.glprogid = result; vs.bGLSL = true;