[Mesa-dev] [PATCH 4/7] radeonsi: make use of LOAD for UBOs

Timothy Arceri tarceri at itsqueeze.com
Tue Aug 29 23:50:28 UTC 2017


On 30/08/17 09:39, Marek Olšák wrote:
> Did you check shader-db for differences in code generation?

Yes, for more details and discussion please see the cover letter.

Thanks,
Tim

> 
> Marek
> 
> On Tue, Aug 22, 2017 at 2:14 PM, Timothy Arceri <tarceri at itsqueeze.com> wrote:
>> v2: always set can_speculate and allow_smem to true
>> ---
>>   src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c | 31 +++++++++++++++--------
>>   1 file changed, 21 insertions(+), 10 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..83cd8cd938 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_CONSTBUF) {
>>                  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_CONSTBUF;
>> +               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;
>>
>> @@ -407,21 +413,21 @@ static unsigned get_load_intr_attribs(bool can_speculate)
>>
>>   static unsigned get_store_intr_attribs(bool writeonly_memory)
>>   {
>>          return writeonly_memory && HAVE_LLVM >= 0x0400 ?
>>                                    LP_FUNC_ATTR_INACCESSIBLE_MEM_ONLY :
>>                                    LP_FUNC_ATTR_WRITEONLY;
>>   }
>>
>>   static void load_emit_buffer(struct si_shader_context *ctx,
>>                               struct lp_build_emit_data *emit_data,
>> -                            bool can_speculate)
>> +                            bool can_speculate, bool allow_smem)
>>   {
>>          const struct tgsi_full_instruction *inst = emit_data->inst;
>>          uint writemask = inst->Dst[0].Register.WriteMask;
>>          uint count = util_last_bit(writemask);
>>          LLVMValueRef *args = emit_data->args;
>>
>>          /* Don't use SMEM for shader buffer loads, because LLVM doesn't
>>           * select SMEM for SI.load.const with a non-constant offset, and
>>           * constant offsets practically don't exist with shader buffers.
>>           *
>> @@ -434,21 +440,21 @@ static void load_emit_buffer(struct si_shader_context *ctx,
>>           *       After that, si_memory_barrier should invalidate sL1 for shader
>>           *       buffers.
>>           */
>>
>>          assert(LLVMConstIntGetZExtValue(args[1]) == 0); /* vindex */
>>          emit_data->output[emit_data->chan] =
>>                  ac_build_buffer_load(&ctx->ac, args[0], count, NULL,
>>                                       args[2], NULL, 0,
>>                                       LLVMConstIntGetZExtValue(args[3]),
>>                                       LLVMConstIntGetZExtValue(args[4]),
>> -                                    can_speculate, false);
>> +                                    can_speculate, allow_smem);
>>   }
>>
>>   static LLVMValueRef get_memory_ptr(struct si_shader_context *ctx,
>>                                      const struct tgsi_full_instruction *inst,
>>                                      LLVMTypeRef type, int arg)
>>   {
>>          struct gallivm_state *gallivm = &ctx->gallivm;
>>          LLVMBuilderRef builder = gallivm->builder;
>>          LLVMValueRef offset, ptr;
>>          int addr_space;
>> @@ -564,32 +570,37 @@ static void load_emit(
>>          const struct tgsi_full_instruction * inst = emit_data->inst;
>>          const struct tgsi_shader_info *info = &ctx->shader->selector->info;
>>          char intrinsic_name[64];
>>          bool can_speculate = false;
>>
>>          if (inst->Src[0].Register.File == TGSI_FILE_MEMORY) {
>>                  load_emit_memory(ctx, emit_data);
>>                  return;
>>          }
>>
>> +       if (inst->Src[0].Register.File == TGSI_FILE_CONSTBUF) {
>> +               load_emit_buffer(ctx, emit_data, true, true);
>> +               return;
>> +       }
>> +
>>          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) {
>> -               load_emit_buffer(ctx, emit_data, can_speculate);
>> +               load_emit_buffer(ctx, emit_data, can_speculate, false);
>>                  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));
>>          } else {
>> @@ -629,21 +640,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 +860,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 +1068,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