2 * Copyright © 2013 Intel Corporation
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:
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
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.
23 #include <gtest/gtest.h>
24 #include "main/compiler.h"
25 #include "main/mtypes.h"
26 #include "main/macros.h"
28 #include "ir_builder.h"
30 using namespace ir_builder
;
32 namespace lower_64bit
{
33 void expand_source(ir_factory
&body
,
35 ir_variable
**expanded_src
);
37 ir_dereference_variable
*compact_destination(ir_factory
&body
,
38 const glsl_type
*type
,
39 ir_variable
*result
[4]);
41 ir_rvalue
*lower_op_to_function_call(ir_instruction
*base_ir
,
43 ir_function_signature
*callee
);
46 class expand_source
: public ::testing::Test
{
49 virtual void TearDown();
51 exec_list instructions
;
53 ir_variable
*expanded_src
[4];
58 expand_source::SetUp()
60 mem_ctx
= ralloc_context(NULL
);
62 memset(expanded_src
, 0, sizeof(expanded_src
));
63 instructions
.make_empty();
64 body
= new ir_factory(&instructions
, mem_ctx
);
68 expand_source::TearDown()
77 static ir_dereference_variable
*
78 create_variable(void *mem_ctx
, const glsl_type
*type
)
80 ir_variable
*var
= new(mem_ctx
) ir_variable(type
,
84 return new(mem_ctx
) ir_dereference_variable(var
);
87 static ir_expression
*
88 create_expression(void *mem_ctx
, const glsl_type
*type
)
90 return new(mem_ctx
) ir_expression(ir_unop_neg
,
91 create_variable(mem_ctx
, type
));
95 check_expanded_source(const glsl_type
*type
,
96 ir_variable
*expanded_src
[4])
98 const glsl_type
*const expanded_type
=
99 type
->base_type
== GLSL_TYPE_UINT64
100 ? glsl_type::uvec2_type
:glsl_type::ivec2_type
;
102 for (int i
= 0; i
< type
->vector_elements
; i
++) {
103 EXPECT_EQ(expanded_type
, expanded_src
[i
]->type
);
105 /* All elements that are part of the vector must be unique. */
106 for (int j
= i
- 1; j
>= 0; j
--) {
107 EXPECT_NE(expanded_src
[i
], expanded_src
[j
])
108 << " Element " << i
<< " is the same as element " << j
;
112 /* All elements that are not part of the vector must be the same as element
113 * 0. This is primarily for scalars (where every element is the same).
115 for (int i
= type
->vector_elements
; i
< 4; i
++) {
116 EXPECT_EQ(expanded_src
[0], expanded_src
[i
])
117 << " Element " << i
<< " should be the same as element 0";
122 check_instructions(exec_list
*instructions
,
123 const glsl_type
*type
,
124 const ir_instruction
*source
)
126 const glsl_type
*const expanded_type
=
127 type
->base_type
== GLSL_TYPE_UINT64
128 ? glsl_type::uvec2_type
: glsl_type::ivec2_type
;
130 const ir_expression_operation unpack_opcode
=
131 type
->base_type
== GLSL_TYPE_UINT64
132 ? ir_unop_unpack_uint_2x32
: ir_unop_unpack_int_2x32
;
136 /* The instruction list should contain IR to represent:
141 * tmp2 = unpackUint2x32(tmp1.x);
143 * tmp3 = unpackUint2x32(tmp1.y);
145 * tmp4 = unpackUint2x32(tmp1.z);
147 * tmp5 = unpackUint2x32(tmp1.w);
149 ASSERT_FALSE(instructions
->is_empty());
150 ir
= (ir_instruction
*) instructions
->pop_head();
151 ir_variable
*const tmp1
= ir
->as_variable();
152 EXPECT_EQ(ir_type_variable
, ir
->ir_type
);
153 EXPECT_EQ(type
, tmp1
->type
) <<
159 ASSERT_FALSE(instructions
->is_empty());
160 ir
= (ir_instruction
*) instructions
->pop_head();
161 ir_assignment
*const assign1
= ir
->as_assignment();
162 EXPECT_EQ(ir_type_assignment
, ir
->ir_type
);
163 ASSERT_NE((void *)0, assign1
);
164 EXPECT_EQ(tmp1
, assign1
->lhs
->variable_referenced());
165 EXPECT_EQ(source
, assign1
->rhs
);
167 for (unsigned i
= 0; i
< type
->vector_elements
; i
++) {
168 ASSERT_FALSE(instructions
->is_empty());
169 ir
= (ir_instruction
*) instructions
->pop_head();
170 ir_variable
*const tmp2
= ir
->as_variable();
171 EXPECT_EQ(ir_type_variable
, ir
->ir_type
);
172 EXPECT_EQ(expanded_type
, tmp2
->type
);
174 ASSERT_FALSE(instructions
->is_empty());
175 ir
= (ir_instruction
*) instructions
->pop_head();
176 ir_assignment
*const assign2
= ir
->as_assignment();
177 EXPECT_EQ(ir_type_assignment
, ir
->ir_type
);
178 ASSERT_NE((void *)0, assign2
);
179 EXPECT_EQ(tmp2
, assign2
->lhs
->variable_referenced());
180 ir_expression
*unpack
= assign2
->rhs
->as_expression();
181 ASSERT_NE((void *)0, unpack
);
182 EXPECT_EQ(unpack_opcode
, unpack
->operation
);
183 EXPECT_EQ(tmp1
, unpack
->operands
[0]->variable_referenced());
186 EXPECT_TRUE(instructions
->is_empty());
189 TEST_F(expand_source
, uint64_variable
)
191 const glsl_type
*const type
= glsl_type::uint64_t_type
;
192 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
194 lower_64bit::expand_source(*body
, deref
, expanded_src
);
196 check_expanded_source(type
, expanded_src
);
197 check_instructions(&instructions
, type
, deref
);
200 TEST_F(expand_source
, u64vec2_variable
)
202 const glsl_type
*const type
= glsl_type::u64vec2_type
;
203 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
205 lower_64bit::expand_source(*body
, deref
, expanded_src
);
207 check_expanded_source(type
, expanded_src
);
208 check_instructions(&instructions
, type
, deref
);
211 TEST_F(expand_source
, u64vec3_variable
)
213 const glsl_type
*const type
= glsl_type::u64vec3_type
;
215 /* Generate an operand that is a scalar variable dereference. */
216 ir_variable
*const var
= new(mem_ctx
) ir_variable(type
,
220 ir_dereference_variable
*const deref
=
221 new(mem_ctx
) ir_dereference_variable(var
);
223 lower_64bit::expand_source(*body
, deref
, expanded_src
);
225 check_expanded_source(type
, expanded_src
);
226 check_instructions(&instructions
, type
, deref
);
229 TEST_F(expand_source
, u64vec4_variable
)
231 const glsl_type
*const type
= glsl_type::u64vec4_type
;
232 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
234 lower_64bit::expand_source(*body
, deref
, expanded_src
);
236 check_expanded_source(type
, expanded_src
);
237 check_instructions(&instructions
, type
, deref
);
240 TEST_F(expand_source
, int64_variable
)
242 const glsl_type
*const type
= glsl_type::int64_t_type
;
243 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
245 lower_64bit::expand_source(*body
, deref
, expanded_src
);
247 check_expanded_source(type
, expanded_src
);
248 check_instructions(&instructions
, type
, deref
);
251 TEST_F(expand_source
, i64vec2_variable
)
253 const glsl_type
*const type
= glsl_type::i64vec2_type
;
254 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
256 lower_64bit::expand_source(*body
, deref
, expanded_src
);
258 check_expanded_source(type
, expanded_src
);
259 check_instructions(&instructions
, type
, deref
);
262 TEST_F(expand_source
, i64vec3_variable
)
264 const glsl_type
*const type
= glsl_type::i64vec3_type
;
265 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
267 lower_64bit::expand_source(*body
, deref
, expanded_src
);
269 check_expanded_source(type
, expanded_src
);
270 check_instructions(&instructions
, type
, deref
);
273 TEST_F(expand_source
, i64vec4_variable
)
275 const glsl_type
*const type
= glsl_type::i64vec4_type
;
276 ir_dereference_variable
*const deref
= create_variable(mem_ctx
, type
);
278 lower_64bit::expand_source(*body
, deref
, expanded_src
);
280 check_expanded_source(type
, expanded_src
);
281 check_instructions(&instructions
, type
, deref
);
284 TEST_F(expand_source
, uint64_expression
)
286 const glsl_type
*const type
= glsl_type::uint64_t_type
;
287 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
289 lower_64bit::expand_source(*body
, expr
, expanded_src
);
291 check_expanded_source(type
, expanded_src
);
292 check_instructions(&instructions
, type
, expr
);
295 TEST_F(expand_source
, u64vec2_expression
)
297 const glsl_type
*const type
= glsl_type::u64vec2_type
;
298 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
300 lower_64bit::expand_source(*body
, expr
, expanded_src
);
302 check_expanded_source(type
, expanded_src
);
303 check_instructions(&instructions
, type
, expr
);
306 TEST_F(expand_source
, u64vec3_expression
)
308 const glsl_type
*const type
= glsl_type::u64vec3_type
;
309 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
311 lower_64bit::expand_source(*body
, expr
, expanded_src
);
313 check_expanded_source(type
, expanded_src
);
314 check_instructions(&instructions
, type
, expr
);
317 TEST_F(expand_source
, u64vec4_expression
)
319 const glsl_type
*const type
= glsl_type::u64vec4_type
;
320 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
322 lower_64bit::expand_source(*body
, expr
, expanded_src
);
324 check_expanded_source(type
, expanded_src
);
325 check_instructions(&instructions
, type
, expr
);
328 TEST_F(expand_source
, int64_expression
)
330 const glsl_type
*const type
= glsl_type::int64_t_type
;
331 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
333 lower_64bit::expand_source(*body
, expr
, expanded_src
);
335 check_expanded_source(type
, expanded_src
);
336 check_instructions(&instructions
, type
, expr
);
339 TEST_F(expand_source
, i64vec2_expression
)
341 const glsl_type
*const type
= glsl_type::i64vec2_type
;
342 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
344 lower_64bit::expand_source(*body
, expr
, expanded_src
);
346 check_expanded_source(type
, expanded_src
);
347 check_instructions(&instructions
, type
, expr
);
350 TEST_F(expand_source
, i64vec3_expression
)
352 const glsl_type
*const type
= glsl_type::i64vec3_type
;
353 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
355 lower_64bit::expand_source(*body
, expr
, expanded_src
);
357 check_expanded_source(type
, expanded_src
);
358 check_instructions(&instructions
, type
, expr
);
361 TEST_F(expand_source
, i64vec4_expression
)
363 const glsl_type
*const type
= glsl_type::i64vec4_type
;
364 ir_expression
*const expr
= create_expression(mem_ctx
, type
);
366 lower_64bit::expand_source(*body
, expr
, expanded_src
);
368 check_expanded_source(type
, expanded_src
);
369 check_instructions(&instructions
, type
, expr
);
372 class compact_destination
: public ::testing::Test
{
374 virtual void SetUp();
375 virtual void TearDown();
377 exec_list instructions
;
379 ir_variable
*expanded_src
[4];
384 compact_destination::SetUp()
386 mem_ctx
= ralloc_context(NULL
);
388 memset(expanded_src
, 0, sizeof(expanded_src
));
389 instructions
.make_empty();
390 body
= new ir_factory(&instructions
, mem_ctx
);
394 compact_destination::TearDown()
399 ralloc_free(mem_ctx
);
403 TEST_F(compact_destination
, uint64
)
405 const glsl_type
*const type
= glsl_type::uint64_t_type
;
407 for (unsigned i
= 0; i
< type
->vector_elements
; i
++) {
408 expanded_src
[i
] = new(mem_ctx
) ir_variable(glsl_type::uvec2_type
,
413 ir_dereference_variable
*deref
=
414 lower_64bit::compact_destination(*body
,
418 ASSERT_EQ(ir_type_dereference_variable
, deref
->ir_type
);
419 EXPECT_EQ(type
, deref
->var
->type
) <<
421 deref
->var
->type
->name
<<
427 ASSERT_FALSE(instructions
.is_empty());
428 ir
= (ir_instruction
*) instructions
.pop_head();
429 ir_variable
*const var
= ir
->as_variable();
430 ASSERT_NE((void *)0, var
);
431 EXPECT_EQ(deref
->var
, var
);
433 for (unsigned i
= 0; i
< type
->vector_elements
; i
++) {
434 ASSERT_FALSE(instructions
.is_empty());
435 ir
= (ir_instruction
*) instructions
.pop_head();
436 ir_assignment
*const assign
= ir
->as_assignment();
437 ASSERT_NE((void *)0, assign
);
438 EXPECT_EQ(deref
->var
, assign
->lhs
->variable_referenced());