glsl/lower_samplers_as_deref: apply bindings for unused samplers
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Mon, 8 May 2023 13:15:08 +0000 (09:15 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 9 May 2023 12:44:27 +0000 (12:44 +0000)
if a sampler is never used (no derefs) then its binding will never be
applied here, leaving it with binding=0. this will clobber the real binding=0
sampler in driver backends, leading to errors, so try to iterate using
the same criteria as above and apply bindings in the same way

fixes #8974

cc: mesa-stable

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22902>

src/compiler/glsl/gl_nir_lower_samplers_as_deref.c

index 25d7acd..934369d 100644 (file)
@@ -382,11 +382,32 @@ gl_nir_lower_samplers_as_deref(nir_shader *shader,
                                                 nir_metadata_dominance,
                                                 &state);
 
+   if (progress) {
+      nir_remove_dead_derefs(shader);
+      if (!shader->info.internal && shader_program) {
+         /* try to apply bindings for unused samplers to avoid index zero clobbering in backends */
+         nir_foreach_uniform_variable(var, shader) {
+            /* ignore hidden variables */
+            if (!glsl_type_is_sampler(glsl_without_array(var->type)) ||
+                var->data.how_declared == nir_var_hidden)
+               continue;
+            bool found = false;
+            hash_table_foreach(state.remap_table, entry) {
+               if (var == entry->data) {
+                  found = true;
+                  break;
+               }
+            }
+            if (!found) {
+               /* same as lower_deref() */
+               var->data.binding = shader_program->data->UniformStorage[var->data.location].opaque[shader->info.stage].index;
+            }
+         }
+      }
+   }
+
    /* keys are freed automatically by ralloc */
    _mesa_hash_table_destroy(state.remap_table, NULL);
 
-   if (progress)
-      nir_remove_dead_derefs(shader);
-
    return progress;
 }