From 867f7aaed2fd20a6a4a7d7e7895888c0c38889a1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 29 Aug 2018 02:45:49 -0400 Subject: [PATCH] radeonsi/nir: port some bindless and sampler code from TGSI MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These might be all missing changes for bindless textures. Tested-by: Dieter Nützel --- src/gallium/drivers/radeonsi/si_shader_nir.c | 80 ++++++++++++-------- 1 file changed, 50 insertions(+), 30 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c index 5d6280b80f7..87ca0161b45 100644 --- a/src/gallium/drivers/radeonsi/si_shader_nir.c +++ b/src/gallium/drivers/radeonsi/si_shader_nir.c @@ -897,50 +897,70 @@ si_nir_load_sampler_desc(struct ac_shader_abi *abi, bool write, bool bindless) { struct si_shader_context *ctx = si_shader_context_from_abi(abi); + const struct tgsi_shader_info *info = &ctx->shader->selector->info; LLVMBuilderRef builder = ctx->ac.builder; - LLVMValueRef list = LLVMGetParam(ctx->main_fn, ctx->param_samplers_and_images); - LLVMValueRef index; + unsigned const_index = base_index + constant_index; + bool dcc_off = write; + + /* TODO: images_store and images_atomic are not set */ + if (!dynamic_index && image && + (info->images_store | info->images_atomic) & (1 << const_index)) + dcc_off = true; assert(!descriptor_set); + assert(!image || desc_type == AC_DESC_IMAGE || desc_type == AC_DESC_BUFFER); - dynamic_index = dynamic_index ? dynamic_index : ctx->ac.i32_0; - index = LLVMBuildAdd(builder, dynamic_index, - LLVMConstInt(ctx->ac.i32, base_index + constant_index, false), - ""); + if (bindless) { + LLVMValueRef list = + LLVMGetParam(ctx->main_fn, ctx->param_bindless_samplers_and_images); - if (image) { - assert(desc_type == AC_DESC_IMAGE || desc_type == AC_DESC_BUFFER); - assert(base_index + constant_index < ctx->num_images); + /* dynamic_index is the bindless handle */ + if (image) { + return si_load_image_desc(ctx, list, dynamic_index, desc_type, + dcc_off, true); + } + + /* 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. + */ + dynamic_index = LLVMBuildMul(ctx->ac.builder, dynamic_index, + LLVMConstInt(ctx->i32, 2, 0), ""); + list = ac_build_pointer_add(&ctx->ac, list, dynamic_index); + return si_load_sampler_desc(ctx, list, ctx->i32_0, desc_type); + } + + unsigned num_slots = image ? ctx->num_images : ctx->num_samplers; + assert(const_index < num_slots); - if (dynamic_index) - index = si_llvm_bound_index(ctx, index, ctx->num_images); + LLVMValueRef list = LLVMGetParam(ctx->main_fn, ctx->param_samplers_and_images); + LLVMValueRef index = LLVMConstInt(ctx->ac.i32, const_index, false); + + if (dynamic_index) { + index = LLVMBuildAdd(builder, index, dynamic_index, ""); + + /* From the GL_ARB_shader_image_load_store extension spec: + * + * If a shader performs an image load, store, or atomic + * operation using an image variable declared as an array, + * and if the index used to select an individual element is + * negative or greater than or equal to the size of the + * array, the results of the operation are undefined but may + * not lead to termination. + */ + index = si_llvm_bound_index(ctx, index, num_slots); + } + if (image) { index = LLVMBuildSub(ctx->ac.builder, LLVMConstInt(ctx->i32, SI_NUM_IMAGES - 1, 0), index, ""); - - /* TODO: be smarter about when we use dcc_off */ - return si_load_image_desc(ctx, list, index, desc_type, write, bindless); + return si_load_image_desc(ctx, list, index, desc_type, dcc_off, false); } - assert(base_index + constant_index < ctx->num_samplers); - - if (dynamic_index) - index = si_llvm_bound_index(ctx, index, ctx->num_samplers); - 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); } -- 2.30.2