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

Marek Olšák maraeo at gmail.com
Fri Sep 7 21:37:01 UTC 2018


Ping

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
>


More information about the mesa-dev mailing list