glsl: correctly find block index when linking glsl with nir linker
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 3 Feb 2020 23:00:39 +0000 (10:00 +1100)
committerMarge Bot <eric+marge@anholt.net>
Fri, 6 Mar 2020 23:22:14 +0000 (23:22 +0000)
The existing code for spirv expects all vars to have explicit
bindings set which is not true for glsl.

Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4050>

src/compiler/glsl/gl_nir_link_uniforms.c

index 57a5595b34d28df4f1555bcad38395acf8aa8abd..abf6b6e74a5aad5369d6e09d1b0c510974919dbe 100644 (file)
@@ -768,10 +768,36 @@ nir_link_uniform(struct gl_context *ctx,
          int num_blocks = nir_variable_is_in_ssbo(state->current_var) ?
             prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;
 
-         for (unsigned i = 0; i < num_blocks; i++) {
-            if (state->current_var->data.binding == blocks[i].Binding) {
-               buffer_block_index = i;
-               break;
+         if (!prog->data->spirv) {
+            bool is_interface_array =
+               glsl_without_array(state->current_var->type) == state->current_var->interface_type &&
+               glsl_type_is_array(state->current_var->type);
+
+            const char *ifc_name =
+               glsl_get_type_name(state->current_var->interface_type);
+            if (is_interface_array) {
+               unsigned l = strlen(ifc_name);
+               for (unsigned i = 0; i < num_blocks; i++) {
+                  if (strncmp(ifc_name, blocks[i].Name, l) == 0 &&
+                      blocks[i].Name[l] == '[') {
+                     buffer_block_index = i;
+                     break;
+                  }
+               }
+            } else {
+               for (unsigned i = 0; i < num_blocks; i++) {
+                  if (strcmp(ifc_name, blocks[i].Name) == 0) {
+                     buffer_block_index = i;
+                     break;
+                  }
+               }
+            }
+         } else {
+            for (unsigned i = 0; i < num_blocks; i++) {
+               if (state->current_var->data.binding == blocks[i].Binding) {
+                  buffer_block_index = i;
+                  break;
+               }
             }
          }
          assert(buffer_block_index >= 0);