• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2017 Gert Wollny
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef mesa_st_tests_h
25 #define mesa_st_tests_h
26 
27 #include "state_tracker/st_glsl_to_tgsi_temprename.h"
28 #include "state_tracker/st_glsl_to_tgsi_array_merge.h"
29 #include "gtest/gtest.h"
30 
31 #include <utility>
32 
33 #define MP(X, W) std::make_pair(X, W)
34 #define MT(X,Y,Z) std::make_tuple(X,Y,Z)
35 
36 /* Use this to make the compiler pick the swizzle constructor below */
37 struct SWZ {};
38 
39 /* Use this to make the compiler pick the constructor with reladdr below */
40 struct RA {};
41 
42 /* Use this to make the compiler pick the constructor with array below */
43 struct ARR {};
44 
45 /* A line to describe a TGSI instruction for building mock shaders. */
46 struct FakeCodeline {
FakeCodelineFakeCodeline47    FakeCodeline(tgsi_opcode _op): op(_op), max_temp_id(0), max_array_id(0) {}
48    FakeCodeline(tgsi_opcode _op, const std::vector<int>& _dst, const std::vector<int>& _src,
49                 const std::vector<int>&_to);
50 
51    FakeCodeline(tgsi_opcode _op, const std::vector<std::pair<int,int>>& _dst,
52                 const std::vector<std::pair<int, const char *>>& _src,
53                 const std::vector<std::pair<int, const char *>>&_to, SWZ with_swizzle);
54 
55    FakeCodeline(tgsi_opcode _op, const std::vector<std::tuple<int,int,int>>& _dst,
56                 const std::vector<std::tuple<int,int,int>>& _src,
57                 const std::vector<std::tuple<int,int,int>>&_to, RA with_reladdr);
58 
59    FakeCodeline(tgsi_opcode _op, const std::vector<std::tuple<int, int, int> > &_dst,
60 		const std::vector<std::tuple<int,int, const char*>>& _src,
61 		const std::vector<std::tuple<int,int, const char*>>&_to, ARR with_array);
62 
63    FakeCodeline(const glsl_to_tgsi_instruction& inst);
64 
get_max_reg_idFakeCodeline65    int get_max_reg_id() const { return max_temp_id;}
get_max_array_idFakeCodeline66    int get_max_array_id() const { return max_array_id;}
67 
68    glsl_to_tgsi_instruction *get_codeline() const;
69 
70    static void set_mem_ctx(void *ctx);
71 
72    friend bool operator == (const FakeCodeline& lsh, const FakeCodeline& rhs);
73 
74    void print(std::ostream& os) const;
75 private:
76    st_src_reg create_src_register(int src_idx);
77    st_src_reg create_src_register(int src_idx, const char *swizzle);
78    st_src_reg create_src_register(int src_idx, gl_register_file file);
79    st_src_reg create_src_register(const std::tuple<int,int,int>& src);
80    st_src_reg *create_rel_src_register(int idx);
81    st_src_reg create_array_src_register(const std::tuple<int,int,const char*>& r);
82    st_dst_reg create_array_dst_register(const std::tuple<int,int,int>& r);
83 
84    st_dst_reg create_dst_register(int dst_idx);
85    st_dst_reg create_dst_register(int dst_idx, int writemask);
86    st_dst_reg create_dst_register(int dst_idx, gl_register_file file);
87    st_dst_reg create_dst_register(const std::tuple<int,int,int>& dest);
88 
89    template <typename st_reg>
90    void read_reg(const st_reg& s);
91 
92    tgsi_opcode op;
93    std::vector<st_dst_reg> dst;
94    std::vector<st_src_reg> src;
95    std::vector<st_src_reg> tex_offsets;
96 
97    int max_temp_id;
98    int max_array_id;
99    static void *mem_ctx;
100 };
101 
102 inline std::ostream& operator << (std::ostream& os, const FakeCodeline& line)
103 {
104    line.print(os);
105    return os;
106 }
107 
108 /* A few constants that will not be tracked as temporary registers
109    by the fake shader.
110  */
111 const int in0 = -1;
112 const int in1 = -2;
113 const int in2 = -3;
114 
115 const int out0 = -1;
116 const int out1 = -2;
117 const int out2 = -3;
118 
119 class FakeShader {
120 public:
121    FakeShader(const std::vector<FakeCodeline>& source);
122    FakeShader(exec_list *tgsi_prog);
123 
124    exec_list* get_program(void *ctx) const;
125    int get_num_temps() const;
126    int get_num_arrays() const;
127 
128    size_t length() const;
129 
130    const FakeCodeline& line(unsigned i) const;
131 
132 private:
133 
134    std::vector<FakeCodeline> program;
135    int num_temps;
136    int num_arrays;
137 };
138 
139 using temp_lt_expect = std::vector<std::vector<int>>;
140 using array_lt_expect = std::vector<array_live_range>;
141 
142 class MesaTestWithMemCtx : public testing::Test {
143    void SetUp();
144    void TearDown();
145 protected:
146    void *mem_ctx;
147 };
148 
149 class LifetimeEvaluatorTest : public MesaTestWithMemCtx {
150 protected:
151    void run(const std::vector<FakeCodeline>& code, const temp_lt_expect& e);
152    void run(const std::vector<FakeCodeline>& code, const array_lt_expect& e);
153 private:
154    using life_range_result=std::pair<std::vector<register_live_range>,
155 				   std::vector<array_live_range>>;
156    life_range_result run(const std::vector<FakeCodeline>& code, bool& success);
157 
158    virtual void check(const std::vector<register_live_range>& result,
159 		      const temp_lt_expect& e) = 0;
160    virtual void check(const std::vector<array_live_range>& lifetimes,
161 		      const array_lt_expect& e) = 0;
162 };
163 
164 /* This is a test class to check the exact life times of
165  * registers. */
166 class LifetimeEvaluatorExactTest : public LifetimeEvaluatorTest {
167 protected:
168    void check(const std::vector<register_live_range>& result,
169 	      const temp_lt_expect& e);
170 
171    void check(const std::vector<array_live_range>& result,
172 	      const array_lt_expect& e);
173 };
174 
175 /* This test class checks that the life time covers at least
176  * in the expected range. It is used for cases where we know that
177  * a the implementation could be improved on estimating the minimal
178  * life time.
179  */
180 class LifetimeEvaluatorAtLeastTest : public LifetimeEvaluatorTest {
181 protected:
182    void check(const std::vector<register_live_range>& result, const temp_lt_expect& e);
183    void check(const std::vector<array_live_range>& result,
184 	      const array_lt_expect& e);
185 };
186 
187 /* With this test class the renaming mapping estimation is tested */
188 class RegisterRemappingTest : public MesaTestWithMemCtx {
189 protected:
190    void run(const std::vector<register_live_range>& lt,
191 	    const std::vector<int> &expect);
192 };
193 
194 /* With this test class the combined lifetime estimation and renaming
195  * mepping estimation is tested
196  */
197 class RegisterLifetimeAndRemappingTest : public RegisterRemappingTest  {
198 protected:
199    using RegisterRemappingTest::run;
200    void run(const std::vector<FakeCodeline>& code, const std::vector<int> &expect);
201 };
202 
203 #endif
204