From 1b808d208f7ae6b7934ada37378c654991a5ca5a Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 6 Jan 2020 08:27:49 +0100 Subject: [PATCH] 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 Reviewed-by: Bas Nieuwenhuizen --- 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 { -- 2.30.2