zink: support arrays of samplers
authorErik Faye-Lund <erik.faye-lund@collabora.com>
Fri, 3 Jan 2020 13:51:55 +0000 (14:51 +0100)
committerMarge Bot <eric+marge@anholt.net>
Sat, 18 Jan 2020 10:45:38 +0000 (10:45 +0000)
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3275>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3275>

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

index 922ed8c81f558c7b28dcff3cc632a8b9300f28ce..6d2d713b7f9171046c0c55bf037642db0c0ffad7 100644 (file)
@@ -386,13 +386,15 @@ type_to_dim(enum glsl_sampler_dim gdim, bool *is_ms)
 static void
 emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
 {
+   const struct glsl_type *type = glsl_without_array(var->type);
+
    bool is_ms;
-   SpvDim dimension = type_to_dim(glsl_get_sampler_dim(var->type), &is_ms);
+   SpvDim dimension = type_to_dim(glsl_get_sampler_dim(type), &is_ms);
 
-   SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(var->type));
+   SpvId result_type = get_glsl_basetype(ctx, glsl_get_sampler_result_type(type));
    SpvId image_type = spirv_builder_type_image(&ctx->builder, result_type,
                                                dimension, false,
-                                               glsl_sampler_type_is_array(var->type),
+                                               glsl_sampler_type_is_array(type),
                                                is_ms, 1,
                                                SpvImageFormatUnknown);
 
@@ -401,21 +403,45 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var)
    SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
                                                    SpvStorageClassUniformConstant,
                                                    sampled_type);
-   SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
-                                         SpvStorageClassUniformConstant);
 
-   if (var->name)
-      spirv_builder_emit_name(&ctx->builder, var_id, var->name);
+   if (glsl_type_is_array(var->type)) {
+      for (int i = 0; i < glsl_get_length(var->type); ++i) {
+         SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
+                                               SpvStorageClassUniformConstant);
 
-   assert(ctx->num_samplers < ARRAY_SIZE(ctx->image_types));
-   ctx->image_types[ctx->num_samplers] = image_type;
+         if (var->name) {
+            char element_name[100];
+            snprintf(element_name, sizeof(element_name), "%s_%d", var->name, i);
+            spirv_builder_emit_name(&ctx->builder, var_id, var->name);
+         }
 
-   assert(ctx->num_samplers < ARRAY_SIZE(ctx->samplers));
-   ctx->samplers[ctx->num_samplers++] = var_id;
+         assert(ctx->num_samplers < ARRAY_SIZE(ctx->image_types));
+         ctx->image_types[ctx->num_samplers] = image_type;
 
-   spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
-                                     var->data.descriptor_set);
-   spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+         assert(ctx->num_samplers < ARRAY_SIZE(ctx->samplers));
+         ctx->samplers[ctx->num_samplers++] = var_id;
+
+         spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
+                                           var->data.descriptor_set);
+         spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+      }
+   } else {
+      SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
+                                            SpvStorageClassUniformConstant);
+
+      if (var->name)
+         spirv_builder_emit_name(&ctx->builder, var_id, var->name);
+
+      assert(ctx->num_samplers < ARRAY_SIZE(ctx->image_types));
+      ctx->image_types[ctx->num_samplers] = image_type;
+
+      assert(ctx->num_samplers < ARRAY_SIZE(ctx->samplers));
+      ctx->samplers[ctx->num_samplers++] = var_id;
+
+      spirv_builder_emit_descriptor_set(&ctx->builder, var_id,
+                                        var->data.descriptor_set);
+      spirv_builder_emit_binding(&ctx->builder, var_id, var->data.binding);
+   }
 }
 
 static void
@@ -465,7 +491,7 @@ emit_uniform(struct ntv_context *ctx, struct nir_variable *var)
       emit_ubo(ctx, var);
    else {
       assert(var->data.mode == nir_var_uniform);
-      if (glsl_type_is_sampler(var->type))
+      if (glsl_type_is_sampler(glsl_without_array(var->type)))
          emit_sampler(ctx, var);
    }
 }
index 7a89dc1088a2612015eaf037df3fe40ca3f5dec1..a1428785bd47e421d3e295e3b0732c6c4e63797e 100644 (file)
@@ -256,18 +256,30 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir)
 
    ret->num_bindings = 0;
    nir_foreach_variable(var, &nir->uniforms) {
-      if (glsl_type_is_sampler(var->type)) {
-         ret->bindings[ret->num_bindings].index = var->data.driver_location;
-         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].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
-         ret->num_bindings++;
-      } else if (var->interface_type) {
+      if (var->data.mode == nir_var_mem_ubo) {
          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].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
          ret->num_bindings++;
+      } else {
+         assert(var->data.mode == nir_var_uniform);
+         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.driver_location + i;
+               var->data.binding = zink_binding(stage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, var->data.driver_location + i);
+               ret->bindings[ret->num_bindings].binding = var->data.binding;
+               ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+               ret->num_bindings++;
+            }
+         } else if (glsl_type_is_sampler(var->type)) {
+            ret->bindings[ret->num_bindings].index = var->data.driver_location;
+            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].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+            ret->num_bindings++;
+         }
       }
    }