From f984654da8bb022baa3531a19746427fa1ea981e Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 28 Sep 2020 15:47:38 +0200 Subject: [PATCH] ac/nir,radv: fix invalid IR when loading inline uniform blocks Fixes dEQP-VK.binding_model.descriptorset_random.* and dEQP-VK.binding_model.descriptor_copy.*. Fixes: 05b6612b4ec ("radv: do not lower UBO/SSBO access to offsets") Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/amd/llvm/ac_nir_to_llvm.c | 21 +++++++- src/amd/llvm/ac_shader_abi.h | 4 +- src/amd/vulkan/radv_nir_to_llvm.c | 61 +++++++++++----------- .../drivers/radeonsi/si_shader_llvm_resources.c | 4 +- 4 files changed, 56 insertions(+), 34 deletions(-) diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index 5702546..f07960e 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -2067,9 +2067,26 @@ static LLVMValueRef visit_load_ubo_buffer(struct ac_nir_context *ctx, nir_intrin LLVMValueRef rsrc = rsrc_base; LLVMValueRef offset = get_src(ctx, instr->src[1]); int num_components = instr->num_components; + unsigned desc_set = 0, binding = 0; + bool valid_binding = false; + + /* Look for vulkan_resource_index to get the desc_set/binding values which + * are used to determine if it's an inline uniform UBO block. + */ + if (instr->src[0].ssa->parent_instr->type == nir_instr_type_alu) { + nir_alu_instr *mov_instr = nir_instr_as_alu(instr->src[0].ssa->parent_instr); + if (mov_instr->src[0].src.ssa->parent_instr->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *idx_instr = nir_instr_as_intrinsic(mov_instr->src[0].src.ssa->parent_instr); + if (idx_instr->intrinsic == nir_intrinsic_vulkan_resource_index) { + desc_set = nir_intrinsic_desc_set(idx_instr); + binding = nir_intrinsic_binding(idx_instr); + valid_binding = true; + } + } + } if (ctx->abi->load_ubo) - rsrc = ctx->abi->load_ubo(ctx->abi, rsrc); + rsrc = ctx->abi->load_ubo(ctx->abi, desc_set, binding, valid_binding, rsrc); if (instr->dest.ssa.bit_size == 64) num_components *= 2; @@ -3766,7 +3783,7 @@ static LLVMValueRef get_bindless_index_from_uniform(struct ac_nir_context *ctx, index = LLVMBuildMul(ctx->ac.builder, index, LLVMConstInt(ctx->ac.i32, 8, 0), ""); offset = LLVMBuildAdd(ctx->ac.builder, offset, index, ""); - LLVMValueRef ubo_index = ctx->abi->load_ubo(ctx->abi, ctx->ac.i32_0); + LLVMValueRef ubo_index = ctx->abi->load_ubo(ctx->abi, 0, 0, false, ctx->ac.i32_0); LLVMValueRef ret = ac_build_buffer_load(&ctx->ac, ubo_index, 1, NULL, offset, NULL, 0, 0, true, true); diff --git a/src/amd/llvm/ac_shader_abi.h b/src/amd/llvm/ac_shader_abi.h index 5bb6204..a50ea1b 100644 --- a/src/amd/llvm/ac_shader_abi.h +++ b/src/amd/llvm/ac_shader_abi.h @@ -100,7 +100,9 @@ struct ac_shader_abi { LLVMValueRef (*load_tess_level)(struct ac_shader_abi *abi, unsigned varying_id, bool load_default_state); - LLVMValueRef (*load_ubo)(struct ac_shader_abi *abi, LLVMValueRef index); + LLVMValueRef (*load_ubo)(struct ac_shader_abi *abi, + unsigned desc_set, unsigned binding, + bool valid_binding, LLVMValueRef index); /** * Load the descriptor for the given buffer. diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c index bc2f495..e77c080 100644 --- a/src/amd/vulkan/radv_nir_to_llvm.c +++ b/src/amd/vulkan/radv_nir_to_llvm.c @@ -375,32 +375,6 @@ radv_load_resource(struct ac_shader_abi *abi, LLVMValueRef index, desc_ptr = ac_cast_ptr(&ctx->ac, desc_ptr, ctx->ac.v4i32); LLVMSetMetadata(desc_ptr, ctx->ac.uniform_md_kind, ctx->ac.empty_md); - if (layout->binding[binding].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) { - uint32_t desc_type = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | - S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) | - S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | - S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W); - - if (ctx->ac.chip_class >= GFX10) { - desc_type |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) | - S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) | - S_008F0C_RESOURCE_LEVEL(1); - } else { - desc_type |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) | - S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32); - } - - LLVMValueRef desc_components[4] = { - LLVMBuildPtrToInt(ctx->ac.builder, desc_ptr, ctx->ac.intptr, ""), - LLVMConstInt(ctx->ac.i32, S_008F04_BASE_ADDRESS_HI(ctx->args->options->address32_hi), false), - /* High limit to support variable sizes. */ - LLVMConstInt(ctx->ac.i32, 0xffffffff, false), - LLVMConstInt(ctx->ac.i32, desc_type, false), - }; - - return ac_build_gather_values(&ctx->ac, desc_components, 4); - } - return desc_ptr; } @@ -950,14 +924,41 @@ static LLVMValueRef radv_load_ssbo(struct ac_shader_abi *abi, return result; } -static LLVMValueRef radv_load_ubo(struct ac_shader_abi *abi, LLVMValueRef buffer_ptr) +static LLVMValueRef radv_load_ubo(struct ac_shader_abi *abi, + unsigned desc_set, unsigned binding, + bool valid_binding, LLVMValueRef buffer_ptr) { struct radv_shader_context *ctx = radv_shader_context_from_abi(abi); LLVMValueRef result; - if (LLVMGetTypeKind(LLVMTypeOf(buffer_ptr)) != LLVMPointerTypeKind) { - /* Do not load the descriptor for inlined uniform blocks. */ - return buffer_ptr; + if (valid_binding) { + struct radv_pipeline_layout *pipeline_layout = ctx->args->options->layout; + struct radv_descriptor_set_layout *layout = pipeline_layout->set[desc_set].layout; + + if (layout->binding[binding].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) { + uint32_t desc_type = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | + S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) | + S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | + S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W); + + if (ctx->ac.chip_class >= GFX10) { + desc_type |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) | + S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) | + S_008F0C_RESOURCE_LEVEL(1); + } else { + desc_type |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) | + S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32); + } + + LLVMValueRef desc_components[4] = { + LLVMBuildPtrToInt(ctx->ac.builder, buffer_ptr, ctx->ac.intptr, ""), + LLVMConstInt(ctx->ac.i32, S_008F04_BASE_ADDRESS_HI(ctx->args->options->address32_hi), false), + LLVMConstInt(ctx->ac.i32, 0xffffffff, false), + LLVMConstInt(ctx->ac.i32, desc_type, false), + }; + + return ac_build_gather_values(&ctx->ac, desc_components, 4); + } } LLVMSetMetadata(buffer_ptr, ctx->ac.uniform_md_kind, ctx->ac.empty_md); diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c b/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c index 9ba8e18..6cf26ac 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm_resources.c @@ -86,7 +86,9 @@ static LLVMValueRef load_const_buffer_desc_fast_path(struct si_shader_context *c return ac_build_gather_values(&ctx->ac, desc_elems, 4); } -static LLVMValueRef load_ubo(struct ac_shader_abi *abi, LLVMValueRef index) +static LLVMValueRef load_ubo(struct ac_shader_abi *abi, + unsigned desc_set, unsigned binding, + bool valid_binding, LLVMValueRef index) { struct si_shader_context *ctx = si_shader_context_from_abi(abi); struct si_shader_selector *sel = ctx->shader->selector; -- 2.7.4