Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
/*
2
 * Copyright © 2012 Intel Corporation
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 DEALINGS
21
 * IN THE SOFTWARE.
22
 */
23
 
24
#include 
25
#include "brw_vec4.h"
26
 
27
using namespace brw;
28
 
29
int ret = 0;
30
 
31
#define register_coalesce(v) _register_coalesce(v, __FUNCTION__)
32
 
33
class register_coalesce_test : public ::testing::Test {
34
   virtual void SetUp();
35
 
36
public:
37
   struct brw_context *brw;
38
   struct gl_context *ctx;
39
   struct gl_shader_program *shader_prog;
40
   struct brw_vertex_program *vp;
41
   vec4_visitor *v;
42
};
43
 
44
 
45
class register_coalesce_vec4_visitor : public vec4_visitor
46
{
47
public:
48
   register_coalesce_vec4_visitor(struct brw_context *brw,
49
                                  struct gl_shader_program *shader_prog)
50
      : vec4_visitor(brw, NULL, NULL, NULL, NULL, shader_prog, NULL, NULL,
51
                     false)
52
   {
53
   }
54
 
55
protected:
56
   virtual dst_reg *make_reg_for_system_value(ir_variable *ir)
57
   {
58
      assert(!"Not reached");
59
      return NULL;
60
   }
61
 
62
   virtual int setup_attributes(int payload_reg)
63
   {
64
      assert(!"Not reached");
65
      return 0;
66
   }
67
 
68
   virtual void emit_prolog()
69
   {
70
      assert(!"Not reached");
71
   }
72
 
73
   virtual void emit_program_code()
74
   {
75
      assert(!"Not reached");
76
   }
77
 
78
   virtual void emit_thread_end()
79
   {
80
      assert(!"Not reached");
81
   }
82
 
83
   virtual void emit_urb_write_header(int mrf)
84
   {
85
      assert(!"Not reached");
86
   }
87
 
88
   virtual vec4_instruction *emit_urb_write_opcode(bool complete)
89
   {
90
      assert(!"Not reached");
91
   }
92
};
93
 
94
 
95
void register_coalesce_test::SetUp()
96
{
97
   brw = (struct brw_context *)calloc(1, sizeof(*brw));
98
   ctx = &brw->ctx;
99
 
100
   vp = ralloc(NULL, struct brw_vertex_program);
101
 
102
   shader_prog = ralloc(NULL, struct gl_shader_program);
103
 
104
   v = new register_coalesce_vec4_visitor(brw, shader_prog);
105
 
106
   _mesa_init_vertex_program(ctx, &vp->program, GL_VERTEX_SHADER, 0);
107
 
108
   brw->gen = 4;
109
}
110
 
111
static void
112
_register_coalesce(vec4_visitor *v, const char *func)
113
{
114
   bool print = false;
115
 
116
   if (print) {
117
      printf("%s: instructions before:\n", func);
118
      v->dump_instructions();
119
   }
120
 
121
   v->opt_register_coalesce();
122
 
123
   if (print) {
124
      printf("%s: instructions after:\n", func);
125
      v->dump_instructions();
126
   }
127
}
128
 
129
TEST_F(register_coalesce_test, test_compute_to_mrf)
130
{
131
   src_reg something = src_reg(v, glsl_type::float_type);
132
   dst_reg temp = dst_reg(v, glsl_type::float_type);
133
   dst_reg init;
134
 
135
   dst_reg m0 = dst_reg(MRF, 0);
136
   m0.writemask = WRITEMASK_X;
137
   m0.type = BRW_REGISTER_TYPE_F;
138
 
139
   vec4_instruction *mul = v->emit(v->MUL(temp, something, src_reg(1.0f)));
140
   v->emit(v->MOV(m0, src_reg(temp)));
141
 
142
   register_coalesce(v);
143
 
144
   EXPECT_EQ(mul->dst.file, MRF);
145
}
146
 
147
 
