spirv,nir: add new lod parameter to image_{load,store} intrinsics
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 6 Jan 2020 07:27:49 +0000 (08:27 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 9 Jan 2020 06:58:33 +0000 (07:58 +0100)
SPV_AMD_shader_image_load_store_lod allows to use a lod parameter
with OpImageRead, OpImageWrite and OpImageSparseRead.

According to the specification, this parameter should be a 32-bit
integer. It is initialized to 0 when no lod parameter is found
during SPIR-V->NIR translation.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_meta_bufimage.c
src/amd/vulkan/radv_meta_fast_clear.c
src/amd/vulkan/radv_meta_fmask_expand.c
src/amd/vulkan/radv_meta_resolve_cs.c
src/compiler/glsl/glsl_to_nir.cpp
src/compiler/nir/nir_intrinsics.py
src/compiler/spirv/spirv_to_nir.c
src/compiler/spirv/vtn_private.h
src/gallium/auxiliary/nir/tgsi_to_nir.c
src/mesa/state_tracker/st_pbo.c

index 0994d2ee92cb054d9dbf14df36c7941fd2daa20b..b5761b2607777bdc144292a5a3f8eb925bb02648 100644 (file)
@@ -121,6 +121,7 @@ build_nir_itob_compute_shader(struct radv_device *dev, bool is_3d)
        store->src[1] = nir_src_for_ssa(coord);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
 
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
@@ -348,6 +349,7 @@ build_nir_btoi_compute_shader(struct radv_device *dev, bool is_3d)
        store->src[1] = nir_src_for_ssa(img_coord);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
 
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
@@ -591,6 +593,7 @@ build_nir_btoi_r32g32b32_compute_shader(struct radv_device *dev)
                store->src[1] = nir_src_for_ssa(coord);
                store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
                store->src[3] = nir_src_for_ssa(nir_channel(&b, outval, chan));
+               store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
                nir_builder_instr_insert(&b, &store->instr);
        }
 
@@ -772,6 +775,7 @@ build_nir_itoi_compute_shader(struct radv_device *dev, bool is_3d)
        store->src[1] = nir_src_for_ssa(dst_coord);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
 
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
@@ -1018,6 +1022,7 @@ build_nir_itoi_r32g32b32_compute_shader(struct radv_device *dev)
                store->src[1] = nir_src_for_ssa(dst_coord);
                store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
                store->src[3] = nir_src_for_ssa(nir_channel(&b, outval, 0));
+               store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
                nir_builder_instr_insert(&b, &store->instr);
        }
 
@@ -1179,6 +1184,7 @@ build_nir_cleari_compute_shader(struct radv_device *dev, bool is_3d)
        store->src[1] = nir_src_for_ssa(global_id);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(&clear_val->dest.ssa);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
 
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
@@ -1377,6 +1383,7 @@ build_nir_cleari_r32g32b32_compute_shader(struct radv_device *dev)
                store->src[1] = nir_src_for_ssa(coord);
                store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
                store->src[3] = nir_src_for_ssa(nir_channel(&b, &clear_val->dest.ssa, chan));
+               store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
                nir_builder_instr_insert(&b, &store->instr);
        }
 
index aa04f6705561644109968bcf669bed9011cd2533..e0e83c2754ff7595e0c3c7147d26dbd91bd242f6 100644 (file)
@@ -97,6 +97,7 @@ build_dcc_decompress_compute_shader(struct radv_device *dev)
        store->src[1] = nir_src_for_ssa(global_id);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
 
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
index 607dc835a2433c85118b7855e25f5eb72672c996..ca0b82a3bf4155b3df91477675c4b9efba91ff08 100644 (file)
@@ -98,6 +98,7 @@ build_fmask_expand_compute_shader(struct radv_device *device, int samples)
                store->src[1] = nir_src_for_ssa(global_id);
                store->src[2] = nir_src_for_ssa(nir_imm_int(&b, i));
                store->src[3] = nir_src_for_ssa(outval);
+               store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
                nir_builder_instr_insert(&b, &store->instr);
        }
 
index d1d69cbd8ae1b9a03386e51576aaa83544313069..f1b38d3ffc8b5d4b2c429b0a4def56bc827d80da 100644 (file)
@@ -135,6 +135,7 @@ build_resolve_compute_shader(struct radv_device *dev, bool is_integer, bool is_s
        store->src[1] = nir_src_for_ssa(coord);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
 }
@@ -295,6 +296,7 @@ build_depth_stencil_resolve_compute_shader(struct radv_device *dev, int samples,
        store->src[1] = nir_src_for_ssa(coord);
        store->src[2] = nir_src_for_ssa(nir_ssa_undef(&b, 1, 32));
        store->src[3] = nir_src_for_ssa(outval);
+       store->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
        nir_builder_instr_insert(&b, &store->instr);
        return b.shader;
 }
index 494c0c2723a79c5d739a5ee3b240085dfc8fc590..479832b5ab0a56f5acdf3d97cee6ef5595f6ee15 100644 (file)
@@ -1373,13 +1373,18 @@ nir_visitor::visit(ir_call *ir)
             instr->src[3] =
                nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
             param = param->get_next();
+         } else if (op == nir_intrinsic_image_deref_load) {
+            instr->src[3] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */
          }
 
          if (!param->is_tail_sentinel()) {
             instr->src[4] =
                nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
             param = param->get_next();
+         } else if (op == nir_intrinsic_image_deref_store) {
+            instr->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0)); /* LOD */
          }
+
          nir_builder_instr_insert(&b, &instr->instr);
          break;
       }
