[Mesa-dev] [PATCH 15/15] radeonsi/nir: port some bindless and sampler code from TGSI

Timothy Arceri tarceri at itsqueeze.com
Sat Sep 8 00:26:43 UTC 2018


On 08/09/18 07:37, Marek Olšák wrote:
> Ping

I had additional patches for bindless somewhere, tbh it's hard to know 
if this is all thats needed since we can't test but if you think this is 
correct feel free to push. It's not like it's going to break anything 
and we can always fix it later when core NIR finally gets bindless support.

> 
> On Wed, Aug 29, 2018 at 4:13 PM, Marek Olšák <maraeo at gmail.com> wrote:
>> From: Marek Olšák <marek.olsak at amd.com>
>>
>> These might be all missing changes for bindless textures.
>> ---
>>   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
>> @@ -890,64 +890,84 @@ si_nir_lookup_interp_param(struct ac_shader_abi *abi,
>>   }
>>
>>   static LLVMValueRef
>>   si_nir_load_sampler_desc(struct ac_shader_abi *abi,
>>                           unsigned descriptor_set, unsigned base_index,
>>                           unsigned constant_index, LLVMValueRef dynamic_index,
>>                           enum ac_descriptor_type desc_type, bool image,
>>                           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);
>>   }
>>
>>   static void bitcast_inputs(struct si_shader_context *ctx,
>>                             LLVMValueRef data[4],
>>                             unsigned input_idx)
>>   {
>>          for (unsigned chan = 0; chan < 4; chan++) {
>>                  ctx->inputs[input_idx + chan] =
>>                          LLVMBuildBitCast(ctx->ac.builder, data[chan], ctx->ac.i32, "");
>> --
>> 2.17.1
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list