148
TEST_F(register_coalesce_test, test_multiple_use)
149
{
150
   src_reg something = src_reg(v, glsl_type::float_type);
151
   dst_reg temp = dst_reg(v, glsl_type::vec4_type);
152
   dst_reg init;
153
 
154
   dst_reg m0 = dst_reg(MRF, 0);
155
   m0.writemask = WRITEMASK_X;
156
   m0.type = BRW_REGISTER_TYPE_F;
157
 
158
   dst_reg m1 = dst_reg(MRF, 1);
159
   m1.writemask = WRITEMASK_XYZW;
160
   m1.type = BRW_REGISTER_TYPE_F;
161
 
162
   src_reg src = src_reg(temp);
163
   vec4_instruction *mul = v->emit(v->MUL(temp, something, src_reg(1.0f)));
164
   src.swizzle = BRW_SWIZZLE_XXXX;
165
   v->emit(v->MOV(m0, src));
166
   src.swizzle = BRW_SWIZZLE_XYZW;
167
   v->emit(v->MOV(m1, src));
168
 
169
   register_coalesce(v);
170
 
171
   EXPECT_NE(mul->dst.file, MRF);
172
}
173
 
174
TEST_F(register_coalesce_test, test_dp4_mrf)
175
{
176
   src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
177
   src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
178
   dst_reg init;
179
 
180
   dst_reg m0 = dst_reg(MRF, 0);
181
   m0.writemask = WRITEMASK_Y;
182
   m0.type = BRW_REGISTER_TYPE_F;
183
 
184
   dst_reg temp = dst_reg(v, glsl_type::float_type);
185
 
186
   vec4_instruction *dp4 = v->emit(v->DP4(temp, some_src_1, some_src_2));
187
   v->emit(v->MOV(m0, src_reg(temp)));
188
 
189
   register_coalesce(v);
190
 
191
   EXPECT_EQ(dp4->dst.file, MRF);
192
   EXPECT_EQ(dp4->dst.writemask, WRITEMASK_Y);
193
}
194
 
195
TEST_F(register_coalesce_test, test_dp4_grf)
196
{
197
   src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
198
   src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
199
   dst_reg init;
200
 
201
   dst_reg to = dst_reg(v, glsl_type::vec4_type);
202
   dst_reg temp = dst_reg(v, glsl_type::float_type);
203
 
204
   vec4_instruction *dp4 = v->emit(v->DP4(temp, some_src_1, some_src_2));
205
   to.writemask = WRITEMASK_Y;
206
   v->emit(v->MOV(to, src_reg(temp)));
207
 
208
   /* if we don't do something with the result, the automatic dead code
209
    * elimination will remove all our instructions.
210
    */
211
   src_reg src = src_reg(to);
212
   src.negate = true;
213
   v->emit(v->MOV(dst_reg(MRF, 0), src));
214
 
215
   register_coalesce(v);
216
 
217
   EXPECT_EQ(dp4->dst.reg, to.reg);
218
   EXPECT_EQ(dp4->dst.writemask, WRITEMASK_Y);
219
}
220
 
221
TEST_F(register_coalesce_test, test_channel_mul_grf)
222
{
223
   src_reg some_src_1 = src_reg(v, glsl_type::vec4_type);
224
   src_reg some_src_2 = src_reg(v, glsl_type::vec4_type);
225
   dst_reg init;
226
 
227
   dst_reg to = dst_reg(v, glsl_type::vec4_type);
228
   dst_reg temp = dst_reg(v, glsl_type::float_type);
229
 
230
   vec4_instruction *mul = v->emit(v->MUL(temp, some_src_1, some_src_2));
231
   to.writemask = WRITEMASK_Y;
232
   v->emit(v->MOV(to, src_reg(temp)));
233
 
234
   /* if we don't do something with the result, the automatic dead code
235
    * elimination will remove all our instructions.
236
    */
237
   src_reg src = src_reg(to);
238
   src.negate = true;
239
   v->emit(v->MOV(dst_reg(MRF, 0), src));
240
 
241
   register_coalesce(v);
242
 
243
   /* This path isn't supported yet in the reswizzling code, so we're checking
244
    * that we haven't done anything bad to scalar non-DP[234]s.
245
    */
246
   EXPECT_NE(mul->dst.reg, to.reg);
247
}