index c53babdde552c7ce608a8241c599fcb777bdd4bd..4aa616d269e06df6ebad7649375a3425f3e3390e 100644 (file)
@@ -379,8 +379,8 @@ def image(name, src_comp=[], **kwargs):
     intrinsic("bindless_image_" + name, src_comp=[1] + src_comp,
               indices=[IMAGE_DIM, IMAGE_ARRAY, FORMAT, ACCESS], **kwargs)
 
-image("load", src_comp=[4, 1], dest_comp=0, flags=[CAN_ELIMINATE])
-image("store", src_comp=[4, 1, 0])
+image("load", src_comp=[4, 1, 1], dest_comp=0, flags=[CAN_ELIMINATE])
+image("store", src_comp=[4, 1, 0, 1])
 image("atomic_add",  src_comp=[4, 1, 1], dest_comp=1)
 image("atomic_imin",  src_comp=[4, 1, 1], dest_comp=1)
 image("atomic_umin",  src_comp=[4, 1, 1], dest_comp=1)
index a4b09a404df13bdbb8576955829789a528ea60d1..e54fc6906b8cf3ddb62cb5bdde1cddd73a5ef677 100644 (file)
@@ -2710,6 +2710,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
       val->image->image = vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
       val->image->coord = get_image_coord(b, w[4]);
       val->image->sample = vtn_ssa_value(b, w[5])->def;
+      val->image->lod = nir_imm_int(&b->nb, 0);
       return;
    }
 
@@ -2748,6 +2749,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
       image.image = vtn_value(b, w[3], vtn_value_type_pointer)->pointer;
       image.coord = NULL;
       image.sample = NULL;
+      image.lod = NULL;
       break;
 
    case SpvOpImageRead: {
@@ -2774,6 +2776,14 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
          scope = vtn_constant_uint(b, w[arg]);
       }
 
+      if (operands & SpvImageOperandsLodMask) {
+         uint32_t arg = image_operand_arg(b, w, count, 5,
+                                          SpvImageOperandsLodMask);
+         image.lod = vtn_ssa_value(b, w[arg])->def;
+      } else {
+         image.lod = nir_imm_int(&b->nb, 0);
+      }
+
       /* TODO: Volatile. */
 
       break;
@@ -2805,6 +2815,14 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
          scope = vtn_constant_uint(b, w[arg]);
       }
 
+      if (operands & SpvImageOperandsLodMask) {
+         uint32_t arg = image_operand_arg(b, w, count, 4,
+                                          SpvImageOperandsLodMask);
+         image.lod = vtn_ssa_value(b, w[arg])->def;
+      } else {
+         image.lod = nir_imm_int(&b->nb, 0);
+      }
+
       /* TODO: Volatile. */
 
       break;
@@ -2861,6 +2879,14 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
    case SpvOpAtomicLoad:
    case SpvOpImageQuerySize:
    case SpvOpImageRead:
+      if (opcode == SpvOpImageRead || opcode == SpvOpAtomicLoad) {
+         /* Only OpImageRead can support a lod parameter if
+          * SPV_AMD_shader_image_load_store_lod is used but the current NIR
+          * intrinsics definition for atomics requires us to set it for
+          * OpAtomicLoad.
+          */
+         intrin->src[3] = nir_src_for_ssa(image.lod);
+      }
       break;
    case SpvOpAtomicStore:
    case SpvOpImageWrite: {
@@ -2870,6 +2896,12 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
       assert(op == nir_intrinsic_image_deref_store);
       intrin->num_components = 4;
       intrin->src[3] = nir_src_for_ssa(expand_to_vec4(&b->nb, value));
+      /* Only OpImageWrite can support a lod parameter if
+       * SPV_AMD_shader_image_load_store_lod is used but the current NIR
+       * intrinsics definition for atomics requires us to set it for
+       * OpAtomicStore.
+       */
+      intrin->src[4] = nir_src_for_ssa(image.lod);
       break;
    }
 
index 7c7527582b4c3326a008607c982de62afff6a533..436bac8a664b76f9119bc5f91fbc4166603cdeba 100644 (file)
@@ -534,6 +534,7 @@ struct vtn_image_pointer {
    struct vtn_pointer *image;
    nir_ssa_def *coord;
    nir_ssa_def *sample;
+   nir_ssa_def *lod;
 };
 
 struct vtn_sampled_image {
index ddc97973b03522fa2d0c0bb4c1332a2885a57a13..bd59949da5c85e7fbe929c6574c6e8b43f787181 100644 (file)
@@ -1932,8 +1932,13 @@ ttn_mem(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
          instr->src[2] = nir_src_for_ssa(nir_ssa_undef(b, 1, 32));
       }
 
+      if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_LOAD) {
+         instr->src[3] = nir_src_for_ssa(nir_imm_int(b, 0)); /* LOD */
+      }
+
       if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_STORE) {
          instr->src[3] = nir_src_for_ssa(nir_swizzle(b, src[1], SWIZ(X, Y, Z, W), 4));
+         instr->src[4] = nir_src_for_ssa(nir_imm_int(b, 0)); /* LOD */
       }
 
       instr->num_components = 4;
index 639e0839245223be13f8a2d931d8b8b9f99cfea5..3f11a89759493e094782a97036a95b6f1d38301e 100644 (file)
@@ -557,6 +557,7 @@ create_fs_nir(struct st_context *st,
          nir_src_for_ssa(nir_vec4(&b, pbo_addr, zero, zero, zero));
       intrin->src[2] = nir_src_for_ssa(zero);
       intrin->src[3] = nir_src_for_ssa(result);
+      intrin->src[4] = nir_src_for_ssa(nir_imm_int(&b, 0));
       intrin->num_components = 4;
       nir_builder_instr_insert(&b, &intrin->instr);
    } else {