[Mesa-dev] [PATCH 09/11] radeonsi: make use of LOAD for UBOs

Marek Olšák maraeo at gmail.com
Mon Aug 21 21:50:51 UTC 2017


This will use vector loads (64 loads per 64 threads) instead of scalar
loads (1 load per 64 threads). Vector loads are much slower.
allow_smem should be set to allow scalar loads for constbufs.

Also, can_speculate should be true for constbuf loads.

I think you really need to check shader-db or shader asm dumps,
because this clearly decreases performance of all shaders using UBOs.

Marek

On Thu, Aug 17, 2017 at 1:03 PM, Timothy Arceri <tarceri at itsqueeze.com> wrote:
> ---
>  src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c | 23 +++++++++++++++--------
>  1 file changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
> index f8c99ff7e7..05ca710094 100644
> --- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
> +++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
> @@ -66,32 +66,36 @@ static LLVMValueRef get_buffer_size(
>                                       LLVMConstInt(ctx->i32, 0x3FFF, 0), "");
>
>                 size = LLVMBuildUDiv(builder, size, stride, "");
>         }
>
>         return size;
>  }
>
>  static LLVMValueRef
>  shader_buffer_fetch_rsrc(struct si_shader_context *ctx,
> -                        const struct tgsi_full_src_register *reg)
> +                        const struct tgsi_full_src_register *reg,
> +                        bool ubo)
>  {
>         LLVMValueRef index;
>
>         if (!reg->Register.Indirect) {
>                 index = LLVMConstInt(ctx->i32, reg->Register.Index, false);
>         } else {
>                 index = si_get_indirect_index(ctx, &reg->Indirect,
>                                               reg->Register.Index);
>         }
>
> -       return ctx->abi.load_ssbo(&ctx->abi, index, false);
> +       if (ubo)
> +               return ctx->abi.load_ubo(&ctx->abi, index);
> +       else
> +               return ctx->abi.load_ssbo(&ctx->abi, index, false);
>  }
>
>  static bool tgsi_is_array_sampler(unsigned target)
>  {
>         return target == TGSI_TEXTURE_1D_ARRAY ||
>                target == TGSI_TEXTURE_SHADOW1D_ARRAY ||
>                target == TGSI_TEXTURE_2D_ARRAY ||
>                target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
>                target == TGSI_TEXTURE_CUBE_ARRAY ||
>                target == TGSI_TEXTURE_SHADOWCUBE_ARRAY ||
> @@ -356,26 +360,28 @@ static void load_fetch_args(
>                 struct lp_build_emit_data * emit_data)
>  {
>         struct si_shader_context *ctx = si_shader_context(bld_base);
>         struct gallivm_state *gallivm = &ctx->gallivm;
>         const struct tgsi_full_instruction * inst = emit_data->inst;
>         unsigned target = inst->Memory.Texture;
>         LLVMValueRef rsrc;
>
>         emit_data->dst_type = ctx->v4f32;
>
> -       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
> +       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
> +                  inst->Src[0].Register.File == TGSI_FILE_UBO) {
>                 LLVMBuilderRef builder = gallivm->builder;
>                 LLVMValueRef offset;
>                 LLVMValueRef tmp;
>
> -               rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
> +               bool ubo = inst->Src[0].Register.File == TGSI_FILE_UBO;
> +               rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], ubo);
>
>                 tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
>                 offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
>
>                 buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
>                                    offset, false, false);
>         } else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE ||
>                    tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
>                 LLVMValueRef coords;
>
> @@ -574,21 +580,22 @@ static void load_emit(
>         if (inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE)
>                 si_emit_waitcnt(ctx, VM_CNT);
>
>         can_speculate = !(inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE) &&
>                           is_oneway_access_only(inst, info,
>                                                 info->shader_buffers_store |
>                                                 info->shader_buffers_atomic,
>                                                 info->images_store |
>                                                 info->images_atomic);
>
> -       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
> +       if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
> +           inst->Src[0].Register.File == TGSI_FILE_UBO) {
>                 load_emit_buffer(ctx, emit_data, can_speculate);
>                 return;
>         }
>
>         if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
>                 emit_data->output[emit_data->chan] =
>                         lp_build_intrinsic(
>                                 builder, "llvm.amdgcn.buffer.load.format.v4f32", emit_data->dst_type,
>                                 emit_data->args, emit_data->arg_count,
>                                 get_load_intr_attribs(can_speculate));
> @@ -629,21 +636,21 @@ static void store_fetch_args(
>         data = lp_build_gather_values(gallivm, chans, 4);
>
>         emit_data->args[emit_data->arg_count++] = data;
>
>         memory = tgsi_full_src_register_from_dst(&inst->Dst[0]);
>
>         if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER) {
>                 LLVMValueRef offset;
>                 LLVMValueRef tmp;
>
> -               rsrc = shader_buffer_fetch_rsrc(ctx, &memory);
> +               rsrc = shader_buffer_fetch_rsrc(ctx, &memory, false);
>
>                 tmp = lp_build_emit_fetch(bld_base, inst, 0, 0);
>                 offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
>
>                 buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
>                                    offset, false, false);
>         } else if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE ||
>                    tgsi_is_bindless_image_file(inst->Dst[0].Register.File)) {
>                 unsigned target = inst->Memory.Texture;
>                 LLVMValueRef coords;
> @@ -849,21 +856,21 @@ static void atomic_fetch_args(
>         /* llvm.amdgcn.image/buffer.atomic.cmpswap reflect the hardware order
>          * of arguments, which is reversed relative to TGSI (and GLSL)
>          */
>         if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS)
>                 emit_data->args[emit_data->arg_count++] = data2;
>         emit_data->args[emit_data->arg_count++] = data1;
>
>         if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
>                 LLVMValueRef offset;
>
> -               rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
> +               rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
>
>                 tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
>                 offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
>
>                 buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
>                                    offset, true, false);
>         } else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE ||
>                    tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
>                 unsigned target = inst->Memory.Texture;
>                 LLVMValueRef coords;
> @@ -1057,21 +1064,21 @@ static void resq_fetch_args(
>                 struct lp_build_tgsi_context * bld_base,
>                 struct lp_build_emit_data * emit_data)
>  {
>         struct si_shader_context *ctx = si_shader_context(bld_base);
>         const struct tgsi_full_instruction *inst = emit_data->inst;
>         const struct tgsi_full_src_register *reg = &inst->Src[0];
>
>         emit_data->dst_type = ctx->v4i32;
>
>         if (reg->Register.File == TGSI_FILE_BUFFER) {
> -               emit_data->args[0] = shader_buffer_fetch_rsrc(ctx, reg);
> +               emit_data->args[0] = shader_buffer_fetch_rsrc(ctx, reg, false);
>                 emit_data->arg_count = 1;
>         } else if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
>                 image_fetch_rsrc(bld_base, reg, false, inst->Memory.Texture,
>                                  &emit_data->args[0]);
>                 emit_data->arg_count = 1;
>         } else {
>                 LLVMValueRef res_ptr;
>                 unsigned image_target;
>
>                 if (inst->Memory.Texture == TGSI_TEXTURE_3D)
> --
> 2.13.4
>
> _______________________________________________
> 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