[Mesa-dev] [PATCH 3/4] spirv: add sampler and image variable support when handling texture opcodes

Samuel Iglesias Gonsálvez siglesias at igalia.com
Fri Oct 6 09:36:20 UTC 2017


From: Samuel Iglesias Gonsalvez <correo at samuelig.es>

Signed-off-by: Samuel Iglesias Gonsalvez <correo at samuelig.es>
---
 src/compiler/spirv/spirv_to_nir.c | 58 +++++++++++++++++++++++++++++++--------
 1 file changed, 47 insertions(+), 11 deletions(-)

diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index 6ce9d1ada34..cf7617454de 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1489,17 +1489,37 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
    if (opcode == SpvOpSampledImage) {
       struct vtn_value *val =
          vtn_push_value(b, w[2], vtn_value_type_sampled_image);
-      val->sampled_image = ralloc(b, struct vtn_sampled_image);
-      val->sampled_image->image =
-         vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
-      val->sampled_image->sampler =
-         vtn_value(b, w[4], vtn_value_type_pointer)->pointer;
+      val->sampled_image = rzalloc(b, struct vtn_sampled_image);
+
+      struct vtn_value *img_val = vtn_untyped_value(b, w[3]);
+      struct vtn_value *sampler_val = vtn_untyped_value(b, w[4]);
+
+      if (img_val->value_type == vtn_value_type_pointer) {
+         val->sampled_image->image = img_val->pointer;
+      } else {
+         assert(img_val->value_type == vtn_value_type_image_variable);
+         val->sampled_image->var_image = img_val->var;
+      }
+
+      if (sampler_val->value_type == vtn_value_type_pointer) {
+         val->sampled_image->sampler = sampler_val->pointer;
+      } else {
+         assert(sampler_val->value_type == vtn_value_type_sampler_variable);
+         val->sampled_image->var_sampler = sampler_val->var;
+      }
       return;
    } else if (opcode == SpvOpImage) {
       struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer);
       struct vtn_value *src_val = vtn_untyped_value(b, w[3]);
       if (src_val->value_type == vtn_value_type_sampled_image) {
          val->pointer = src_val->sampled_image->image;
+         if (val->pointer == NULL && src_val->sampled_image->var_image != NULL) {
+            val->value_type = vtn_value_type_image_variable;
+            val->var = src_val->sampled_image->var_image;
+         } else if (val->pointer == NULL && src_val->sampled_image->var_sampler != NULL) {
+            val->value_type = vtn_value_type_sampler_variable;
+            val->var = src_val->sampled_image->var_sampler;
+         }
       } else {
          assert(src_val->value_type == vtn_value_type_pointer);
          val->pointer = src_val->pointer;
@@ -1510,21 +1530,32 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
    struct vtn_type *ret_type = vtn_value(b, w[1], vtn_value_type_type)->type;
    struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
 
-   struct vtn_sampled_image sampled;
+   struct vtn_sampled_image sampled = {NULL};
+   nir_deref_var *sampler = NULL;
    struct vtn_value *sampled_val = vtn_untyped_value(b, w[3]);
    if (sampled_val->value_type == vtn_value_type_sampled_image) {
       sampled = *sampled_val->sampled_image;
-   } else {
+      if (sampled.var_sampler)
+         sampler = nir_deref_var_create(b, sampled.var_sampler->var);
+   } else if (sampled_val->value_type == vtn_value_type_pointer) {
       assert(sampled_val->value_type == vtn_value_type_pointer);
       sampled.image = NULL;
       sampled.sampler = sampled_val->pointer;
+   } else {
+      assert(sampled_val->value_type == vtn_value_type_image_variable ||
+             sampled_val->value_type == vtn_value_type_sampler_variable);
+      sampler = nir_deref_var_create(b, sampled_val->var->var);
    }
 
    const struct glsl_type *image_type;
    if (sampled.image) {
       image_type = sampled.image->var->var->interface_type;
-   } else {
+   } else if (sampled.var_image) {
+      image_type = sampled.var_image->type->type;
+   } else if (sampled.sampler) {
       image_type = sampled.sampler->var->var->interface_type;
+   } else {
+      image_type = sampled_val->var->var->type;
    }
    const enum glsl_sampler_dim sampler_dim = glsl_get_sampler_dim(image_type);
    const bool is_array = glsl_sampler_type_is_array(image_type);
@@ -1741,10 +1772,15 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
       unreachable("Invalid base type for sampler result");
    }
 
-   nir_deref_var *sampler = vtn_pointer_to_deref(b, sampled.sampler);
+   if (!sampler)
+      sampler = vtn_pointer_to_deref(b, sampled.sampler);
    nir_deref_var *texture;
-   if (sampled.image) {
-      nir_deref_var *image = vtn_pointer_to_deref(b, sampled.image);
+   if (sampled.image || sampled.var_image) {
+      nir_deref_var *image;
+      if (!sampled.image && sampled.var_image)
+         image = nir_deref_var_create(b, sampled.var_image->var);
+      else
+         image = vtn_pointer_to_deref(b, sampled.image);
       texture = image;
    } else {
       texture = sampler;
-- 
2.13.6



More information about the mesa-dev mailing list