spirv: Use correct type for sampled images
authorAlex Smith <asmith@feralinteractive.com>
Mon, 6 Nov 2017 10:37:05 +0000 (10:37 +0000)
committerAlex Smith <asmith@feralinteractive.com>
Mon, 13 Nov 2017 13:37:50 +0000 (13:37 +0000)
We should use the result type of the OpSampledImage opcode, rather than
the type of the underlying image/samplers.

This resolves an issue when using separate images and shadow samplers
with glslang. Example:

    layout (...) uniform samplerShadow s0;
    layout (...) uniform texture2D res0;
    ...
    float result = textureLod(sampler2DShadow(res0, s0), uv, 0);

For this, for the combined OpSampledImage, the type of the base image
was being used (which does not have the Depth flag set, whereas the
result type does), therefore it was not being recognised as a shadow
sampler. This led to the wrong LLVM intrinsics being emitted by RADV.

Signed-off-by: Alex Smith <asmith@feralinteractive.com>
Cc: "17.2 17.3" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/spirv/spirv_to_nir.c
src/compiler/spirv/vtn_private.h
src/compiler/spirv/vtn_variables.c

index 6825e0d6a82ab8135bef97e4d48f2c30087305b0..93a515d731e0cf7a5976b4023442e7981fec1a89 100644 (file)
@@ -1490,6 +1490,8 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
       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->type =
+         vtn_value(b, w[1], vtn_value_type_type)->type;
       val->sampled_image->image =
          vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
       val->sampled_image->sampler =
@@ -1516,16 +1518,12 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
       sampled = *sampled_val->sampled_image;
    } else {
       assert(sampled_val->value_type == vtn_value_type_pointer);
+      sampled.type = sampled_val->pointer->type;
       sampled.image = NULL;
       sampled.sampler = sampled_val->pointer;
    }
 
-   const struct glsl_type *image_type;
-   if (sampled.image) {
-      image_type = sampled.image->var->var->interface_type;
-   } else {
-      image_type = sampled.sampler->var->var->interface_type;
-   }
+   const struct glsl_type *image_type = sampled.type->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);
    const bool is_shadow = glsl_sampler_type_is_shadow(image_type);
index 84584620fc1d55b4b8be56f800240ddc25349ac4..6b4645acc8b8fa100b3e64c81c6dc37c050bd8a2 100644 (file)
@@ -411,6 +411,7 @@ struct vtn_image_pointer {
 };
 
 struct vtn_sampled_image {
+   struct vtn_type *type;
    struct vtn_pointer *image; /* Image or array of images */
    struct vtn_pointer *sampler; /* Sampler */
 };
index 1cf9d597cf06460f7bf4fab8060c6e9821ba1668..9a69b4f6fc2e5357a6c4f33d4a4a296697c81c05 100644 (file)
@@ -1805,6 +1805,7 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
          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->type = base_val->sampled_image->type;
          val->sampled_image->image =
             vtn_pointer_dereference(b, base_val->sampled_image->image, chain);
          val->sampled_image->sampler = base_val->sampled_image->sampler;