mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 08:20:12 +01:00
spirv: Work around the Doom shader bug
Doom shipped with a broken version of GLSLang which handles samplers as function arguments in a way that isn't spec-compliant. In particular, it creates a temporary local sampler variable and copies the sampler into it. While Dave has had a hack patch out for a while that gets it working, we've never landed it because we've been hoping that a game update would come out with fixed shaders. Unfortunately, no game update appears on to be on the horizon and I've found this issue in yet another application so I think we're stuck working around it. Hopefully, we can delete this code one day. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99467 Cc: "17.1" <mesa-stable@lists.freedesktop.org> Tested-by: Grazvydas Ignotas <notasas@gmail.com> Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
93055576ae
commit
1bd0acab21
2 changed files with 28 additions and 0 deletions
|
|
@ -288,6 +288,20 @@ struct vtn_variable {
|
|||
nir_variable *var;
|
||||
nir_variable **members;
|
||||
|
||||
/**
|
||||
* In some early released versions of GLSLang, it implemented all function
|
||||
* calls by making copies of all parameters into temporary variables and
|
||||
* passing those variables into the function. It even did so for samplers
|
||||
* and images which violates the SPIR-V spec. Unfortunately, two games
|
||||
* (Talos Principle and Doom) shipped with this old version of GLSLang and
|
||||
* also happen to pass samplers into functions. Talos Principle received
|
||||
* an update fairly shortly after release with an updated GLSLang. Doom,
|
||||
* on the other hand, has never received an update so we need to work
|
||||
* around this GLSLang issue in SPIR-V -> NIR. Hopefully, we can drop this
|
||||
* hack at some point in the future.
|
||||
*/
|
||||
struct vtn_access_chain *copy_prop_sampler;
|
||||
|
||||
struct vtn_access_chain chain;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ rewrite_deref_types(nir_deref *deref, const struct glsl_type *type)
|
|||
nir_deref_var *
|
||||
vtn_access_chain_to_deref(struct vtn_builder *b, struct vtn_access_chain *chain)
|
||||
{
|
||||
/* Do on-the-fly copy propagation for samplers. */
|
||||
if (chain->var->copy_prop_sampler)
|
||||
return vtn_access_chain_to_deref(b, chain->var->copy_prop_sampler);
|
||||
|
||||
nir_deref_var *deref_var;
|
||||
if (chain->var->var) {
|
||||
deref_var = nir_deref_var_create(b, chain->var->var);
|
||||
|
|
@ -1613,6 +1617,16 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
|
|||
case SpvOpStore: {
|
||||
struct vtn_access_chain *dest =
|
||||
vtn_value(b, w[1], vtn_value_type_access_chain)->access_chain;
|
||||
|
||||
if (glsl_type_is_sampler(dest->var->type->type)) {
|
||||
vtn_warn("OpStore of a sampler detected. Doing on-the-fly copy "
|
||||
"propagation to workaround the problem.");
|
||||
assert(dest->var->copy_prop_sampler == NULL);
|
||||
dest->var->copy_prop_sampler =
|
||||
vtn_value(b, w[2], vtn_value_type_access_chain)->access_chain;
|
||||
break;
|
||||
}
|
||||
|
||||
struct vtn_ssa_value *src = vtn_ssa_value(b, w[2]);
|
||||
vtn_variable_store(b, src, dest);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue