});
}
+FakeCodeline::FakeCodeline(unsigned _op, const vector<tuple<int,int,int>>& _dst,
+ const vector<tuple<int,int,int>>& _src,
+ const vector<tuple<int,int,int>>&_to, RA with_reladdr):
+ op(_op),
+ max_temp_id(0)
+{
+ (void)with_reladdr;
+
+ transform(_dst.begin(), _dst.end(), std::back_inserter(dst),
+ [this](const tuple<int,int,int>& r) {
+ return create_dst_register(r);
+ });
+
+ transform(_src.begin(), _src.end(), std::back_inserter(src),
+ [this](const tuple<int,int,int>& r) {
+ return create_src_register(r);
+ });
+
+ transform(_to.begin(), _to.end(), std::back_inserter(tex_offsets),
+ [this](const tuple<int,int,int>& r) {
+ return create_src_register(r);
+ });
+}
+
FakeCodeline::FakeCodeline(const glsl_to_tgsi_instruction& instr):
op(instr.op),
max_temp_id(0)
return retval;
}
-st_dst_reg FakeCodeline::create_dst_register(int dst_idx)
+st_src_reg *FakeCodeline::create_rel_src_register(int idx)
{
- return create_dst_register(dst_idx, dst_idx < 0 ?
- PROGRAM_OUTPUT : PROGRAM_TEMPORARY);
+ st_src_reg *retval = ralloc(mem_ctx, st_src_reg);
+ *retval = st_src_reg(PROGRAM_TEMPORARY, idx, GLSL_TYPE_INT);
+ if (max_temp_id < idx)
+ max_temp_id = idx;
+ return retval;
+}
+
+st_src_reg FakeCodeline::create_src_register(const tuple<int,int,int>& src)
+{
+ int src_idx = std::get<0>(src);
+ int relidx1 = std::get<1>(src);
+ int relidx2 = std::get<2>(src);
+
+ gl_register_file file = PROGRAM_TEMPORARY;
+ if (src_idx < 0)
+ file = PROGRAM_OUTPUT;
+ else if (relidx1 || relidx2) {
+ file = PROGRAM_ARRAY;
+ }
+
+ st_src_reg retval = create_src_register(src_idx, file);
+ if (src_idx >= 0) {
+ if (relidx1 || relidx2) {
+ retval.array_id = 1;
+
+ if (relidx1)
+ retval.reladdr = create_rel_src_register(relidx1);
+ if (relidx2) {
+ retval.reladdr2 = create_rel_src_register(relidx2);
+ retval.has_index2 = true;
+ retval.index2D = 10;
+ }
+ }
+ }
+ return retval;
}
st_dst_reg FakeCodeline::create_dst_register(int dst_idx,int writemask)
return st_dst_reg(file, writemask, GLSL_TYPE_INT, idx);
}
+st_dst_reg FakeCodeline::create_dst_register(int dst_idx)
+{
+ return create_dst_register(dst_idx, dst_idx < 0 ?
+ PROGRAM_OUTPUT : PROGRAM_TEMPORARY);
+}
+
st_dst_reg FakeCodeline::create_dst_register(int dst_idx, gl_register_file file)
{
st_dst_reg retval;
return retval;
}
+st_dst_reg FakeCodeline::create_dst_register(const tuple<int,int,int>& dst)
+{
+ int dst_idx = std::get<0>(dst);
+ int relidx1 = std::get<1>(dst);
+ int relidx2 = std::get<2>(dst);
+
+ gl_register_file file = PROGRAM_TEMPORARY;
+ if (dst_idx < 0)
+ file = PROGRAM_OUTPUT;
+ else if (relidx1 || relidx2) {
+ file = PROGRAM_ARRAY;
+ }
+ st_dst_reg retval = create_dst_register(dst_idx, file);
+
+ if (relidx1 || relidx2) {
+ if (relidx1)
+ retval.reladdr = create_rel_src_register(relidx1);
+ if (relidx2) {
+ retval.reladdr2 = create_rel_src_register(relidx2);
+ retval.has_index2 = true;
+ retval.index2D = 10;
+ }
+ }
+ return retval;
+}
+
glsl_to_tgsi_instruction *FakeCodeline::get_codeline() const
{
glsl_to_tgsi_instruction *next_instr = new(mem_ctx) glsl_to_tgsi_instruction();
/* Use this to make the compiler pick the swizzle constructor below */
struct SWZ {};
+/* Use this to make the compiler pick the constructor with reladdr below */
+struct RA {};
+
/* A line to describe a TGSI instruction for building mock shaders. */
struct FakeCodeline {
- FakeCodeline(unsigned _op): op(_op), max_temp_id(0){}
+ FakeCodeline(unsigned _op): op(_op), max_temp_id(0) {}
FakeCodeline(unsigned _op, const std::vector<int>& _dst, const std::vector<int>& _src,
const std::vector<int>&_to);
const std::vector<std::pair<int, const char *>>& _src,
const std::vector<std::pair<int, const char *>>&_to, SWZ with_swizzle);
+ FakeCodeline(unsigned _op, const std::vector<std::tuple<int,int,int>>& _dst,
+ const std::vector<std::tuple<int,int,int>>& _src,
+ const std::vector<std::tuple<int,int,int>>&_to, RA with_reladdr);
+
FakeCodeline(const glsl_to_tgsi_instruction& inst);
int get_max_reg_id() const { return max_temp_id;}
st_src_reg create_src_register(int src_idx);
st_src_reg create_src_register(int src_idx, const char *swizzle);
st_src_reg create_src_register(int src_idx, gl_register_file file);
+ st_src_reg create_src_register(const std::tuple<int,int,int>& src);
+ st_src_reg *create_rel_src_register(int idx);
st_dst_reg create_dst_register(int dst_idx);
st_dst_reg create_dst_register(int dst_idx, int writemask);
st_dst_reg create_dst_register(int dst_idx, gl_register_file file);
+ st_dst_reg create_dst_register(const std::tuple<int,int,int>& dest);
template <typename st_reg>
void read_reg(const st_reg& s);
run (code, temp_lt_expect({{-1,-1}, {0,8}}));
}
+
+#define MT(X,Y,Z) std::make_tuple(X,Y,Z)
+/* Check lifetime estimation with a relative addressing in src.
+ * Note, since the lifetime estimation always extends the lifetime
+ * at to at least one instruction after the last write, for the
+ * test the last read must be at least two instructions after the
+ * last write to obtain a proper test.
+ */
+
+TEST_F(LifetimeEvaluatorExactTest, ReadIndirectReladdr1)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV, {1}, {in1}, {}},
+ { TGSI_OPCODE_MOV, {2}, {in0}, {}},
+ { TGSI_OPCODE_MOV, {MT(3,0,0)}, {MT(2,1,0)}, {}, RA()},
+ { TGSI_OPCODE_MOV, {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}, {1,2}, {2,3}}));
+}
+
+/* Check lifetime estimation with a relative addressing in src */
+TEST_F(LifetimeEvaluatorExactTest, ReadIndirectReladdr2)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in1}, {}},
+ { TGSI_OPCODE_MOV , {2}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {MT(3,0,0)}, {MT(4,0,1)}, {}, RA()},
+ { TGSI_OPCODE_MOV , {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}, {1,2},{2,3}}));
+}
+
+/* Check lifetime estimation with a relative addressing in src */
+TEST_F(LifetimeEvaluatorExactTest, ReadIndirectTexOffsReladdr1)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in1}, {}},
+ { TGSI_OPCODE_MOV , {2}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {MT(3,0,0)}, {MT(in2,0,0)}, {MT(5,1,0)}, RA()},
+ { TGSI_OPCODE_MOV , {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}, {1,2}, {2,3}}));
+}
+
+/* Check lifetime estimation with a relative addressing in src */
+TEST_F(LifetimeEvaluatorExactTest, ReadIndirectTexOffsReladdr2)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in1}, {}},
+ { TGSI_OPCODE_MOV , {2}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {MT(3,0,0)}, {MT(in2,0,0)}, {MT(2,0,1)}, RA()},
+ { TGSI_OPCODE_MOV , {out0}, {3}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}, {1,2}, {2,3}}));
+}
+
+/* Check lifetime estimation with a relative addressing in dst */
+TEST_F(LifetimeEvaluatorExactTest, WriteIndirectReladdr1)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {1}, {in1}, {}},
+ { TGSI_OPCODE_MOV , {MT(5,1,0)}, {MT(in1,0,0)}, {}, RA()},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}}));
+}
+
+/* Check lifetime estimation with a relative addressing in dst */
+TEST_F(LifetimeEvaluatorExactTest, WriteIndirectReladdr2)
+{
+ const vector<FakeCodeline> code = {
+ { TGSI_OPCODE_MOV , {1}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {2}, {in1}, {}},
+ { TGSI_OPCODE_MOV , {MT(5,0,1)}, {MT(in1,0,0)}, {}, RA()},
+ { TGSI_OPCODE_MOV , {out0}, {in0}, {}},
+ { TGSI_OPCODE_MOV , {out1}, {2}, {}},
+ { TGSI_OPCODE_END}
+ };
+ run (code, temp_lt_expect({{-1,-1}, {0,2}, {1,4}}));
+}
+
/* Test remapping table of registers. The tests don't assume
* that the sorting algorithm used to sort the lifetimes
* based on their 'begin' is stable.