[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