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
{
55 virtual void TearDown();
57 char *interface_field_name(const glsl_type
*iface
, unsigned field
= 0)
59 return ralloc_asprintf(mem_ctx
,
62 iface
->fields
.structure
[field
].name
);
67 hash_table
*consumer_inputs
;
68 hash_table
*consumer_interface_inputs
;
70 const glsl_type
*simple_interface
;
71 ir_variable
*junk
[VARYING_SLOT_TESS_MAX
];
75 link_varyings::SetUp()
77 glsl_type_singleton_init_or_ref();
79 this->mem_ctx
= ralloc_context(NULL
);
80 this->ir
.make_empty();
82 this->consumer_inputs
=
83 _mesa_hash_table_create(NULL
, _mesa_hash_string
,
84 _mesa_key_string_equal
);
86 this->consumer_interface_inputs
=
87 _mesa_hash_table_create(NULL
, _mesa_hash_string
,
88 _mesa_key_string_equal
);
90 /* Needs to happen after glsl type initialization */
91 static const glsl_struct_field f
[] = {
92 glsl_struct_field(glsl_type::vec(4), "v")
95 this->simple_interface
=
96 glsl_type::get_interface_instance(f
,
98 GLSL_INTERFACE_PACKING_STD140
,
104 link_varyings::TearDown()
106 ralloc_free(this->mem_ctx
);
107 this->mem_ctx
= NULL
;
109 _mesa_hash_table_destroy(this->consumer_inputs
, NULL
);
110 this->consumer_inputs
= NULL
;
111 _mesa_hash_table_destroy(this->consumer_interface_inputs
, NULL
);
112 this->consumer_interface_inputs
= NULL
;
114 glsl_type_singleton_decref();
117 TEST_F(link_varyings
, single_simple_input
)
119 ir_variable
*const v
=
120 new(mem_ctx
) ir_variable(glsl_type::vec(4),
127 linker::populate_consumer_input_sets(mem_ctx
,
130 consumer_interface_inputs
,
133 hash_entry
*entry
= _mesa_hash_table_search(consumer_inputs
, "a");
134 EXPECT_EQ((void *) v
, entry
->data
);
135 EXPECT_EQ(1u, consumer_inputs
->entries
);
136 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
139 TEST_F(link_varyings
, gl_ClipDistance
)
141 const glsl_type
*const array_8_of_float
=
142 glsl_type::get_array_instance(glsl_type::vec(1), 8);
144 ir_variable
*const clipdistance
=
145 new(mem_ctx
) ir_variable(array_8_of_float
,
149 clipdistance
->data
.explicit_location
= true;
150 clipdistance
->data
.location
= VARYING_SLOT_CLIP_DIST0
;
151 clipdistance
->data
.explicit_index
= 0;
153 ir
.push_tail(clipdistance
);
155 linker::populate_consumer_input_sets(mem_ctx
,
158 consumer_interface_inputs
,
161 EXPECT_EQ(clipdistance
, junk
[VARYING_SLOT_CLIP_DIST0
]);
162 EXPECT_TRUE(consumer_inputs
->entries
== 0);
163 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
166 TEST_F(link_varyings
, gl_CullDistance
)
168 const glsl_type
*const array_8_of_float
=
169 glsl_type::get_array_instance(glsl_type::vec(1), 8);
171 ir_variable
*const culldistance
=
172 new(mem_ctx
) ir_variable(array_8_of_float
,
176 culldistance
->data
.explicit_location
= true;
177 culldistance
->data
.location
= VARYING_SLOT_CULL_DIST0
;
178 culldistance
->data
.explicit_index
= 0;
180 ir
.push_tail(culldistance
);
182 linker::populate_consumer_input_sets(mem_ctx
,
185 consumer_interface_inputs
,
188 EXPECT_EQ(culldistance
, junk
[VARYING_SLOT_CULL_DIST0
]);
189 EXPECT_TRUE(consumer_inputs
->entries
== 0);
190 EXPECT_TRUE(consumer_interface_inputs
->entries
== 0);
193 TEST_F(link_varyings
, single_interface_input
)
195 ir_variable
*const v
=
196 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
197 simple_interface
->fields
.structure
[0].name
,
200 v
->init_interface_type(simple_interface
);
204 linker::populate_consumer_input_sets(mem_ctx
,
207 consumer_interface_inputs
,
209 char *const full_name
= interface_field_name(simple_interface
);
211 hash_entry
*entry
= _mesa_hash_table_search(consumer_interface_inputs
,
213 EXPECT_EQ((void *) v
, entry
->data
);
214 EXPECT_EQ(1u, consumer_interface_inputs
->entries
);
215 EXPECT_TRUE(consumer_inputs
->entries
== 0);
218 TEST_F(link_varyings
, one_interface_and_one_simple_input
)
220 ir_variable
*const v
=
221 new(mem_ctx
) ir_variable(glsl_type::vec(4),
228 ir_variable
*const iface
=
229 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
230 simple_interface
->fields
.structure
[0].name
,
233 iface
->init_interface_type(simple_interface
);
237 linker::populate_consumer_input_sets(mem_ctx
,
240 consumer_interface_inputs
,
243 char *const iface_field_name
= interface_field_name(simple_interface
);
245 hash_entry
*entry
= _mesa_hash_table_search(consumer_interface_inputs
,
247 EXPECT_EQ((void *) iface
, entry
->data
);
248 EXPECT_EQ(1u, consumer_interface_inputs
->entries
);
250 entry
= _mesa_hash_table_search(consumer_inputs
, "a");
251 EXPECT_EQ((void *) v
, entry
->data
);
252 EXPECT_EQ(1u, consumer_inputs
->entries
);
255 TEST_F(link_varyings
, interface_field_doesnt_match_noninterface
)
257 char *const iface_field_name
= interface_field_name(simple_interface
);
259 /* The input shader has a single input variable name "a.v"
261 ir_variable
*const in_v
=
262 new(mem_ctx
) ir_variable(glsl_type::vec(4),
268 linker::populate_consumer_input_sets(mem_ctx
,
271 consumer_interface_inputs
,
274 /* Create an output variable, "v", that is part of an interface block named
275 * "a". They should not match.
277 ir_variable
*const out_v
=
278 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
279 simple_interface
->fields
.structure
[0].name
,
282 out_v
->init_interface_type(simple_interface
);
284 ir_variable
*const match
=
285 linker::get_matching_input(mem_ctx
,
288 consumer_interface_inputs
,
291 EXPECT_EQ(NULL
, match
);
294 TEST_F(link_varyings
, interface_field_doesnt_match_noninterface_vice_versa
)
296 char *const iface_field_name
= interface_field_name(simple_interface
);
298 /* In input shader has a single variable, "v", that is part of an interface
301 ir_variable
*const in_v
=
302 new(mem_ctx
) ir_variable(simple_interface
->fields
.structure
[0].type
,
303 simple_interface
->fields
.structure
[0].name
,
306 in_v
->init_interface_type(simple_interface
);
310 linker::populate_consumer_input_sets(mem_ctx
,
313 consumer_interface_inputs
,
316 /* Create an output variable "a.v". They should not match.
318 ir_variable
*const out_v
=
319 new(mem_ctx
) ir_variable(glsl_type::vec(4),
323 ir_variable
*const match
=
324 linker::get_matching_input(mem_ctx
,
327 consumer_interface_inputs
,
330 EXPECT_EQ(NULL
, match
);