spirv: Handle image and sampler function parameters
authorJason Ekstrand <jason@jlekstrand.net>
Fri, 8 Dec 2017 07:42:16 +0000 (23:42 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 12 Dec 2017 15:34:46 +0000 (07:34 -0800)
src/compiler/spirv/vtn_cfg.c

index 9f3f55f07dce53eb333335aa9b47575d8d8cc633..8582c4f0e9433043e1ead8c5c1be3ef3a6a12f64 100644 (file)
 #include "vtn_private.h"
 #include "nir/nir_vla.h"
 
+static struct vtn_pointer *
+vtn_pointer_for_image_or_sampler_variable(struct vtn_builder *b,
+                                          struct vtn_variable *var)
+{
+   assert(var->type->base_type == vtn_base_type_image ||
+          var->type->base_type == vtn_base_type_sampler);
+
+   struct vtn_type *ptr_type = rzalloc(b, struct vtn_type);
+   ptr_type->base_type = vtn_base_type_pointer;
+   ptr_type->storage_class = SpvStorageClassUniformConstant;
+   ptr_type->deref = var->type;
+
+   return vtn_pointer_for_variable(b, var, ptr_type);
+}
+
 static bool
 vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
                                    const uint32_t *w, unsigned count)
@@ -58,6 +73,17 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
             func->params[np].type = func_type->params[i]->deref->type;
             func->params[np].param_type = nir_parameter_inout;
             np++;
+         } else if (func_type->params[i]->base_type ==
+                    vtn_base_type_sampled_image) {
+            /* Sampled images are actually two parameters */
+            func->params = reralloc(b->shader, func->params,
+                                    nir_parameter, func->num_params++);
+            func->params[np].type = func_type->params[i]->type;
+            func->params[np].param_type = nir_parameter_in;
+            np++;
+            func->params[np].type = glsl_bare_sampler_type();
+            func->params[np].param_type = nir_parameter_in;
+            np++;
          } else {
             func->params[np].type = func_type->params[i]->type;
             func->params[np].param_type = nir_parameter_in;
@@ -114,6 +140,53 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
          param->name = ralloc_strdup(param, val->name);
 
          val->pointer = vtn_pointer_for_variable(b, vtn_var, type);
+      } else if (type->base_type == vtn_base_type_image ||
+                 type->base_type == vtn_base_type_sampler ||
+                 type->base_type == vtn_base_type_sampled_image) {
+         struct vtn_variable *vtn_var = rzalloc(b, struct vtn_variable);
+         vtn_var->type = type;
+         vtn_var->var = param;
+         param->interface_type = param->type;
+
+         if (type->base_type == vtn_base_type_sampled_image) {
+            /* Sampled images are actually two parameters.  The first is the
+             * image and the second is the sampler.
+             */
+            struct vtn_value *val =
+               vtn_push_value(b, w[2], vtn_value_type_sampled_image);
+
+            /* Name the parameter so it shows up nicely in NIR */
+            param->name = ralloc_strdup(param, val->name);
+
+            /* Adjust the type of the image variable to the image type */
+            vtn_var->type = type->image;
+
+            /* Now get the sampler parameter and set up its variable */
+            param = b->func->impl->params[b->func_param_idx++];
+            struct vtn_variable *sampler_var = rzalloc(b, struct vtn_variable);
+            sampler_var->type = rzalloc(b, struct vtn_type);
+            sampler_var->type->base_type = vtn_base_type_sampler;
+            sampler_var->type->type = glsl_bare_sampler_type();
+            sampler_var->var = param;
+            param->interface_type = param->type;
+            param->name = ralloc_strdup(param, val->name);
+
+            val->sampled_image = ralloc(b, struct vtn_sampled_image);
+            val->sampled_image->type = type;
+            val->sampled_image->image =
+               vtn_pointer_for_image_or_sampler_variable(b, vtn_var);
+            val->sampled_image->sampler =
+               vtn_pointer_for_image_or_sampler_variable(b, sampler_var);
+         } else {
+            struct vtn_value *val =
+               vtn_push_value(b, w[2], vtn_value_type_pointer);
+
+            /* Name the parameter so it shows up nicely in NIR */
+            param->name = ralloc_strdup(param, val->name);
+
+            val->pointer =
+               vtn_pointer_for_image_or_sampler_variable(b, vtn_var);
+         }
       } else {
          /* We're a regular SSA value. */
          struct vtn_ssa_value *param_ssa =