OpenGL plugin: Support for dual-source blending, CURRENTLY DISABLED. It doesn't work yet. To fix it, we may need to convert all our shaders to GLSL so that we can use glBindFragDataLocation.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6306 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
91186d2b8a
commit
2ec3db44ed
|
@ -22,7 +22,7 @@ static const char ID[4] = {'D', 'C', 'A', 'C'};
|
||||||
// Update this to the current SVN revision every time you change shader generation code.
|
// Update this to the current SVN revision every time you change shader generation code.
|
||||||
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
// We don't automatically get this from SVN_REV because that would mean regenerating the
|
||||||
// shader cache for every revision, graphics-related or not, which is simply annoying.
|
// shader cache for every revision, graphics-related or not, which is simply annoying.
|
||||||
const int version = 6296;
|
const int version = 6306;
|
||||||
|
|
||||||
LinearDiskCache::LinearDiskCache()
|
LinearDiskCache::LinearDiskCache()
|
||||||
: file_(NULL), num_entries_(0) {
|
: file_(NULL), num_entries_(0) {
|
||||||
|
|
|
@ -519,8 +519,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
|
||||||
WRITE(p, "void main(\n");
|
WRITE(p, "void main(\n");
|
||||||
if(ApiType != API_D3D11)
|
if(ApiType != API_D3D11)
|
||||||
{
|
{
|
||||||
// TODO: Support DSTALPHA_DUAL_SOURCE_BLEND for non-D3D11 shaders
|
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
|
||||||
WRITE(p, " out float4 ocol0 : COLOR0,%s\n in float4 rawpos : %s,\n",
|
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
|
||||||
DepthTextureEnable ? "\n out float depth : DEPTH," : "",
|
DepthTextureEnable ? "\n out float depth : DEPTH," : "",
|
||||||
ApiType == API_OPENGL ? "WPOS" : "POSITION");
|
ApiType == API_OPENGL ? "WPOS" : "POSITION");
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,4 +136,9 @@ extern CGcontext g_cgcontext;
|
||||||
extern CGprofile g_cgvProf, g_cgfProf;
|
extern CGprofile g_cgvProf, g_cgfProf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XXX: Dual-source blending in OpenGL does not work correctly yet. To make it
|
||||||
|
// work, we may need to use glBindFragDataLocation. To use that, we need to
|
||||||
|
// use GLSL shaders across the whole pipeline. Yikes!
|
||||||
|
const bool USE_DUAL_SOURCE_BLEND = false;
|
||||||
|
|
||||||
#endif // _GLINIT_H_
|
#endif // _GLINIT_H_
|
||||||
|
|
|
@ -151,7 +151,7 @@ static const GLenum glSrcFactors[8] =
|
||||||
GL_DST_COLOR,
|
GL_DST_COLOR,
|
||||||
GL_ONE_MINUS_DST_COLOR,
|
GL_ONE_MINUS_DST_COLOR,
|
||||||
GL_SRC_ALPHA,
|
GL_SRC_ALPHA,
|
||||||
GL_ONE_MINUS_SRC_ALPHA,
|
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
|
||||||
GL_DST_ALPHA,
|
GL_DST_ALPHA,
|
||||||
GL_ONE_MINUS_DST_ALPHA
|
GL_ONE_MINUS_DST_ALPHA
|
||||||
};
|
};
|
||||||
|
@ -162,7 +162,7 @@ static const GLenum glDestFactors[8] = {
|
||||||
GL_SRC_COLOR,
|
GL_SRC_COLOR,
|
||||||
GL_ONE_MINUS_SRC_COLOR,
|
GL_ONE_MINUS_SRC_COLOR,
|
||||||
GL_SRC_ALPHA,
|
GL_SRC_ALPHA,
|
||||||
GL_ONE_MINUS_SRC_ALPHA,
|
GL_ONE_MINUS_SRC_ALPHA, // NOTE: If dual-source blending is enabled, use SRC1_ALPHA
|
||||||
GL_DST_ALPHA,
|
GL_DST_ALPHA,
|
||||||
GL_ONE_MINUS_DST_ALPHA
|
GL_ONE_MINUS_DST_ALPHA
|
||||||
};
|
};
|
||||||
|
@ -1034,17 +1034,47 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
|
|
||||||
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
|
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
|
||||||
|
|
||||||
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
|
||||||
|
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
||||||
|
bool useDualSource = USE_DUAL_SOURCE_BLEND && useDstAlpha && GLEW_ARB_blend_func_extended;
|
||||||
|
|
||||||
if (changes & 1)
|
if (changes & 1)
|
||||||
// blend enable change
|
// blend enable change
|
||||||
(newval & 1) ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
(newval & 1) ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||||
|
|
||||||
if (changes & 4)
|
if (changes & 4)
|
||||||
|
{
|
||||||
// subtract enable change
|
// subtract enable change
|
||||||
glBlendEquation(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;
|
||||||
|
glBlendEquationSeparate(equation, equationAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
if (changes & 0x1F8)
|
if (changes & 0x1F8)
|
||||||
|
{
|
||||||
|
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 (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
|
// blend RGB change
|
||||||
glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]);
|
glBlendFuncSeparate(srcFactor, dstFactor, srcFactorAlpha, dstFactorAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
s_blendMode = newval;
|
s_blendMode = newval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,8 +184,31 @@ void VertexManager::vFlush()
|
||||||
VertexShaderManager::SetConstants();
|
VertexShaderManager::SetConstants();
|
||||||
PixelShaderManager::SetConstants();
|
PixelShaderManager::SetConstants();
|
||||||
|
|
||||||
|
bool useDstAlpha = !g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate
|
||||||
|
&& bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
|
||||||
|
bool dualSourcePossible = USE_DUAL_SOURCE_BLEND && GLEW_ARB_blend_func_extended;
|
||||||
|
|
||||||
// finally bind
|
// finally bind
|
||||||
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
FRAGMENTSHADER* ps;
|
||||||
|
if (dualSourcePossible)
|
||||||
|
{
|
||||||
|
if (useDstAlpha)
|
||||||
|
{
|
||||||
|
// If host supports GL_ARB_blend_func_extended, we can do dst alpha in
|
||||||
|
// the same pass as regular rendering.
|
||||||
|
Renderer::SetBlendMode(true);
|
||||||
|
ps = PixelShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Renderer::SetBlendMode(true);
|
||||||
|
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components);
|
||||||
|
}
|
||||||
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
|
||||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
|
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
|
||||||
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
|
if (vs) VertexShaderCache::SetCurrentShader(vs->glprogid);
|
||||||
|
@ -193,10 +216,8 @@ void VertexManager::vFlush()
|
||||||
Draw();
|
Draw();
|
||||||
|
|
||||||
// run through vertex groups again to set alpha
|
// run through vertex groups again to set alpha
|
||||||
if (!g_ActiveConfig.bDstAlphaPass && bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate)
|
if (useDstAlpha && !dualSourcePossible)
|
||||||
{
|
{
|
||||||
// TODO: If host supports GL_ARB_blend_func_extended, use
|
|
||||||
// DSTALPHA_DUAL_SOURCE_BLEND and set blend modes accordingly.
|
|
||||||
ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components);
|
ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components);
|
||||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue