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.

This commit is contained in:
Ryan Houdek 2011-12-29 00:32:06 -06:00 committed by Sonicadvance1
parent 5085cebaf3
commit 2e15440896
7 changed files with 53 additions and 27 deletions

View File

@ -577,6 +577,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if (g_ActiveConfig.backend_info.bSupportsGLSLATTRBind) if (g_ActiveConfig.backend_info.bSupportsGLSLATTRBind)
WRITE(p, "#extension GL_ARB_explicit_attrib_location : enable\n"); 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 // Silly differences
WRITE(p, "#define float2 vec2\n"); WRITE(p, "#define float2 vec2\n");
WRITE(p, "#define float3 vec3\n"); WRITE(p, "#define float3 vec3\n");
@ -702,13 +704,20 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
{ {
// GLSL doesn't do main arguments // GLSL doesn't do main arguments
// Once we switch to GLSL 1.3 we will bind a lot of these. // Once we switch to GLSL 1.3 we will bind a lot of these.
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
{ {
// This won't get hit unless we support GL 3.3 // This won't get hit unless we support GL 3.3
WRITE(p, " layout(location = 0) out float4 ocol0;\n"); if (g_ActiveConfig.backend_info.bSupportsGLSLBinding)
WRITE(p, " layout(location = 0, index = 1) out float4 ocol1;\n"); // Will be supported later {
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 else
{ {

View File

@ -166,6 +166,7 @@ struct VideoConfig
bool bSupportsGLSL; bool bSupportsGLSL;
bool bSupportsGLSLBinding; bool bSupportsGLSLBinding;
bool bSupportsGLSLBlend;
bool bSupportsGLSLUBO; bool bSupportsGLSLUBO;
bool bSupportsGLSLATTRBind; bool bSupportsGLSLATTRBind;
bool bSupportsGLSLCache; bool bSupportsGLSLCache;

View File

@ -406,7 +406,6 @@ bool CompileGLSLPixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
FILE *fp = fopen(szTemp, "wb"); FILE *fp = fopen(szTemp, "wb");
fwrite(pstrprogram, strlen(pstrprogram), 1, fp); fwrite(pstrprogram, strlen(pstrprogram), 1, fp);
fclose(fp); fclose(fp);
delete[] infoLog; delete[] infoLog;
} }
// Don't try to use this shader // Don't try to use this shader

View File

@ -91,6 +91,14 @@ void ProgramShaderCache::SetProgramVariables(PCacheEntry &entry)
if (entry.UniformLocations[a] != -1) if (entry.UniformLocations[a] != -1)
glUniform1i(entry.UniformLocations[a], a); 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 // Need to get some attribute locations

View File

@ -319,6 +319,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 // 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) if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_shading_language_420pack") != NULL)
g_Config.backend_info.bSupportsGLSLBinding = true; 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) if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_uniform_buffer_object") != NULL)
g_Config.backend_info.bSupportsGLSLUBO = true; 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) if ((g_Config.backend_info.bSupportsGLSLBinding || g_Config.backend_info.bSupportsGLSLUBO) && strstr((const char*)glGetString(GL_EXTENSIONS), "GL_ARB_explicit_attrib_location") != NULL)
@ -960,7 +962,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; && 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) if (changes & 1)
// blend enable change // blend enable change
@ -971,33 +973,42 @@ void Renderer::SetBlendMode(bool forceUpdate)
// subtract enable change // subtract enable change
GLenum equation = newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD; GLenum equation = newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
GLenum equationAlpha = useDualSource ? GL_FUNC_ADD : equation; 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) if (changes & 0x1F8)
{ {
GLenum srcFactor = glSrcFactors[(newval >> 3) & 7]; if (g_ActiveConfig.backend_info.bSupportsGLSLBlend)
GLenum srcFactorAlpha = srcFactor;
GLenum dstFactor = glDestFactors[(newval >> 6) & 7];
GLenum dstFactorAlpha = dstFactor;
if (useDualSource)
{ {
srcFactorAlpha = GL_ONE; GLenum srcFactor = glSrcFactors[(newval >> 3) & 7];
dstFactorAlpha = GL_ZERO; 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) if (srcFactor == GL_SRC_ALPHA)
srcFactor = GL_SRC1_ALPHA; srcFactor = GL_SRC1_ALPHA;
else if (srcFactor == GL_ONE_MINUS_SRC_ALPHA) else if (srcFactor == GL_ONE_MINUS_SRC_ALPHA)
srcFactor = GL_ONE_MINUS_SRC1_ALPHA; srcFactor = GL_ONE_MINUS_SRC1_ALPHA;
if (dstFactor == GL_SRC_ALPHA) if (dstFactor == GL_SRC_ALPHA)
dstFactor = GL_SRC1_ALPHA; dstFactor = GL_SRC1_ALPHA;
else if (dstFactor == GL_ONE_MINUS_SRC_ALPHA) else if (dstFactor == GL_ONE_MINUS_SRC_ALPHA)
dstFactor = GL_ONE_MINUS_SRC1_ALPHA; dstFactor = GL_ONE_MINUS_SRC1_ALPHA;
}
// blend RGB change
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
} }
else
// blend RGB change glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]);
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
} }
s_blendMode = newval; s_blendMode = newval;

View File

@ -170,7 +170,7 @@ void VertexManager::vFlush()
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; && bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
// Makes sure we can actually do Dual source blending // 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 // finally bind
FRAGMENTSHADER* ps; FRAGMENTSHADER* ps;

View File

@ -204,14 +204,12 @@ bool CompileGLSLVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
FILE *fp = fopen(szTemp, "wb"); FILE *fp = fopen(szTemp, "wb");
fwrite(pstrprogram, strlen(pstrprogram), 1, fp); fwrite(pstrprogram, strlen(pstrprogram), 1, fp);
fclose(fp); fclose(fp);
delete[] infoLog; delete[] infoLog;
} }
// Don't try to use this shader // Don't try to use this shader
glDeleteShader(result); glDeleteShader(result);
return false; return false;
} }
(void)GL_REPORT_ERROR(); (void)GL_REPORT_ERROR();
vs.glprogid = result; vs.glprogid = result;
vs.bGLSL = true; vs.bGLSL = true;