aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2017-12-07 13:57:21 +0100
committerBrian Paul <[email protected]>2018-01-24 10:34:00 -0700
commitf2040fbe4890224b5f2b0b78318a4f5c7643b3dd (patch)
tree7a8782dafd75b0f5e0d8f6eb009a04a9a479db2d /src/mesa/state_tracker
parent51c0cee267206ae9de215b8e4f75c04a2fa251b2 (diff)
mesa/st/tests: Add tests for lifetime tracking with indirect addressing
Add a code line type that accepts one layer of indirect addressing and add tests to check that temporary register access used for indirect addressing is accounted for in the lifetime estimation. Reviewed-by: Brian Paul <[email protected]> Signed-off-by: Gert Wollny <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/tests/st_tests_common.cpp95
-rw-r--r--src/mesa/state_tracker/tests/st_tests_common.h12
-rw-r--r--src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp86
3 files changed, 189 insertions, 4 deletions
diff --git a/src/mesa/state_tracker/tests/st_tests_common.cpp b/src/mesa/state_tracker/tests/st_tests_common.cpp
index 03d664dd4bb..ea01ca5555f 100644
--- a/src/mesa/state_tracker/tests/st_tests_common.cpp
+++ b/src/mesa/state_tracker/tests/st_tests_common.cpp
@@ -84,6 +84,30 @@ FakeCodeline::FakeCodeline(unsigned _op, const vector<pair<int,int>>& _dst,
});
}
+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)
@@ -190,10 +214,43 @@ st_src_reg FakeCodeline::create_src_register(int src_idx, gl_register_file file)
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)
@@ -212,6 +269,12 @@ 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;
@@ -230,6 +293,32 @@ st_dst_reg FakeCodeline::create_dst_register(int dst_idx, gl_register_file file)
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();
diff --git a/src/mesa/state_tracker/tests/st_tests_common.h b/src/mesa/state_tracker/tests/st_tests_common.h
index cea8a5ce08e..2e188329231 100644
--- a/src/mesa/state_tracker/tests/st_tests_common.h
+++ b/src/mesa/state_tracker/tests/st_tests_common.h
@@ -35,9 +35,12 @@
/* 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);
@@ -45,6 +48,10 @@ struct FakeCodeline {
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;}
@@ -60,10 +67,13 @@ private:
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);
diff --git a/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp b/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp
index a1dc28a3875..a3b0f0e02f9 100644
--- a/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp
+++ b/src/mesa/state_tracker/tests/test_glsl_to_tgsi_lifetime.cpp
@@ -1568,6 +1568,92 @@ TEST_F(LifetimeEvaluatorExactTest, NestedLoopWithWriteAfterBreak)
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.