i965: Implement a drirc workaround for broken dual color blending.
OpenGL's dual color blending feature was specified so that an implementation could support both multiple render targets (MRT) and dual source blending. Fragment shader outputs specify both "location" (the render target number) and "index" (either color 0 or 1). I believe DirectX only has the notion of "location" - if using dual color blending, location 0 or 1 will specify the operands. If not, then location means the render target index. The two features can't be used together. As such, some applications mistakenly try to use <loc = 0, index = 0> and <loc = 1, index = 0> in a shader used for dual color blending with a single render target, rather than the correct <loc = 0, index = 0> and <loc = 0, index = 1>. In particular, Unigine Heaven 4.0 and Valley 1.0 suffer from this bug. Unigine is aware of the problem, and quickly developed a fix, but has not bothered to change the download link on their website to a working copy in over a year. People were still using the broken version and complaining. We tried working around this by disabling dual color blending, but that apparently hurts performance, and people were once again unhappy. On i965, dual source blending is achieved by using different framebuffer write messages than normal rendering. So, we have to compile different code for the two cases. We're not being pedantic: we actually have to know in order to function. Normally, dual source blending is detectable in the shader: if a shader has an output with index = 1, then it's meant for blending, not MRT. With the broken inputs, they're indistinguishable, so we can only tell by looking at the current GL state. This patch implements a new drirc workaround: export dual_color_blend_by_location=true which makes the i965 driver detect when OpenGL state is configured for dual source blending, and recompile the fragment shader to use the right messages. In that case, we allow either location = 1 or index = 1 to specify the second source for the blending equations. It also re-enables GL_ARB_blend_func_extended for Unigine. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92233 Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
cd9c07e7cd
commit
b3340cd32a
|
@ -37,26 +37,26 @@ TODO: document the other workarounds.
|
||||||
|
|
||||||
<application name="Unigine Heaven (32-bit)" executable="heaven_x86">
|
<application name="Unigine Heaven (32-bit)" executable="heaven_x86">
|
||||||
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
||||||
<!-- remove disable_blend_func_extended if 4.1 ever comes out -->
|
<!-- remove dual_color_blend_by_location if 4.1 ever comes out -->
|
||||||
<option name="disable_blend_func_extended" value="true" />
|
<option name="dual_color_blend_by_location" value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<application name="Unigine Heaven (64-bit)" executable="heaven_x64">
|
<application name="Unigine Heaven (64-bit)" executable="heaven_x64">
|
||||||
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
||||||
<!-- remove disable_blend_func_extended if 4.1 ever comes out -->
|
<!-- remove dual_color_blend_by_location if 4.1 ever comes out -->
|
||||||
<option name="disable_blend_func_extended" value="true" />
|
<option name="dual_color_blend_by_location" value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<application name="Unigine Valley (32-bit)" executable="valley_x86">
|
<application name="Unigine Valley (32-bit)" executable="valley_x86">
|
||||||
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
||||||
<!-- remove disable_blend_func_extended if 1.1 ever comes out -->
|
<!-- remove dual_color_blend_by_location if 1.1 ever comes out -->
|
||||||
<option name="disable_blend_func_extended" value="true" />
|
<option name="dual_color_blend_by_location" value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<application name="Unigine Valley (64-bit)" executable="valley_x64">
|
<application name="Unigine Valley (64-bit)" executable="valley_x64">
|
||||||
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
<option name="allow_glsl_extension_directive_midshader" value="true" />
|
||||||
<!-- remove disable_blend_func_extended if 1.1 ever comes out -->
|
<!-- remove dual_color_blend_by_location if 1.1 ever comes out -->
|
||||||
<option name="disable_blend_func_extended" value="true" />
|
<option name="dual_color_blend_by_location" value="true" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
|
<application name="Unigine OilRush (32-bit)" executable="OilRush_x86">
|
||||||
|
|
|
@ -90,6 +90,11 @@ DRI_CONF_OPT_BEGIN_B(disable_blend_func_extended, def) \
|
||||||
DRI_CONF_DESC(en,gettext("Disable dual source blending")) \
|
DRI_CONF_DESC(en,gettext("Disable dual source blending")) \
|
||||||
DRI_CONF_OPT_END
|
DRI_CONF_OPT_END
|
||||||
|
|
||||||
|
#define DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION(def) \
|
||||||
|
DRI_CONF_OPT_BEGIN_B(dual_color_blend_by_location, def) \
|
||||||
|
DRI_CONF_DESC(en,gettext("Identify dual color blending sources by location rather than index")) \
|
||||||
|
DRI_CONF_OPT_END
|
||||||
|
|
||||||
#define DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS(def) \
|
#define DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS(def) \
|
||||||
DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \
|
DRI_CONF_OPT_BEGIN_B(disable_glsl_line_continuations, def) \
|
||||||
DRI_CONF_DESC(en,gettext("Disable backslash-based line continuations in GLSL source")) \
|
DRI_CONF_DESC(en,gettext("Disable backslash-based line continuations in GLSL source")) \
|
||||||
|
|
|
@ -246,6 +246,7 @@ struct brw_wm_prog_key {
|
||||||
bool compute_sample_id:1;
|
bool compute_sample_id:1;
|
||||||
unsigned line_aa:2;
|
unsigned line_aa:2;
|
||||||
bool high_quality_derivatives:1;
|
bool high_quality_derivatives:1;
|
||||||
|
bool force_dual_color_blend:1;
|
||||||
|
|
||||||
uint16_t drawable_height;
|
uint16_t drawable_height;
|
||||||
uint64_t input_slots_valid;
|
uint64_t input_slots_valid;
|
||||||
|
|
|
@ -750,6 +750,9 @@ brw_process_driconf_options(struct brw_context *brw)
|
||||||
|
|
||||||
ctx->Const.AllowGLSLExtensionDirectiveMidShader =
|
ctx->Const.AllowGLSLExtensionDirectiveMidShader =
|
||||||
driQueryOptionb(options, "allow_glsl_extension_directive_midshader");
|
driQueryOptionb(options, "allow_glsl_extension_directive_midshader");
|
||||||
|
|
||||||
|
brw->dual_color_blend_by_location =
|
||||||
|
driQueryOptionb(options, "dual_color_blend_by_location");
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean
|
GLboolean
|
||||||
|
|
|
@ -836,6 +836,7 @@ struct brw_context
|
||||||
bool always_flush_cache;
|
bool always_flush_cache;
|
||||||
bool disable_throttling;
|
bool disable_throttling;
|
||||||
bool precompile;
|
bool precompile;
|
||||||
|
bool dual_color_blend_by_location;
|
||||||
|
|
||||||
driOptionCache optionCache;
|
driOptionCache optionCache;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
|
@ -130,7 +130,11 @@ fs_visitor::nir_setup_outputs()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MESA_SHADER_FRAGMENT:
|
case MESA_SHADER_FRAGMENT:
|
||||||
if (var->data.index > 0) {
|
if (key->force_dual_color_blend &&
|
||||||
|
var->data.location == FRAG_RESULT_DATA1) {
|
||||||
|
this->dual_src_output = reg;
|
||||||
|
this->do_dual_src = true;
|
||||||
|
} else if (var->data.index > 0) {
|
||||||
assert(var->data.location == FRAG_RESULT_DATA0);
|
assert(var->data.location == FRAG_RESULT_DATA0);
|
||||||
assert(var->data.index == 1);
|
assert(var->data.index == 1);
|
||||||
this->dual_src_output = reg;
|
this->dual_src_output = reg;
|
||||||
|
|
|
@ -515,6 +515,10 @@ brw_wm_populate_key(struct brw_context *brw, struct brw_wm_prog_key *key)
|
||||||
/* _NEW_BUFFERS */
|
/* _NEW_BUFFERS */
|
||||||
key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
|
key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
|
||||||
|
|
||||||
|
/* _NEW_COLOR */
|
||||||
|
key->force_dual_color_blend = brw->dual_color_blend_by_location &&
|
||||||
|
(ctx->Color.BlendEnabled & 1) && ctx->Color.Blend[0]._UsesDualSrc;
|
||||||
|
|
||||||
/* _NEW_MULTISAMPLE, _NEW_COLOR, _NEW_BUFFERS */
|
/* _NEW_MULTISAMPLE, _NEW_COLOR, _NEW_BUFFERS */
|
||||||
key->replicate_alpha = ctx->DrawBuffer->_NumColorDrawBuffers > 1 &&
|
key->replicate_alpha = ctx->DrawBuffer->_NumColorDrawBuffers > 1 &&
|
||||||
(ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled);
|
(ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled);
|
||||||
|
|
|
@ -79,6 +79,7 @@ DRI_CONF_BEGIN
|
||||||
DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
|
DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
|
||||||
DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
|
DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
|
||||||
DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
|
DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
|
||||||
|
DRI_CONF_DUAL_COLOR_BLEND_BY_LOCATION("false")
|
||||||
DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false")
|
DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false")
|
||||||
|
|
||||||
DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
|
DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
|
||||||
|
|
Loading…
Reference in New Issue