nir/spirv: Implement ImageQuerySize for storage iamges
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 5 Jan 2016 22:03:58 +0000 (14:03 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 19 Jan 2016 01:21:05 +0000 (17:21 -0800)
SPIR-V only has one ImageQuerySize opcode that has to work for both
textures and storage images.  Therefore, we have to special-case that one a
bit and look at the type of the incoming image handle.

src/glsl/nir/spirv/spirv_to_nir.c

index ef24156a48e5e6d78cbc2209ffc5a7c9b548e06b..4110c3571c67fe7caf835c5b3e95e89d6447df6b 100644 (file)
@@ -2594,6 +2594,12 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
       image = *vtn_value(b, w[3], vtn_value_type_image_pointer)->image;
       break;
 
+   case SpvOpImageQuerySize:
+      image.deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      image.coord = NULL;
+      image.sample = NULL;
+      break;
+
    case SpvOpImageRead:
       image.deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
       image.coord = get_image_coord(b, w[4]);
@@ -2627,6 +2633,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
    nir_intrinsic_op op;
    switch (opcode) {
 #define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
+   OP(ImageQuerySize,         size)
    OP(ImageRead,              load)
    OP(ImageWrite,             store)
    OP(AtomicExchange,         atomic_exchange)
@@ -2651,17 +2658,21 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
    intrin->variables[0] =
       nir_deref_as_var(nir_copy_deref(&intrin->instr, &image.deref->deref));
 
-   /* The image coordinate is always 4 components but we may not have that
-    * many.  Swizzle to compensate.
-    */
-   unsigned swiz[4];
-   for (unsigned i = 0; i < 4; i++)
-      swiz[i] = i < image.coord->num_components ? i : 0;
-   intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
-                                                swiz, 4, false));
-   intrin->src[1] = nir_src_for_ssa(image.sample);
+   /* ImageQuerySize doesn't take any extra parameters */
+   if (opcode != SpvOpImageQuerySize) {
+      /* The image coordinate is always 4 components but we may not have that
+       * many.  Swizzle to compensate.
+       */
+      unsigned swiz[4];
+      for (unsigned i = 0; i < 4; i++)
+         swiz[i] = i < image.coord->num_components ? i : 0;
+      intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
+                                                   swiz, 4, false));
+      intrin->src[1] = nir_src_for_ssa(image.sample);
+   }
 
    switch (opcode) {
+   case SpvOpImageQuerySize:
    case SpvOpImageRead:
       break;
    case SpvOpImageWrite:
@@ -3578,7 +3589,6 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
    case SpvOpImageGather:
    case SpvOpImageDrefGather:
    case SpvOpImageQuerySizeLod:
-   case SpvOpImageQuerySize:
    case SpvOpImageQueryLod:
    case SpvOpImageQueryLevels:
    case SpvOpImageQuerySamples:
@@ -3591,6 +3601,17 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
       vtn_handle_image(b, opcode, w, count);
       break;
 
+   case SpvOpImageQuerySize: {
+      nir_deref_var *image = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      const struct glsl_type *image_type = nir_deref_tail(&image->deref)->type;
+      if (glsl_type_is_image(image_type)) {
+         vtn_handle_image(b, opcode, w, count);
+      } else {
+         vtn_handle_texture(b, opcode, w, count);
+      }
+      break;
+   }
+
    case SpvOpAtomicExchange:
    case SpvOpAtomicCompareExchange:
    case SpvOpAtomicCompareExchangeWeak: