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"
27 #include "util/ralloc.h"
29 #include "util/hash_table.h"
32 * \file varyings_test.cpp
34 * Test various aspects of linking shader stage inputs and outputs.
39 populate_consumer_input_sets(void *mem_ctx
, exec_list
*ir
,
40 hash_table
*consumer_inputs
,
41 hash_table
*consumer_interface_inputs
,
42 ir_variable
*consumer_inputs_with_locations
[VARYING_SLOT_MAX
]);
45 get_matching_input(void *mem_ctx
,
46 const ir_variable
*output_var
,
47 hash_table
*consumer_inputs
,
48 hash_table
*consumer_interface_inputs
,
49 ir_variable
*consumer_inputs_with_locations
[VARYING_SLOT_MAX
]);
52 class link_varyings
: public ::testing::Test
{
57 virtual void TearDown();
59 char *interface_field_name(const glsl_type
*iface
, unsigned field
= 0)
61 return ralloc_asprintf(mem_ctx
,
64 iface
->fields
.structure
[field
].name
);
69 hash_table
*consumer_inputs
;
70 hash_table
*consumer_interface_inputs
;
72 const glsl_type
*simple_interface
;
73 ir_variable
*junk
[VARYING_SLOT_TESS_MAX
];
76 link_varyings::link_varyings()
78 static const glsl_struct_field f
[] = {
79 glsl_struct_field(glsl_type::vec(4), "v")
82 this->simple_interface
=
83 glsl_type::get_interface_instance(f
,
85 GLSL_INTERFACE_PACKING_STD140
,
90 link_varyings::SetUp()
92 this->mem_ctx
= ralloc_context(NULL
);
93 this->ir
.make_empty();
95 this->consumer_inputs
=
96 _mesa_hash_table_create(NULL
, _mesa_key_hash_string
,
97 _mesa_key_string_equal
);
99 this->consumer_interface_inputs
=
100 _mesa_hash_table_create(NULL
, _mesa_key_hash_string
,
101 _mesa_key_string_equal
);
105 link_varyings::TearDown()
107 ralloc_free(this->mem_ctx
);
108 this->mem_ctx
= NULL
;
110 _mesa_hash_table_destroy(this->consumer_inputs
, NULL
);
111 this->consumer_inputs
= NULL
;
112 _mesa_hash_table_destroy(this->consumer_interface_inputs
, NULL
);
113 this->consumer_interface_inputs
= NULL
;
116 TEST_F(link_varyings
, single_simple_input
)
118 ir_variable
*const v
=
119 new(mem_ctx
) ir_variable(glsl_type::vec(4),
126 linker::populate_consumer_input_sets(mem_ctx
,
129 consumer_interface_inputs
,
132 hash_entry
*entry
= _mesa_hash_table_search(consumer_inputs
, "a");
133 EXPECT_EQ((void *) v
, entry
->data
);
134 EXPECT_EQ(1u, consumer_inputs
->entries
);
135 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
138 TEST_F(link_varyings
, gl_ClipDistance
)
140 const glsl_type
*const array_8_of_float
=
141 glsl_type::get_array_instance(glsl_type::vec(1), 8);
143 ir_variable
*const clipdistance
=
144 new(mem_ctx
) ir_variable(array_8_of_float
,
148 clipdistance
->data
.explicit_location
= true;
149 clipdistance
->data
.location
= VARYING_SLOT_CLIP_DIST0
;
150 clipdistance
->data
.explicit_index
= 0;
152 ir
.push_tail(clipdistance
);
154 linker::populate_consumer_input_sets(mem_ctx
,
157 consumer_interface_inputs
,
160 EXPECT_EQ(clipdistance
, junk
[VARYING_SLOT_CLIP_DIST0
]);
161 EXPECT_TRUE(consumer_inputs
->entries
== 0);
162 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
165 TEST_F(link_varyings
, gl_CullDistance
)
167 const glsl_type
*const array_8_of_float
=
168 glsl_type::get_array_instance(glsl_type::vec(1), 8);
170 ir_variable
*const culldistance
=
171 new(mem_ctx
) ir_variable(array_8_of_float
,
175 culldistance
->data
.explicit_location
= true;
176 culldistance
->data
.location
= VARYING_SLOT_CULL_DIST0
;
177 culldistance
->data
.explicit_index
= 0;
179 ir
.push_tail(culldistance
);
181 linker::populate_consumer_input_sets(mem_ctx
,
184 consumer_interface_inputs
,
187 EXPECT_EQ(culldistance
, junk
[VARYING_SLOT_CULL_DIST0
]);
188 EXPECT_TRUE(consumer_inputs
->entries
== 0);
189 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
192 TEST_F(link_varyings
, single_interface_input
)
194 ir_variable
*const v
=
195 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
196 simple_interface
->fields
.structure
[0].name
,
199 v
->init_interface_type(simple_interface
);
203 linker::populate_consumer_input_sets(mem_ctx
,
206 consumer_interface_inputs
,
208 char *const full_name
= interface_field_name(simple_interface
);
210 hash_entry
*entry
= _mesa_hash_table_search(consumer_interface_inputs
,
212 EXPECT_EQ((void *) v
, entry
->data
);
213 EXPECT_EQ(1u, consumer_interface_inputs
->entries
);
214 EXPECT_TRUE(consumer_inputs
->entries
== 0);
217 TEST_F(link_varyings
, one_interface_and_one_simple_input
)
219 ir_variable
*const v
=
220 new(mem_ctx
) ir_variable(glsl_type::vec(4),
227 ir_variable
*const iface
=
228 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
229 simple_interface
->fields
.structure
[0].name
,
232 iface
->init_interface_type(simple_interface
);
236 linker::populate_consumer_input_sets(mem_ctx
,
239 consumer_interface_inputs
,
242 char *const iface_field_name
= interface_field_name(simple_interface
);
244 hash_entry
*entry
= _mesa_hash_table_search(consumer_interface_inputs
,
246 EXPECT_EQ((void *) iface
, entry
->data
);
247 EXPECT_EQ(1u, consumer_interface_inputs
->entries
);
249 entry
= _mesa_hash_table_search(consumer_inputs
, "a");
250 EXPECT_EQ((void *) v
, entry
->data
);
251 EXPECT_EQ(1u, consumer_inputs
->entries
);
254 TEST_F(link_varyings
, interface_field_doesnt_match_noninterface
)
256 char *const iface_field_name
= interface_field_name(simple_interface
);
258 /* The input shader has a single input variable name "a.v"
260 ir_variable
*const in_v
=
261 new(mem_ctx
) ir_variable(glsl_type::vec(4),
267 linker::populate_consumer_input_sets(mem_ctx
,
270 consumer_interface_inputs
,
273 /* Create an output variable, "v", that is part of an interface block named
274 * "a". They should not match.
276 ir_variable
*const out_v
=
277 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
278 simple_interface
->fields
.structure
[0].name
,
281 out_v
->init_interface_type(simple_interface
);
283 ir_variable
*const match
=
284 linker::get_matching_input(mem_ctx
,
287 consumer_interface_inputs
,
290 EXPECT_EQ(NULL
, match
);
293 TEST_F(link_varyings
, interface_field_doesnt_match_noninterface_vice_versa
)
295 char *const iface_field_name
= interface_field_name(simple_interface
);
297 /* In input shader has a single variable, "v", that is part of an interface
300 ir_variable
*const in_v
=
301 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
302 simple_interface
->fields
.structure
[0].name
,
305 in_v
->init_interface_type(simple_interface
);
309 linker::populate_consumer_input_sets(mem_ctx
,
312 consumer_interface_inputs
,
315 /* Create an output variable "a.v". They should not match.
317 ir_variable
*const out_v
=
318 new(mem_ctx
) ir_variable(glsl_type::vec(4),
322 ir_variable
*const match
=
323 linker::get_matching_input(mem_ctx
,
326 consumer_interface_inputs
,
329 EXPECT_EQ(NULL
, match
);