[Mesa-dev] [RFC 3/9] st/glsl_to_tgsi: handle precise modifier

Karol Herbst karolherbst at gmail.com
Sun Jun 11 18:42:33 UTC 2017


all subexpression inside an ir_assignment needs to be tagged as precise.

Signed-off-by: Karol Herbst <karolherbst at gmail.com>
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 80 ++++++++++++++++++++++++------
 1 file changed, 65 insertions(+), 15 deletions(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index c5d2e0fcd2..19f90f21fe 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -87,6 +87,13 @@ static int swizzle_for_type(const glsl_type *type, int component = 0)
    return swizzle;
 }
 
+static unsigned is_precise(const ir_variable *ir)
+{
+   if (!ir)
+      return 0;
+   return ir->data.precise || ir->data.invariant;
+}
+
 /**
  * This struct is a corresponding struct to TGSI ureg_src.
  */
@@ -296,6 +303,7 @@ public:
    ir_instruction *ir;
 
    unsigned op:8; /**< TGSI opcode */
+   unsigned precise:1;
    unsigned saturate:1;
    unsigned is_64bit_expanded:1;
    unsigned sampler_base:5;
@@ -435,6 +443,7 @@ public:
    bool have_fma;
    bool use_shared_memory;
    bool has_tex_txf_lz;
+   unsigned precise;
 
    variable_storage *find_variable_storage(ir_variable *var);
 
@@ -505,13 +514,29 @@ public:
                                       st_src_reg src0 = undef_src,
                                       st_src_reg src1 = undef_src,
                                       st_src_reg src2 = undef_src,
-                                      st_src_reg src3 = undef_src);
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
 
    glsl_to_tgsi_instruction *emit_asm(ir_instruction *ir, unsigned op,
                                       st_dst_reg dst, st_dst_reg dst1,
                                       st_src_reg src0 = undef_src,
                                       st_src_reg src1 = undef_src,
                                       st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src,
+                                      unsigned precise = 0);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst = undef_dst,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
+                                      st_src_reg src3 = undef_src);
+
+   glsl_to_tgsi_instruction *emit_asm(ir_expression *ir, unsigned op,
+                                      st_dst_reg dst, st_dst_reg dst1,
+                                      st_src_reg src0 = undef_src,
+                                      st_src_reg src1 = undef_src,
+                                      st_src_reg src2 = undef_src,
                                       st_src_reg src3 = undef_src);
 
    unsigned get_opcode(unsigned op,
@@ -650,7 +675,8 @@ glsl_to_tgsi_instruction *
 glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                st_dst_reg dst, st_dst_reg dst1,
                                st_src_reg src0, st_src_reg src1,
-                               st_src_reg src2, st_src_reg src3)
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
 {
    glsl_to_tgsi_instruction *inst = new(mem_ctx) glsl_to_tgsi_instruction();
    int num_reladdr = 0, i, j;
@@ -691,6 +717,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
    STATIC_ASSERT(TGSI_OPCODE_LAST <= 255);
 
    inst->op = op;
+   inst->precise = precise;
    inst->info = tgsi_get_opcode_info(op);
    inst->dst[0] = dst;
    inst->dst[1] = dst1;
@@ -881,9 +908,28 @@ glsl_to_tgsi_instruction *
 glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
                                st_dst_reg dst,
                                st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3,
+                               unsigned precise)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst,
+                               st_src_reg src0, st_src_reg src1,
+                               st_src_reg src2, st_src_reg src3)
+{
+   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3, this->precise);
+}
+
+glsl_to_tgsi_instruction *
+glsl_to_tgsi_visitor::emit_asm(ir_expression *ir, unsigned op,
+                               st_dst_reg dst, st_dst_reg dst1,
+                               st_src_reg src0, st_src_reg src1,
                                st_src_reg src2, st_src_reg src3)
 {
-   return emit_asm(ir, op, dst, undef_dst, src0, src1, src2, src3);
+   return emit_asm(ir, op, dst, dst1, src0, src1, src2, src3, this->precise);
 }
 
 /**
@@ -1116,7 +1162,7 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
    if (dst.index >= this->num_address_regs)
       this->num_address_regs = dst.index + 1;
 
-   emit_asm(NULL, op, dst, src0);
+   emit_asm((ir_instruction *)NULL, op, dst, src0);
 }
 
 int
@@ -1406,11 +1452,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
 void
 glsl_to_tgsi_visitor::visit(ir_loop *ir)
 {
-   emit_asm(NULL, TGSI_OPCODE_BGNLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BGNLOOP);
 
    visit_exec_list(&ir->body_instructions, this);
 
-   emit_asm(NULL, TGSI_OPCODE_ENDLOOP);
+   emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ENDLOOP);
 }
 
 void
@@ -1418,10 +1464,10 @@ glsl_to_tgsi_visitor::visit(ir_loop_jump *ir)
 {
    switch (ir->mode) {
    case ir_loop_jump::jump_break:
-      emit_asm(NULL, TGSI_OPCODE_BRK);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_BRK);
       break;
    case ir_loop_jump::jump_continue:
-      emit_asm(NULL, TGSI_OPCODE_CONT);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_CONT);
       break;
    }
 }
@@ -2703,7 +2749,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
             st_dst_reg dst = st_dst_reg(get_temp(var->type));
             st_src_reg src = st_src_reg(PROGRAM_OUTPUT, decl->mesa_index,
                                         var->type, component, decl->array_id);
-            emit_asm(NULL, TGSI_OPCODE_FBFETCH, dst, src);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_FBFETCH, dst, src);
             entry = new(mem_ctx) variable_storage(var, dst.file, dst.index,
                                                   dst.array_id);
          } else {
@@ -3148,7 +3194,10 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
    st_dst_reg l;
    st_src_reg r;
 
+   /* all generated instructions need to be flaged as precise */
+   this->precise = is_precise(ir->lhs->variable_referenced());
    ir->rhs->accept(this);
