[Mesa-dev] [PATCH v4 09/10] mesa/st/tests: Add tests for lifetime tracking with indirect addressing

Gert Wollny gw.fossdev at gmail.com
Tue Dec 12 13:40:59 UTC 2017


 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.

Signed-off-by: Gert Wollny <gw.fossdev at gmail.com>
---
 src/mesa/state_tracker/tests/st_tests_common.cpp   | 95 +++++++++++++++++++++-
 src/mesa/state_tracker/tests/st_tests_common.h     | 12 ++-
 .../tests/test_glsl_to_tgsi_lifetime.cpp           | 86 ++++++++++++++++++++
 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 91fd39343f..c6563472a8 100644
--- a/src/mesa/state_tracker/tests/st_tests_common.cpp
+++ b/src/mesa/state_tracker/tests/st_tests_common.cpp
@@ -87,6 +87,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)
@@ -193,10 +217,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)
@@ -215,6 +272,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;
@@ -233,6 +296,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 cea8a5ce08..2e18832923 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 a1dc28a387..a3b0f0e02f 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.
-- 
2.13.6



More information about the mesa-dev mailing list