On 29.09.2017 14:25, Marek Olšák wrote:
From: Marek Olšák <[email protected]>

---
  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 <[email protected]>


+   }
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.
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to