mesa/st: Use memset to zero out struct
[mesa.git] / src / mesa / state_tracker / tests / st_tests_common.h
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 {
47 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
65 int get_max_reg_id() const { return max_temp_id;}
66 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