radeonsi/nir: port some bindless and sampler code from TGSI
authorMarek Olšák <marek.olsak@amd.com>
Wed, 29 Aug 2018 06:45:49 +0000 (02:45 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 10 Sep 2018 19:23:21 +0000 (15:23 -0400)
These might be all missing changes for bindless textures.

Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/gallium/drivers/radeonsi/si_shader_nir.c

index 5d6280b80f7e1b4a530c6cd1e79fcf2ac9d705e7..87ca0161b45a3e7c9d0bf8771e9091b1ea6dfc8b 100644 (file)
@@ -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);
 }