[Mesa-dev] [PATCH 11/11] glsl_to_tgsi: skip UARL for 1D registers if the driver doesn't need it

Nicolai Hähnle nhaehnle at gmail.com
Mon Oct 2 11:12:06 UTC 2017


On 29.09.2017 14:25, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
> 
> ---
>   src/mesa/state_tracker/st_glsl_to_tgsi.cpp       | 45 +++++++++++++++++++-----
>   src/mesa/state_tracker/st_glsl_to_tgsi_private.h |  8 +++++
>   2 files changed, 44 insertions(+), 9 deletions(-)
> 
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index e9d98ed..879ae65 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -186,20 +186,21 @@ public:
>      bool indirect_addr_consts;
>      int wpos_transform_const;
>   
>      int glsl_version;
>      bool native_integers;
>      bool have_sqrt;
>      bool have_fma;
>      bool use_shared_memory;
>      bool has_tex_txf_lz;
>      bool precise;
> +   bool need_uarl;
>   
>      variable_storage *find_variable_storage(ir_variable *var);
>   
>      int add_constant(gl_register_file file, gl_constant_value values[8],
>                       int size, int datatype, uint16_t *swizzle_out);
>   
>      st_src_reg get_temp(const glsl_type *type);
>      void reladdr_to_temp(ir_instruction *ir, st_src_reg *reg, int *num_reladdr);
>   
>      st_src_reg st_src_reg_for_double(double val);
> @@ -796,22 +797,26 @@ glsl_to_tgsi_visitor::emit_scalar(ir_instruction *ir, unsigned op,
>   
>      emit_scalar(ir, op, dst, src0, undef);
>   }
>   
>   void
>   glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
>                                  st_dst_reg dst, st_src_reg src0)
>   {
>      int op = TGSI_OPCODE_ARL;
>   
> -   if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
> -      op = TGSI_OPCODE_UARL;
> +   if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT) {
> +      if (this->need_uarl || !src0.is_legal_tgsi_address_operand())
> +         op = TGSI_OPCODE_UARL;
> +      else
> +         return;

I'd find this cleaner as

   if (!this->need_uarl && src0.is_legal_tgsi_address_operand())
      return;
   op = TGSI_OPCODE_UARL;

I also sent some comments on patches 3, 7, and 9. Apart from those, the 
series is

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>


> +   }
>   
>      assert(dst.file == PROGRAM_ADDRESS);
>      if (dst.index >= this->num_address_regs)
>         this->num_address_regs = dst.index + 1;
>   
>      emit_asm(NULL, op, dst, src0);
>   }
>   
>   int
>   glsl_to_tgsi_visitor::add_constant(gl_register_file file,
> @@ -5319,20 +5324,21 @@ struct st_translate {
>      unsigned *array_sizes;
>      struct inout_decl *input_decls;
>      unsigned num_input_decls;
>      struct inout_decl *output_decls;
>      unsigned num_output_decls;
>   
>      const ubyte *inputMapping;
>      const ubyte *outputMapping;
>   
>      unsigned procType;  /**< PIPE_SHADER_VERTEX/FRAGMENT */
> +   bool need_uarl;
>   };
>   
>   /** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */
>   unsigned
>   _mesa_sysval_to_semantic(unsigned sysval)
>   {
>      switch (sysval) {
>      /* Vertex shader */
>      case SYSTEM_VALUE_VERTEX_ID:
>         return TGSI_SEMANTIC_VERTEXID;
> @@ -5515,20 +5521,33 @@ dst_register(struct st_translate *t, gl_register_file file, unsigned index,
>   
>      case PROGRAM_ADDRESS:
>         return t->address[index];
>   
>      default:
>         assert(!"unknown dst register file");
>         return ureg_dst_undef();
>      }
>   }
>   
> +static struct ureg_src
> +translate_src(struct st_translate *t, const st_src_reg *src_reg);
> +
> +static struct ureg_src
> +translate_addr(struct st_translate *t, const st_src_reg *reladdr,
> +               unsigned addr_index)
> +{
> +   if (t->need_uarl || !reladdr->is_legal_tgsi_address_operand())
> +      return ureg_src(t->address[addr_index]);
> +
> +   return translate_src(t, reladdr);
> +}
> +
>   /**
>    * Create a TGSI ureg_dst register from an st_dst_reg.
>    */
>   static struct ureg_dst
>   translate_dst(struct st_translate *t,
>                 const st_dst_reg *dst_reg,
>                 bool saturate)
>   {
>      struct ureg_dst dst = dst_register(t, dst_reg->file, dst_reg->index,
>                                         dst_reg->array_id);
> @@ -5536,26 +5555,27 @@ translate_dst(struct st_translate *t,
>      if (dst.File == TGSI_FILE_NULL)
>         return dst;
>   
>      dst = ureg_writemask(dst, dst_reg->writemask);
>   
>      if (saturate)
>         dst = ureg_saturate(dst);
>   
>      if (dst_reg->reladdr != NULL) {
>         assert(dst_reg->file != PROGRAM_TEMPORARY);
> -      dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
> +      dst = ureg_dst_indirect(dst, translate_addr(t, dst_reg->reladdr, 0));
>      }
>   
>      if (dst_reg->has_index2) {
>         if (dst_reg->reladdr2)
> -         dst = ureg_dst_dimension_indirect(dst, ureg_src(t->address[1]),
> +         dst = ureg_dst_dimension_indirect(dst,
> +                                           translate_addr(t, dst_reg->reladdr2, 1),
>                                              dst_reg->index2D);
>         else
>            dst = ureg_dst_dimension(dst, dst_reg->index2D);
>      }
>   
>      return dst;
>   }
>   
>   /**
>    * Create a TGSI ureg_src register from an st_src_reg.
> @@ -5644,41 +5664,42 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
>      default:
>         assert(!"unknown src register file");
>         return ureg_src_undef();
>      }
>   
>      if (src_reg->has_index2) {
>         /* 2D indexes occur with geometry shader inputs (attrib, vertex)
>          * and UBO constant buffers (buffer, position).
>          */
>         if (src_reg->reladdr2)
> -         src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]),
> +         src = ureg_src_dimension_indirect(src,
> +                                           translate_addr(t, src_reg->reladdr2, 1),
>                                              src_reg->index2D);
>         else
>            src = ureg_src_dimension(src, src_reg->index2D);
>      }
>   
>      src = ureg_swizzle(src,
>                         GET_SWZ(src_reg->swizzle, 0) & 0x3,
>                         GET_SWZ(src_reg->swizzle, 1) & 0x3,
>                         GET_SWZ(src_reg->swizzle, 2) & 0x3,
>                         GET_SWZ(src_reg->swizzle, 3) & 0x3);
>   
>      if (src_reg->abs)
>         src = ureg_abs(src);
>   
>      if ((src_reg->negate & 0xf) == NEGATE_XYZW)
>         src = ureg_negate(src);
>   
>      if (src_reg->reladdr != NULL) {
>         assert(src_reg->file != PROGRAM_TEMPORARY);
> -      src = ureg_src_indirect(src, ureg_src(t->address[0]));
> +      src = ureg_src_indirect(src, translate_addr(t, src_reg->reladdr, 0));
>      }
>   
>      return src;
>   }
>   
>   static struct tgsi_texture_offset
>   translate_tex_offset(struct st_translate *t,
>                        const st_src_reg *in_offset)
>   {
>      struct tgsi_texture_offset offset;
> @@ -5752,21 +5773,22 @@ compile_tgsi_instruction(struct st_translate *t,
>      case TGSI_OPCODE_LODQ:
>         if (inst->resource.file == PROGRAM_SAMPLER) {
>            src[num_src] = t->samplers[inst->resource.index];
>         } else {
>            /* Bindless samplers. */
>            src[num_src] = translate_src(t, &inst->resource);
>         }
>         assert(src[num_src].File != TGSI_FILE_NULL);
>         if (inst->resource.reladdr)
>            src[num_src] =
> -            ureg_src_indirect(src[num_src], ureg_src(t->address[2]));
> +            ureg_src_indirect(src[num_src],
> +                              translate_addr(t, inst->resource.reladdr, 2));
>         num_src++;
>         for (i = 0; i < (int)inst->tex_offset_num_offset; i++) {
>            texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
>         }
>         tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
>   
>         ureg_tex_insn(ureg,
>                       inst->op,
>                       dst, num_dst,
>                       tex_target,
> @@ -5801,21 +5823,22 @@ compile_tgsi_instruction(struct st_translate *t,
>            assert(inst->resource.file != PROGRAM_UNDEFINED);
>            if (inst->resource.file == PROGRAM_IMAGE) {
>               src[0] = t->images[inst->resource.index];
>            } else {
>               /* Bindless images. */
>               src[0] = translate_src(t, &inst->resource);
>            }
>            tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
>         }
>         if (inst->resource.reladdr)
> -         src[0] = ureg_src_indirect(src[0], ureg_src(t->address[2]));
> +         src[0] = ureg_src_indirect(src[0],
> +                                    translate_addr(t, inst->resource.reladdr, 2));
>         assert(src[0].File != TGSI_FILE_NULL);
>         ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
>                          inst->buffer_access,
>                          tex_target, inst->image_format);
>         break;
>   
>      case TGSI_OPCODE_STORE:
>         if (inst->resource.file == PROGRAM_MEMORY) {
>            dst[0] = ureg_dst(t->shared_memory);
>         } else if (inst->resource.file == PROGRAM_BUFFER) {
> @@ -5824,21 +5847,22 @@ compile_tgsi_instruction(struct st_translate *t,
>            if (inst->resource.file == PROGRAM_IMAGE) {
>               dst[0] = ureg_dst(t->images[inst->resource.index]);
>            } else {
>               /* Bindless images. */
>               dst[0] = ureg_dst(translate_src(t, &inst->resource));
>            }
>            tex_target = st_translate_texture_target(inst->tex_target, inst->tex_shadow);
>         }
>         dst[0] = ureg_writemask(dst[0], inst->dst[0].writemask);
>         if (inst->resource.reladdr)
> -         dst[0] = ureg_dst_indirect(dst[0], ureg_src(t->address[2]));
> +         dst[0] = ureg_dst_indirect(dst[0],
> +                                    translate_addr(t, inst->resource.reladdr, 2));
>         assert(dst[0].File != TGSI_FILE_NULL);
>         ureg_memory_insn(ureg, inst->op, dst, num_dst, src, num_src,
>                          inst->buffer_access,
>                          tex_target, inst->image_format);
>         break;
>   
>      default:
>         ureg_insn(ureg,
>                   inst->op,
>                   dst, num_dst,
> @@ -6143,36 +6167,38 @@ st_translate_program(
>      const ubyte inputMapping[],
>      const ubyte inputSlotToAttr[],
>      const ubyte inputSemanticName[],
>      const ubyte inputSemanticIndex[],
>      const ubyte interpMode[],
>      GLuint numOutputs,
>      const ubyte outputMapping[],
>      const ubyte outputSemanticName[],
>      const ubyte outputSemanticIndex[])
>   {
> +   struct pipe_screen *screen = st_context(ctx)->pipe->screen;
>      struct st_translate *t;
>      unsigned i;
>      struct gl_program_constants *frag_const =
>         &ctx->Const.Program[MESA_SHADER_FRAGMENT];
>      enum pipe_error ret = PIPE_OK;
>   
>      assert(numInputs <= ARRAY_SIZE(t->inputs));
>      assert(numOutputs <= ARRAY_SIZE(t->outputs));
>   
>      t = CALLOC_STRUCT(st_translate);
>      if (!t) {
>         ret = PIPE_ERROR_OUT_OF_MEMORY;
>         goto out;
>      }
>   
>      t->procType = procType;
> +   t->need_uarl = !screen->get_param(screen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
>      t->inputMapping = inputMapping;
>      t->outputMapping = outputMapping;
>      t->ureg = ureg;
>      t->num_temp_arrays = program->next_array;
>      if (t->num_temp_arrays)
>         t->arrays = (struct ureg_dst*)
>                     calloc(t->num_temp_arrays, sizeof(t->arrays[0]));
>   
>      /*
>       * Declare input attributes.
> @@ -6584,20 +6610,21 @@ get_mesa_program_tgsi(struct gl_context *ctx,
>      v->options = options;
>      v->glsl_version = ctx->Const.GLSLVersion;
>      v->native_integers = ctx->Const.NativeIntegers;
>   
>      v->have_sqrt = pscreen->get_shader_param(pscreen, ptarget,
>                                               PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED);
>      v->have_fma = pscreen->get_shader_param(pscreen, ptarget,
>                                              PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED);
>      v->has_tex_txf_lz = pscreen->get_param(pscreen,
>                                             PIPE_CAP_TGSI_TEX_TXF_LZ);
> +   v->need_uarl = !pscreen->get_param(pscreen, PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS);
>   
>      v->variables = _mesa_hash_table_create(v->mem_ctx, _mesa_hash_pointer,
>                                             _mesa_key_pointer_equal);
>      skip_merge_registers =
>         pscreen->get_shader_param(pscreen, ptarget,
>                                   PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS);
>   
>      _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader,
>                                                  prog->Parameters);
>   
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
> index b9112e5..d57525d 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi_private.h
> @@ -67,20 +67,28 @@ public:
>       * Is this the second half of a double register pair?
>       * currently used for input mapping only.
>       */
>      unsigned double_reg2:1;
>      unsigned is_double_vertex_input:1;
>      unsigned array_id:10;
>      /** Register index should be offset by the integer in this reg. */
>      st_src_reg *reladdr;
>      st_src_reg *reladdr2;
>   
> +   bool is_legal_tgsi_address_operand() const
> +   {
> +      /* 2D registers can't be used as an address operand, or if the address
> +       * operand itself is a result of indirect addressing.
> +       */
> +      return (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT) &&
> +             !has_index2 && !reladdr && !reladdr2;
> +   }
>   };
>   
>   class st_dst_reg {
>   public:
>      st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type, int index);
>   
>      st_dst_reg(gl_register_file file, int writemask, enum glsl_base_type type);
>   
>      st_dst_reg();
>      st_dst_reg(const st_dst_reg &reg);
> 


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list