From f2040fbe4890224b5f2b0b78318a4f5c7643b3dd Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Thu, 7 Dec 2017 13:57:21 +0100 Subject: [PATCH] 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 Signed-off-by: Gert Wollny --- .../state_tracker/tests/st_tests_common.cpp | 95 ++++++++++++++++++- .../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 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>& _dst, }); } +FakeCodeline::FakeCodeline(unsigned _op, const vector>& _dst, + const vector>& _src, + const vector>&_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& r) { + return create_dst_register(r); + }); + + transform(_src.begin(), _src.end(), std::back_inserter(src), + [this](const tuple& r) { + return create_src_register(r); + }); + + transform(_to.begin(), _to.end(), std::back_inserter(tex_offsets), + [this](const tuple& 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& 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& 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& _dst, const std::vector& _src, const std::vector&_to); @@ -45,6 +48,10 @@ struct FakeCodeline { const std::vector>& _src, const std::vector>&_to, SWZ with_swizzle); + FakeCodeline(unsigned _op, const std::vector>& _dst, + const std::vector>& _src, + const std::vector>&_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& 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& dest); template 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 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 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 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 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 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 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.30.2