diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader_internal.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader_nir.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c | 23 |
3 files changed, 33 insertions, 5 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h index a638dbf8f1a..235c46ecf92 100644 --- a/src/gallium/drivers/radeonsi/si_shader_internal.h +++ b/src/gallium/drivers/radeonsi/si_shader_internal.h @@ -305,7 +305,8 @@ LLVMValueRef si_load_sampler_desc(struct si_shader_context *ctx, enum ac_descriptor_type type); LLVMValueRef si_load_image_desc(struct si_shader_context *ctx, LLVMValueRef list, LLVMValueRef index, - enum ac_descriptor_type desc_type, bool dcc_off); + enum ac_descriptor_type desc_type, bool dcc_off, + bool bindless); void si_load_system_value(struct si_shader_context *ctx, unsigned index, diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index 0aefca22385..5d6280b80f7 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -920,7 +920,7 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi, index, ""); /* TODO: be smarter about when we use dcc_off */ - return si_load_image_desc(ctx, list, index, desc_type, write); + return si_load_image_desc(ctx, list, index, desc_type, write, bindless); } assert(base_index + constant_index < ctx->num_samplers); @@ -931,6 +931,16 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi, index = LLVMBuildAdd(ctx->ac.builder, index, LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), ""); + if (bindless) { + /* Since bindless handle arithmetic can contain an unsigned integer + * wraparound and si_load_sampler_desc assumes there isn't any, + * use GEP without "inbounds" (inside ac_build_pointer_add) + * to prevent incorrect code generation and hangs. + */ + index = LLVMBuildMul(ctx->ac.builder, index, LLVMConstInt(ctx->i32, 2, 0), ""); + list = ac_build_pointer_add(&ctx->ac, list, index); + index = ctx->i32_0; + } return si_load_sampler_desc(ctx, list, index, desc_type); } diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c index eaa200a95d6..cabc448a082 100644 --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c @@ -176,7 +176,8 @@ static LLVMValueRef force_dcc_off(struct si_shader_context *ctx, LLVMValueRef si_load_image_desc(struct si_shader_context *ctx, LLVMValueRef list, LLVMValueRef index, - enum ac_descriptor_type desc_type, bool dcc_off) + enum ac_descriptor_type desc_type, bool dcc_off, + bool bindless) { LLVMBuilderRef builder = ctx->ac.builder; LLVMValueRef rsrc; @@ -190,7 +191,11 @@ LLVMValueRef si_load_image_desc(struct si_shader_context *ctx, assert(desc_type == AC_DESC_IMAGE); } - rsrc = ac_build_load_to_sgpr(&ctx->ac, list, index); + if (bindless) + rsrc = ac_build_load_to_sgpr_uint_wraparound(&ctx->ac, list, index); + else + rsrc = ac_build_load_to_sgpr(&ctx->ac, list, index); + if (desc_type == AC_DESC_IMAGE && dcc_off) rsrc = force_dcc_off(ctx, rsrc); return rsrc; @@ -240,6 +245,8 @@ image_fetch_rsrc( index, ""); } + bool bindless = false; + if (image->Register.File != TGSI_FILE_IMAGE) { /* Bindless descriptors are accessible from a different pair of * user SGPR indices. @@ -254,11 +261,12 @@ image_fetch_rsrc( */ index = LLVMBuildMul(ctx->ac.builder, index, LLVMConstInt(ctx->i32, 2, 0), ""); + bindless = true; } *rsrc = si_load_image_desc(ctx, rsrc_ptr, index, target == TGSI_TEXTURE_BUFFER ? AC_DESC_BUFFER : AC_DESC_IMAGE, - dcc_off); + dcc_off, bindless); } static void image_fetch_coords( @@ -1068,6 +1076,15 @@ static void tex_fetch_ptrs(struct lp_build_tgsi_context *bld_base, ctx->param_bindless_samplers_and_images); index = lp_build_emit_fetch_src(bld_base, reg, TGSI_TYPE_UNSIGNED, 0); + + /* Since bindless handle arithmetic can contain an unsigned integer + * wraparound and si_load_sampler_desc assumes there isn't any, + * use GEP without "inbounds" (inside ac_build_pointer_add) + * to prevent incorrect code generation and hangs. + */ + index = LLVMBuildMul(ctx->ac.builder, index, LLVMConstInt(ctx->i32, 2, 0), ""); + list = ac_build_pointer_add(&ctx->ac, list, index); + index = ctx->i32_0; } if (target == TGSI_TEXTURE_BUFFER) |