+   this->precise = 0;
    r = this->result;
 
    l = get_assignment_lhs(ir->lhs, this, &dst_component);
@@ -3233,7 +3282,8 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
        */
       glsl_to_tgsi_instruction *inst, *new_inst;
       inst = (glsl_to_tgsi_instruction *)this->instructions.get_tail();
-      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3]);
+      new_inst = emit_asm(ir, inst->op, l, inst->src[0], inst->src[1], inst->src[2], inst->src[3],
+                          is_precise(ir->lhs->variable_referenced()));
       new_inst->saturate = inst->saturate;
       inst->dead_mask = inst->dst[0].writemask;
    } else {
@@ -4072,16 +4122,16 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
 
          deref_arr->array_index->accept(this);
          if (*array_elements != 1)
-            emit_asm(NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MUL, temp_dst, this->result, st_src_reg_for_int(*array_elements));
          else
-            emit_asm(NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, temp_dst, this->result);
 
          if (indirect->file == PROGRAM_UNDEFINED)
             *indirect = temp_reg;
          else {
             temp_dst = st_dst_reg(*indirect);
             temp_dst.writemask = 1;
-            emit_asm(NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
+            emit_asm((ir_instruction *)NULL, TGSI_OPCODE_ADD, temp_dst, *indirect, temp_reg);
          }
       } else
          *index += array_index->value.u[0] * *array_elements;
@@ -4141,7 +4191,7 @@ glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
       st_src_reg tmp = get_temp(glsl_type::ivec2_type);
       st_dst_reg tmp_dst = st_dst_reg(tmp);
       tmp_dst.writemask = WRITEMASK_XY;
-      emit_asm(NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
+      emit_asm((ir_instruction *)NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
       return tmp;
    }
 
@@ -6777,7 +6827,7 @@ get_mesa_program_tgsi(struct gl_context *ctx,
    v->renumber_registers();
 
    /* Write the END instruction. */
-   v->emit_asm(NULL, TGSI_OPCODE_END);
+   v->emit_asm((ir_instruction *)NULL, TGSI_OPCODE_END);
 
    if (ctx->_Shader->Flags & GLSL_DUMP) {
       _mesa_log("\n");
-- 
2.13.1



More information about the mesa-dev mailing list