zink: fix binding-usage
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Fri, 14 Feb 2020 15:50:42 +0000 (16:50 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 17 Feb 2020 10:00:18 +0000 (10:00 +0000)
Rewriting the variable bindings is nasty and error-prone, and this code
triggered an assert when trying to resolve API bindings into Vulkan
bindings.

This code still needs some tweaks, but this makes things much better,
and fixes a few bugs where we incorrectly accounted for the
array-indexes.

Fixes: 1c3f4c07047 ("zink: fixup sampler-usage")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3826>

src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h
src/gallium/drivers/zink/zink_compiler.c

index 9e516eae56d70a499abc362fc7eade0e12f81a1e..b53a25feba5b5fb540db94a0d2fd4075aae0597b 100644 (file)
@@ -384,6 +384,31 @@ type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
    return SpvDim2D;
 }
 
+uint32_t
+zink_binding(gl_shader_stage stage, VkDescriptorType type, int index)
+{
+   if (stage == MESA_SHADER_NONE ||
+       stage >= MESA_SHADER_COMPUTE) {
+      unreachable("not supported");
+   } else {
+      uint32_t stage_offset = (uint32_t)stage * (PIPE_MAX_CONSTANT_BUFFERS +
+                                                 PIPE_MAX_SHADER_SAMPLER_VIEWS);
+
+      switch (type) {
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+         assert(index < PIPE_MAX_CONSTANT_BUFFERS);
+         return stage_offset + index;
+
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         assert(index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
+         return stage_offset + PIPE_MAX_CONSTANT_BUFFERS + index;
+
+      default:
+         unreachable("unexpected type");
+      }
+   }
+}
+
 static void
 emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
 {
@@ -416,7 +441,7 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
             spirv_builder_emit_name(&ctx->builder, var_id, var->name);
          }
 
-         int index = var->data.driver_location + i;
+         int index = var->data.binding + i;
          assert(!(ctx->samplers_used & (1 << index)));
          assert(!ctx->image_types[index]);
          ctx->image_types[index] = image_type;
@@ -425,7 +450,10 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
 
          spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
                                            var->data.descriptor_set);
-         spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+         int binding = zink_binding(ctx->stage,
+                                    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                    var->data.binding + i);
+         spirv_builder_emit_binding(&ctx->builder, var_id, binding);
       }
    } else {
       SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
@@ -434,7 +462,7 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
       if (var->name)
          spirv_builder_emit_name(&ctx->builder, var_id, var->name);
 
-      int index = var->data.driver_location;
+      int index = var->data.binding;
       assert(!(ctx->samplers_used & (1 << index)));
       assert(!ctx->image_types[index]);
       ctx->image_types[index] = image_type;
@@ -443,7 +471,10 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
 
       spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
                                         var->data.descriptor_set);
-      spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+      int binding = zink_binding(ctx->stage,
+                                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                 var->data.binding);
+      spirv_builder_emit_binding(&ctx->builder, var_id, binding);
    }
 }
 
@@ -484,7 +515,10 @@ emit_ubo(struct ntv_context *ctx, struct nir_variable *var)
 
    spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
                                      var->data.descriptor_set);
-   spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+   int binding = zink_binding(ctx->stage,
+                              VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+                              var->data.binding);
+   spirv_builder_emit_binding(&ctx->builder, var_id, binding);
 }
 
 static void
index 758ca901a2de44133ca5652a39210936eeced381..e709515da820b6803ecf664e9eb61df112bb362f 100644 (file)
@@ -28,6 +28,8 @@
 #include <stdint.h>
 #include <vulkan/vulkan.h>
 
+#include "compiler/shader_enums.h"
+
 struct spirv_shader {
    uint32_t *words;
    size_t num_words;
@@ -41,4 +43,7 @@ nir_to_spirv(struct nir_shader *s);
 void
 spirv_shader_delete(struct spirv_shader *s);
 
+uint32_t
+zink_binding(gl_shader_stage stage, VkDescriptorType type, int index);
+
 #endif
index f1981dbbd159dd73686494bb45bed7c56f9c8c4e..c8ad749ba744d1459f27cf7b3a7e0c8688eb400b 100644 (file)
@@ -210,30 +210,6 @@ optimize_nir(struct nir_shader *s)
    } while (progress);
 }
 
-static uint32_t
-zink_binding(enum pipe_shader_type stage, VkDescriptorType type, int index)
-{
-   if (stage == PIPE_SHADER_COMPUTE) {
-      unreachable("not supported");
-   } else {
-      uint32_t stage_offset = (uint32_t)stage * (PIPE_MAX_CONSTANT_BUFFERS +
-                                                 PIPE_MAX_SHADER_SAMPLER_VIEWS);
-
-      switch (type) {
-      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
-         assert(index < PIPE_MAX_CONSTANT_BUFFERS);
-         return stage_offset + index;
-
-      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-         assert(index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
-         return stage_offset + PIPE_MAX_CONSTANT_BUFFERS + index;
-
-      default:
-         unreachable("unexpected type");
-      }
-   }
-}
-
 struct zink_shader *
 zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir)
 {
@@ -253,14 +229,14 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir)
       fprintf(stderr, "---8<---\n");
    }
 
-   enum pipe_shader_type stage = pipe_shader_type_from_mesa(nir->info.stage);
-
    ret->num_bindings = 0;
    nir_foreach_variable(var, &nir->uniforms) {
       if (var->data.mode == nir_var_mem_ubo) {
+         int binding = zink_binding(nir->info.stage,
+                                    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
+                                    var->data.binding);
          ret->bindings[ret->num_bindings].index = var->data.binding;
-         var->data.binding = zink_binding(stage, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, var->data.binding);
-         ret->bindings[ret->num_bindings].binding = var->data.binding;
+         ret->bindings[ret->num_bindings].binding = binding;
          ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
          ret->num_bindings++;
       } else {
@@ -268,18 +244,20 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir)
          if (glsl_type_is_array(var->type) &&
              glsl_type_is_sampler(glsl_get_array_element(var->type))) {
             for (int i = 0; i < glsl_get_length(var->type); ++i) {
-               ret->bindings[ret->num_bindings].index = var->data.binding;
-               var->data.driver_location = var->data.binding + i;
-               var->data.binding = zink_binding(stage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, var->data.driver_location);
-               ret->bindings[ret->num_bindings].binding = var->data.binding;
+               int binding = zink_binding(nir->info.stage,
+                                          VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                          var->data.binding + i);
+               ret->bindings[ret->num_bindings].index = var->data.binding + i;
+               ret->bindings[ret->num_bindings].binding = binding;
                ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
                ret->num_bindings++;
             }
          } else if (glsl_type_is_sampler(var->type)) {
+            int binding = zink_binding(nir->info.stage,
+                                       VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                       var->data.binding);
             ret->bindings[ret->num_bindings].index = var->data.binding;
-            var->data.driver_location = var->data.binding;
-            var->data.binding = zink_binding(stage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, var->data.driver_location);
-            ret->bindings[ret->num_bindings].binding = var->data.binding;
+            ret->bindings[ret->num_bindings].binding = binding;
             ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
             ret->num_bindings++;
          }