Mesa (master): spirv,nir: add new lod parameter to image_{load,store} intrinsics

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 9 07:21:58 UTC 2020


Module: Mesa
Branch: master
Commit: 1b808d208f7ae6b7934ada37378c654991a5ca5a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1b808d208f7ae6b7934ada37378c654991a5ca5a

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Mon Jan  6 08:27:49 2020 +0100

spirv,nir: add new lod parameter to image_{load,store} intrinsics

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 at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

---

 src/amd/vulkan/radv_meta_bufimage.c     |  7 +++++++
 src/amd/vulkan/radv_meta_fast_clear.c   |  1 +
 src/amd/vulkan/radv_meta_fmask_expand.c |  1 +
 src/amd/vulkan/radv_meta_resolve_cs.c   |  2 ++
 src/compiler/glsl/glsl_to_nir.cpp       |  5 +++++
 src/compiler/nir/nir_intrinsics.py      |  4 ++--
 src/compiler/spirv/spirv_to_nir.c       | 32 ++++++++++++++++++++++++++++++++
 src/compiler/spirv/vtn_private.h        |  1 +
 src/gallium/auxiliary/nir/tgsi_to_nir.c |  5 +++++
 src/mesa/state_tracker/st_pbo.c         |  1 +
 10 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/amd/vulkan/radv_meta_bufimage.c b/src/amd/vulkan/radv_meta_bufimage.c
index 0994d2ee92c..b5761b26077 100644
--- a/src/amd/vulkan/radv_meta_bufimage.c
+++ b/src/amd/vulkan/radv_meta_bufimage.c
@@ -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);
 	}
 
diff --git a/src/amd/vulkan/radv_meta_fast_clear.c b/src/amd/vulkan/radv_meta_fast_clear.c
index aa04f670556..e0e83c2754f 100644
--- a/src/amd/vulkan/radv_meta_fast_clear.c
+++ b/src/amd/vulkan/radv_meta_fast_clear.c
@@ -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;
diff --git a/src/amd/vulkan/radv_meta_fmask_expand.c b/src/amd/vulkan/radv_meta_fmask_expand.c
index 607dc835a24..ca0b82a3bf4 100644
--- a/src/amd/vulkan/radv_meta_fmask_expand.c
+++ b/src/amd/vulkan/radv_meta_fmask_expand.c
@@ -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);
 	}
 
diff --git a/src/amd/vulkan/radv_meta_resolve_cs.c b/src/amd/vulkan/radv_meta_resolve_cs.c
index d1d69cbd8ae..f1b38d3ffc8 100644
--- a/src/amd/vulkan/radv_meta_resolve_cs.c
+++ b/src/amd/vulkan/radv_meta_resolve_cs.c
@@ -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;
 }
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 494c0c2723a..479832b5ab0 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -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;
       }
diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
index c53babdde55..4aa616d269e 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -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)
diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c
index a4b09a404df..e54fc6906b8 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -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;
    }
 
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 7c7527582b4..436bac8a664 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -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 {
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index ddc97973b03..bd59949da5c 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c
index 639e0839245..3f11a897594 100644
--- a/src/mesa/state_tracker/st_pbo.c
+++ b/src/mesa/state_tracker/st_pbo.c
@@ -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 {




More information about the mesa-commit mailing list