• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /*!
25  * \file esextcGPUShader5TextureGatherOffset.cpp
26  * \brief gpu_shader5 extension - texture gather offset tests (Test 9 and 10)
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "esextcGPUShader5TextureGatherOffset.hpp"
30 
31 #include "gluContextInfo.hpp"
32 #include "glwEnums.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuTestLog.hpp"
35 
36 #include <cstdlib>
37 #include <cstring>
38 #include <sstream>
39 
40 namespace glcts
41 {
42 
43 /* Fragment Shader for GPUShader5TextureGatherOffsetTestBase */
44 const glw::GLchar* const GPUShader5TextureGatherOffsetTestBase::m_fragment_shader_code =
45 	"${VERSION}\n"
46 	"\n"
47 	"${GPU_SHADER5_REQUIRE}\n"
48 	"\n"
49 	"precision highp float;\n"
50 	"\n"
51 	"layout(location = 0) out vec4 fs_out_color;\n"
52 	"\n"
53 	"void main()\n"
54 	"{\n"
55 	"    fs_out_color = vec4(1, 1, 1, 1);\n"
56 	"}\n";
57 
58 /* Vertex Shader for GPUShader5TextureGatherOffsetColor2DRepeatCaseTest */
59 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::m_vertex_shader_code =
60 	"${VERSION}\n"
61 	"\n"
62 	"${GPU_SHADER5_REQUIRE}\n"
63 	"\n"
64 	"precision highp float;\n"
65 	"precision highp isampler2D;\n"
66 	"\n"
67 	"uniform isampler2D sampler;\n"
68 	"\n"
69 	"in ivec2 offsets;\n"
70 	"in vec2  texCoords;\n"
71 	"\n"
72 	"flat out ivec4 without_offset_0;\n"
73 	"flat out ivec4 without_offset_1;\n"
74 	"flat out ivec4 without_offset_2;\n"
75 	"flat out ivec4 without_offset_3;\n"
76 	"\n"
77 	"flat out ivec4 with_offset_0;\n"
78 	"flat out ivec4 with_offset_1;\n"
79 	"flat out ivec4 with_offset_2;\n"
80 	"flat out ivec4 with_offset_3;\n"
81 	"\n"
82 	"void main()\n"
83 	"{\n"
84 	"    without_offset_0 = textureGather      (sampler, texCoords, 0);\n"
85 	"    without_offset_1 = textureGather      (sampler, texCoords, 1);\n"
86 	"    without_offset_2 = textureGather      (sampler, texCoords, 2);\n"
87 	"    without_offset_3 = textureGather      (sampler, texCoords, 3);\n"
88 	"\n"
89 	"    with_offset_0    = textureGatherOffset(sampler, texCoords, offsets, 0);\n"
90 	"    with_offset_1    = textureGatherOffset(sampler, texCoords, offsets, 1);\n"
91 	"    with_offset_2    = textureGatherOffset(sampler, texCoords, offsets, 2);\n"
92 	"    with_offset_3    = textureGatherOffset(sampler, texCoords, offsets, 3);\n"
93 	"}\n";
94 
95 /* Vertex Shader for GPUShader5TextureGatherOffsetColor2DArrayCaseTest */
96 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DArrayCaseTest::m_vertex_shader_code =
97 	"${VERSION}\n"
98 	"\n"
99 	"${GPU_SHADER5_REQUIRE}\n"
100 	"\n"
101 	"precision highp float;\n"
102 	"precision highp isampler2DArray;\n"
103 	"\n"
104 	"uniform isampler2DArray sampler;\n"
105 	"\n"
106 	"in ivec2 offsets;\n"
107 	"in vec3  texCoords;\n"
108 	"\n"
109 	"flat out ivec4 without_offset_0;\n"
110 	"flat out ivec4 without_offset_1;\n"
111 	"flat out ivec4 without_offset_2;\n"
112 	"flat out ivec4 without_offset_3;\n"
113 	"\n"
114 	"flat out ivec4 with_offset_0;\n"
115 	"flat out ivec4 with_offset_1;\n"
116 	"flat out ivec4 with_offset_2;\n"
117 	"flat out ivec4 with_offset_3;\n"
118 	"\n"
119 	"void main()\n"
120 	"{\n"
121 	"    without_offset_0 = textureGather      (sampler, texCoords, 0);\n"
122 	"    without_offset_1 = textureGather      (sampler, texCoords, 1);\n"
123 	"    without_offset_2 = textureGather      (sampler, texCoords, 2);\n"
124 	"    without_offset_3 = textureGather      (sampler, texCoords, 3);\n"
125 	"\n"
126 	"    with_offset_0    = textureGatherOffset(sampler, texCoords, offsets, 0);\n"
127 	"    with_offset_1    = textureGatherOffset(sampler, texCoords, offsets, 1);\n"
128 	"    with_offset_2    = textureGatherOffset(sampler, texCoords, offsets, 2);\n"
129 	"    with_offset_3    = textureGatherOffset(sampler, texCoords, offsets, 3);\n"
130 	"}\n";
131 
132 /* Vertex Shader for GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest */
133 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::m_vertex_shader_code =
134 	"${VERSION}\n"
135 	"\n"
136 	"${GPU_SHADER5_REQUIRE}\n"
137 	"\n"
138 	"precision highp float;\n"
139 	"precision highp isampler2D;\n"
140 	"\n"
141 	"uniform isampler2D sampler;\n"
142 	"\n"
143 	"in ivec2 offsets;\n"
144 	"in vec2  texCoords;\n"
145 	"\n"
146 	"flat out ivec4 without_offset_0;\n"
147 	"flat out ivec4 without_offset_1;\n"
148 	"flat out ivec4 without_offset_2;\n"
149 	"flat out ivec4 without_offset_3;\n"
150 	"\n"
151 	"flat out ivec4 with_offset_0;\n"
152 	"flat out ivec4 with_offset_1;\n"
153 	"flat out ivec4 with_offset_2;\n"
154 	"flat out ivec4 with_offset_3;\n"
155 	"\n"
156 	"void main()\n"
157 	"{\n"
158 	"    vec2 floorTexCoords = floor(texCoords);\n"
159 	"    vec2 fractTexCoords = texCoords - floorTexCoords;\n"
160 	"\n"
161 	"    without_offset_0 = textureGather      (sampler, fractTexCoords, 0);\n"
162 	"    without_offset_1 = textureGather      (sampler, fractTexCoords, 1);\n"
163 	"\n"
164 	"    without_offset_2 = ivec4(int(floorTexCoords.x));\n"
165 	"    without_offset_3 = ivec4(int(floorTexCoords.y));\n"
166 	"\n"
167 	"    with_offset_0    = textureGatherOffset(sampler, texCoords, offsets, 0);\n"
168 	"    with_offset_1    = textureGatherOffset(sampler, texCoords, offsets, 1);\n"
169 	"    with_offset_2    = textureGatherOffset(sampler, texCoords, offsets, 2);\n"
170 	"    with_offset_3    = textureGatherOffset(sampler, texCoords, offsets, 3);\n"
171 	"}\n";
172 
173 /* Vertex Shader for GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest */
174 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::m_vertex_shader_code =
175 	"${VERSION}\n"
176 	"\n"
177 	"${GPU_SHADER5_REQUIRE}\n"
178 	"\n"
179 	"precision highp float;\n"
180 	"precision highp isampler2D;\n"
181 	"\n"
182 	"uniform isampler2D sampler;\n"
183 	"uniform isampler2D reference_sampler;\n"
184 	"\n"
185 	"in ivec2 offsets;\n"
186 	"in vec2  texCoords;\n"
187 	"\n"
188 	"flat out ivec4 without_offset_0;\n"
189 	"flat out ivec4 without_offset_1;\n"
190 	"flat out ivec4 without_offset_2;\n"
191 	"flat out ivec4 without_offset_3;\n"
192 	"\n"
193 	"flat out ivec4 with_offset_0;\n"
194 	"flat out ivec4 with_offset_1;\n"
195 	"flat out ivec4 with_offset_2;\n"
196 	"flat out ivec4 with_offset_3;\n"
197 	"\n"
198 	"void main()\n"
199 	"{\n"
200 	"    vec2 floorTexCoords = floor(texCoords);\n"
201 	"    vec2 fractTexCoords = texCoords - floorTexCoords;\n"
202 	"\n"
203 	"    without_offset_0 = textureGather      (reference_sampler, fractTexCoords, 0);\n"
204 	"    without_offset_1 = textureGather      (reference_sampler, fractTexCoords, 1);\n"
205 	"\n"
206 	"    without_offset_2 = ivec4(int(floorTexCoords.x));\n"
207 	"    without_offset_3 = ivec4(int(floorTexCoords.y));\n"
208 	"\n"
209 	"    with_offset_0    = textureGatherOffset(sampler, texCoords, offsets, 0);\n"
210 	"    with_offset_1    = textureGatherOffset(sampler, texCoords, offsets, 1);\n"
211 	"    with_offset_2    = textureGatherOffset(sampler, texCoords, offsets, 2);\n"
212 	"    with_offset_3    = textureGatherOffset(sampler, texCoords, offsets, 3);\n"
213 	"}\n";
214 
215 /* Vertex Shader for GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest */
216 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::m_vertex_shader_code_preamble =
217 	"${VERSION}\n"
218 	"\n"
219 	"${GPU_SHADER5_REQUIRE}\n"
220 	"\n"
221 	"precision highp float;\n"
222 	"precision highp isampler2D;\n"
223 	"\n"
224 	"uniform isampler2D sampler;\n"
225 	"\n"
226 	"in vec2  texCoords;\n"
227 	"\n"
228 	"flat out ivec4 without_offset_0;\n"
229 	"flat out ivec4 without_offset_1;\n"
230 	"flat out ivec4 without_offset_2;\n"
231 	"flat out ivec4 without_offset_3;\n"
232 	"\n"
233 	"flat out ivec4 with_offset_0;\n"
234 	"flat out ivec4 with_offset_1;\n"
235 	"flat out ivec4 with_offset_2;\n"
236 	"flat out ivec4 with_offset_3;\n"
237 	"\n"
238 	"void main()\n"
239 	"{\n"
240 	"    const ivec2 offsets[4] = \n";
241 
242 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::m_vertex_shader_code_body =
243 	"\n"
244 	"    without_offset_0 = textureGather       (sampler, texCoords, 0);\n"
245 	"    without_offset_1 = textureGather       (sampler, texCoords, 1);\n"
246 	"    without_offset_2 = textureGather       (sampler, texCoords, 2);\n"
247 	"    without_offset_3 = textureGather       (sampler, texCoords, 3);\n"
248 	"\n"
249 	"    with_offset_0    = textureGatherOffsets(sampler, texCoords, offsets, 0);\n"
250 	"    with_offset_1    = textureGatherOffsets(sampler, texCoords, offsets, 1);\n"
251 	"    with_offset_2    = textureGatherOffsets(sampler, texCoords, offsets, 2);\n"
252 	"    with_offset_3    = textureGatherOffsets(sampler, texCoords, offsets, 3);\n"
253 	"}\n";
254 
255 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest */
256 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::m_vertex_shader_code =
257 	"${VERSION}\n"
258 	"\n"
259 	"${GPU_SHADER5_REQUIRE}\n"
260 	"\n"
261 	"precision highp float;\n"
262 	"precision highp sampler2DShadow;\n"
263 	"\n"
264 	"uniform sampler2DShadow sampler;\n"
265 	"\n"
266 	"in ivec2 offsets;\n"
267 	"in vec2  texCoords;\n"
268 	"\n"
269 	"flat out ivec4 with_offset;\n"
270 	"flat out ivec4 without_offset;\n"
271 	"\n"
272 	"void main()\n"
273 	"{\n"
274 	"    ivec2 texture_size = textureSize(sampler, 0 /* lod */);\n"
275 	"    float step         = 1.0f / float(texture_size.x);\n"
276 	"\n"
277 	"    without_offset = ivec4(0, 0, 0, 0);\n"
278 	"    with_offset    = ivec4(0, 0, 0, 0);\n"
279 	"\n"
280 	"    for (int x = 0; x < texture_size.x; ++x)\n"
281 	"    {\n"
282 	"        float refZ = float(x) * step;\n"
283 	"\n"
284 	"        without_offset += ivec4(textureGather      (sampler, texCoords, refZ));\n"
285 	"        with_offset    += ivec4(textureGatherOffset(sampler, texCoords, refZ, offsets));\n"
286 	"    }\n"
287 	"}\n";
288 
289 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest */
290 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::m_vertex_shader_code =
291 	"${VERSION}\n"
292 	"\n"
293 	"${GPU_SHADER5_REQUIRE}\n"
294 	"\n"
295 	"precision highp float;\n"
296 	"precision highp sampler2DShadow;\n"
297 	"\n"
298 	"uniform sampler2DShadow sampler;\n"
299 	"\n"
300 	"in ivec2 offsets;\n"
301 	"in vec2  texCoords;\n"
302 	"\n"
303 	"flat out ivec4 without_offset;\n"
304 	"flat out ivec4 with_offset;\n"
305 	"\n"
306 	"void main()\n"
307 	"{\n"
308 	"    ivec2 texture_size = textureSize(sampler, 0 /* lod */);\n"
309 	"    float step         = 1.0f / float(texture_size.y);\n"
310 	"\n"
311 	"    without_offset = ivec4(0, 0, 0, 0);\n"
312 	"    with_offset    = ivec4(0, 0, 0, 0);\n"
313 	"\n"
314 	"    for (int y = 0; y < texture_size.y; ++y)\n"
315 	"    {\n"
316 	"        float refZ = float(y) * step;\n"
317 	"\n"
318 	"        without_offset += ivec4(textureGather      (sampler, texCoords, refZ));\n"
319 	"        with_offset    += ivec4(textureGatherOffset(sampler, texCoords, refZ, offsets));\n"
320 	"    }\n"
321 	"}\n";
322 
323 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DArrayCaseTest */
324 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::m_vertex_shader_code =
325 	"${VERSION}\n"
326 	"\n"
327 	"${GPU_SHADER5_REQUIRE}\n"
328 	"\n"
329 	"precision highp float;\n"
330 	"precision highp sampler2DArrayShadow;\n"
331 	"\n"
332 	"uniform sampler2DArrayShadow sampler;\n"
333 	"\n"
334 	"in ivec2 offsets;\n"
335 	"in vec3  texCoords;\n"
336 	"\n"
337 	"flat out ivec4 without_offset;\n"
338 	"flat out ivec4 with_offset;\n"
339 	"\n"
340 	"void main()\n"
341 	"{\n"
342 	"    ivec3 texture_size = textureSize(sampler, 0 /* lod */);\n"
343 	"    float step         = 1.0f / float(texture_size.x);\n"
344 	"\n"
345 	"    without_offset = ivec4(0, 0, 0, 0);\n"
346 	"    with_offset    = ivec4(0, 0, 0, 0);\n"
347 	"\n"
348 	"    for (int x = 0; x < texture_size.x; ++x)\n"
349 	"    {\n"
350 	"        float refZ = float(x) * step;\n"
351 	"\n"
352 	"        without_offset += ivec4(textureGather      (sampler, texCoords, refZ));\n"
353 	"        with_offset    += ivec4(textureGatherOffset(sampler, texCoords, refZ, offsets));\n"
354 	"    }\n"
355 	"}\n";
356 
357 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest */
358 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::m_vertex_shader_code =
359 	"${VERSION}\n"
360 	"\n"
361 	"${GPU_SHADER5_REQUIRE}\n"
362 	"\n"
363 	"precision highp float;\n"
364 	"precision highp sampler2DShadow;\n"
365 	"\n"
366 	"uniform sampler2DShadow sampler;\n"
367 	"\n"
368 	"in ivec2 offsets;\n"
369 	"in vec2  texCoords;\n"
370 	"\n"
371 	"flat out ivec4 with_offset;\n"
372 	"flat out ivec4 without_offset;\n"
373 	"flat out ivec4 floor_tex_coord;\n"
374 	"\n"
375 	"void main()\n"
376 	"{\n"
377 	"    ivec2 texture_size  = textureSize(sampler, 0 /* lod */);\n"
378 	"    float step          = 1.0f / float(texture_size.x);\n"
379 	"\n"
380 	"    vec2 floorTexCoords = floor(texCoords);\n"
381 	"    vec2 fractTexCoords = texCoords - floorTexCoords;\n"
382 	"\n"
383 	"    floor_tex_coord     = ivec4(ivec2(floorTexCoords.xy), 0, 0);\n"
384 	"\n"
385 	"    without_offset      = ivec4(0, 0, 0, 0);\n"
386 	"    with_offset         = ivec4(0, 0, 0, 0);\n"
387 	"\n"
388 	"    for (int x = 0; x < texture_size.x; ++x)\n"
389 	"    {\n"
390 	"        float refZ = float(x) * step;\n"
391 	"\n"
392 	"        without_offset += ivec4(textureGather      (sampler, fractTexCoords, refZ));\n"
393 	"        with_offset    += ivec4(textureGatherOffset(sampler, texCoords,      refZ, offsets));\n"
394 	"    }\n"
395 	"}\n";
396 
397 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest */
398 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::m_vertex_shader_code =
399 	"${VERSION}\n"
400 	"\n"
401 	"${GPU_SHADER5_REQUIRE}\n"
402 	"\n"
403 	"precision highp float;\n"
404 	"precision highp sampler2DShadow;\n"
405 	"\n"
406 	"uniform sampler2DShadow sampler;\n"
407 	"uniform sampler2DShadow reference_sampler;\n"
408 	"\n"
409 	"in ivec2 offsets;\n"
410 	"in vec2  texCoords;\n"
411 	"\n"
412 	"flat out ivec4 with_offset;\n"
413 	"flat out ivec4 without_offset;\n"
414 	"flat out ivec4 floor_tex_coord;\n"
415 	"\n"
416 	"void main()\n"
417 	"{\n"
418 	"    ivec2 texture_size  = textureSize(sampler, 0 /* lod */);\n"
419 	"    float step          = 1.0f / float(texture_size.x);\n"
420 	"\n"
421 	"    vec2 floorTexCoords = floor(texCoords);\n"
422 	"    vec2 fractTexCoords = texCoords - floorTexCoords;\n"
423 	"\n"
424 	"    floor_tex_coord     = ivec4(ivec2(floorTexCoords.xy), 0, 0);\n"
425 	"\n"
426 	"    without_offset      = ivec4(0, 0, 0, 0);\n"
427 	"    with_offset         = ivec4(0, 0, 0, 0);\n"
428 	"\n"
429 	"    for (int x = 0; x < texture_size.x; ++x)\n"
430 	"    {\n"
431 	"        float refZ = float(x) * step;\n"
432 	"\n"
433 	"        without_offset += ivec4(textureGather      (reference_sampler, fractTexCoords, refZ));\n"
434 	"        with_offset    += ivec4(textureGatherOffset(sampler,           texCoords,      refZ, offsets));\n"
435 	"    }\n"
436 	"}\n";
437 
438 /* Vertex Shader for GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest */
439 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::m_vertex_shader_code_preamble =
440 	"${VERSION}\n"
441 	"\n"
442 	"${GPU_SHADER5_REQUIRE}\n"
443 	"\n"
444 	"precision highp float;\n"
445 	"precision highp sampler2DShadow;\n"
446 	"\n"
447 	"uniform sampler2DShadow sampler;\n"
448 	"\n"
449 	"in vec2  texCoords;\n"
450 	"\n"
451 	"flat out ivec4 without_offset;\n"
452 	"flat out ivec4 with_offset;\n"
453 	"\n"
454 	"void main()\n"
455 	"{\n"
456 	"    const ivec2 offsets[4] =\n";
457 
458 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::m_vertex_shader_code_body =
459 	"\n"
460 	"    ivec2 texture_size = textureSize(sampler, 0 /* lod */);\n"
461 	"    float step         = 1.0f / float(texture_size.x);\n"
462 	"\n"
463 	"    without_offset = ivec4(0, 0, 0, 0);\n"
464 	"    with_offset = ivec4(0, 0, 0, 0);\n"
465 	"\n"
466 	"    for (int x = 0; x < texture_size.x; ++x)\n"
467 	"    {\n"
468 	"        float refZ = float(x) * step;\n"
469 	"\n"
470 	"        without_offset += ivec4(textureGather       (sampler, texCoords, refZ));\n"
471 	"        with_offset    += ivec4(textureGatherOffsets(sampler, texCoords, refZ, offsets));\n"
472 	"    }\n"
473 	"}\n";
474 
475 /* Constants for GPUShader5TextureGatherOffsetTestBase */
476 const glw::GLchar* const GPUShader5TextureGatherOffsetTestBase::m_coordinates_attribute_name	 = "texCoords";
477 const int				 GPUShader5TextureGatherOffsetTestBase::m_coordinate_resolution			 = 1024;
478 const int				 GPUShader5TextureGatherOffsetTestBase::m_max_coordinate_value			 = 8;
479 const int				 GPUShader5TextureGatherOffsetTestBase::m_min_coordinate_value			 = -8;
480 const unsigned int		 GPUShader5TextureGatherOffsetTestBase::m_n_components_per_varying		 = 4;
481 const unsigned int		 GPUShader5TextureGatherOffsetTestBase::m_n_texture_array_length		 = 4;
482 const unsigned int		 GPUShader5TextureGatherOffsetTestBase::m_n_vertices					 = 128;
483 const glw::GLchar* const GPUShader5TextureGatherOffsetTestBase::m_sampler_uniform_name			 = "sampler";
484 const glw::GLchar* const GPUShader5TextureGatherOffsetTestBase::m_reference_sampler_uniform_name = "reference_sampler";
485 
486 /* Constants for GPUShader5TextureGatherOffsetColorTestBase */
487 const unsigned int GPUShader5TextureGatherOffsetColorTestBase::m_texture_size = 64;
488 
489 /* Constants for GPUShader5TextureGatherOffsetDepthTestBase */
490 const unsigned int GPUShader5TextureGatherOffsetDepthTestBase::m_texture_size = 64;
491 
492 /* Constants for GPUShader5TextureGatherOffsetColor2DRepeatCaseTest */
493 const glw::GLchar* const GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::m_offsets_attribute_name = "offsets";
494 const unsigned int		 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::m_n_offsets_components   = 2;
495 
496 /* Constants for GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest */
497 const glw::GLchar* const GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::m_offsets_attribute_name = "offsets";
498 const unsigned int		 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::m_n_offsets_components   = 2;
499 
500 /** Constructor
501  *
502  *  @param context       Test context
503  *  @param name          Test case's name
504  *  @param description   Test case's description
505  **/
GPUShader5TextureGatherOffsetTestBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)506 GPUShader5TextureGatherOffsetTestBase::GPUShader5TextureGatherOffsetTestBase(Context&			  context,
507 																			 const ExtParameters& extParams,
508 																			 const char* name, const char* description)
509 	: TestCaseBase(context, extParams, name, description)
510 	, m_min_texture_gather_offset(0)
511 	, m_max_texture_gather_offset(0)
512 	, m_fragment_shader_id(0)
513 	, m_program_object_id(0)
514 	, m_vertex_shader_id(0)
515 	, m_vertex_array_object_id(0)
516 	, m_texture_object_id(0)
517 	, m_sampler_object_id(0)
518 	, m_is_texture_array(0)
519 	, m_texture_bytes_per_pixel(0)
520 	, m_texture_format(0)
521 	, m_texture_internal_format(0)
522 	, m_texture_type(0)
523 	, m_texture_size(0)
524 	, m_texture_wrap_mode(0)
525 	, m_transform_feedback_buffer_size(0)
526 	, m_transform_feedback_buffer_object_id(0)
527 	, m_n_coordinates_components(0)
528 {
529 	/* Nothing to be done here */
530 }
531 
532 /** Deinitializes GLES objects created during the test.
533  *
534  */
deinit()535 void GPUShader5TextureGatherOffsetTestBase::deinit()
536 {
537 	/* GL */
538 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
539 
540 	/* Bind default values */
541 	gl.useProgram(0);
542 	gl.bindVertexArray(0);
543 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */, 0 /* id */);
544 	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
545 
546 	/* Delete everything */
547 	if (0 != m_vertex_array_object_id)
548 	{
549 		gl.deleteVertexArrays(1, &m_vertex_array_object_id);
550 
551 		m_vertex_array_object_id = 0;
552 	}
553 
554 	if (0 != m_transform_feedback_buffer_object_id)
555 	{
556 		gl.deleteBuffers(1, &m_transform_feedback_buffer_object_id);
557 
558 		m_transform_feedback_buffer_object_id = 0;
559 	}
560 
561 	if (false == m_vertex_buffer_ids.empty())
562 	{
563 		gl.deleteBuffers((glw::GLsizei)m_vertex_buffer_ids.size(), &m_vertex_buffer_ids[0]);
564 	}
565 
566 	if (0 != m_program_object_id)
567 	{
568 		gl.deleteProgram(m_program_object_id);
569 
570 		m_program_object_id = 0;
571 	}
572 
573 	if (0 != m_fragment_shader_id)
574 	{
575 		gl.deleteShader(m_fragment_shader_id);
576 
577 		m_fragment_shader_id = 0;
578 	}
579 
580 	if (0 != m_vertex_shader_id)
581 	{
582 		gl.deleteShader(m_vertex_shader_id);
583 
584 		m_vertex_shader_id = 0;
585 	}
586 
587 	if (0 != m_texture_object_id)
588 	{
589 		gl.deleteTextures(1, &m_texture_object_id);
590 
591 		m_texture_object_id = 0;
592 	}
593 
594 	if (0 != m_sampler_object_id)
595 	{
596 		gl.deleteSamplers(1, &m_sampler_object_id);
597 
598 		m_sampler_object_id = 0;
599 	}
600 
601 	/* Deinitialize base */
602 	TestCaseBase::deinit();
603 }
604 
605 /** Initializes GLES objects used during the test.
606  *
607  */
initTest()608 void GPUShader5TextureGatherOffsetTestBase::initTest()
609 {
610 	/* This test should only run if EXT_gpu_shader5 is supported */
611 	if (true != m_is_gpu_shader5_supported)
612 	{
613 		throw tcu::NotSupportedError(GPU_SHADER5_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
614 	}
615 
616 	/* GL */
617 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
618 
619 	/* Get minimum and maximum texture gather offsets */
620 	gl.getIntegerv(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET, &m_min_texture_gather_offset);
621 	gl.getIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET, &m_max_texture_gather_offset);
622 
623 	GLU_EXPECT_NO_ERROR(
624 		gl.getError(),
625 		"Failed to get value of GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET or GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET");
626 
627 	/* Get details for transform feedback from child class */
628 	getTransformFeedBackDetails(m_transform_feedback_buffer_size, m_captured_varying_names);
629 
630 	/* Get shaders' code from children class */
631 	getShaderParts(m_vertex_shader_parts);
632 
633 	/* Create program and shaders */
634 	m_program_object_id = gl.createProgram();
635 
636 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
637 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
638 
639 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program or shader object(s)");
640 
641 	/* Set up transform feedback */
642 	gl.transformFeedbackVaryings(m_program_object_id, (glw::GLsizei)m_captured_varying_names.size(),
643 								 &m_captured_varying_names[0], GL_INTERLEAVED_ATTRIBS);
644 
645 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed");
646 
647 	/* Build program */
648 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1 /* number of FS parts */,
649 							  &m_fragment_shader_code, m_vertex_shader_id, (unsigned int)m_vertex_shader_parts.size(),
650 							  &m_vertex_shader_parts[0]))
651 	{
652 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
653 	}
654 
655 	/* Set program as active */
656 	gl.useProgram(m_program_object_id);
657 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed");
658 
659 	/* Generate and bind VAO */
660 	gl.genVertexArrays(1, &m_vertex_array_object_id);
661 	gl.bindVertexArray(m_vertex_array_object_id);
662 
663 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
664 
665 	/* Generate, bind and allocate buffer */
666 	gl.genBuffers(1, &m_transform_feedback_buffer_object_id);
667 	gl.bindBuffer(GL_ARRAY_BUFFER, m_transform_feedback_buffer_object_id);
668 	gl.bufferData(GL_ARRAY_BUFFER, m_transform_feedback_buffer_size, 0 /* no start data */, GL_STATIC_DRAW);
669 
670 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create buffer object");
671 
672 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_transform_feedback_buffer_object_id);
673 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed");
674 
675 	/* Create and fill texture */
676 	prepareTexture();
677 
678 	/* Let inheriting class prepare test specific input for program */
679 	prepareProgramInput();
680 }
681 
682 /** Executes the test.
683  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
684  *
685  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
686  *
687  *  Note the function throws exception should an error occur!
688  **/
iterate()689 tcu::TestCase::IterateResult GPUShader5TextureGatherOffsetTestBase::iterate()
690 {
691 	initTest();
692 
693 	/* Retrieve ES entrypoints */
694 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
695 
696 	/* Verification result */
697 	bool result = false;
698 
699 	/* Setup transform feedback */
700 	gl.enable(GL_RASTERIZER_DISCARD);
701 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed");
702 
703 	gl.beginTransformFeedback(GL_POINTS);
704 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed");
705 	{
706 		/* Draw */
707 		gl.drawArrays(GL_POINTS, 0 /* first */, m_n_vertices);
708 
709 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed");
710 	}
711 	/* Stop transform feedback */
712 	gl.endTransformFeedback();
713 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed");
714 
715 	gl.disable(GL_RASTERIZER_DISCARD);
716 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed");
717 
718 	/* Map transfrom feedback results */
719 	const void* transform_feedback_data = gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* offset */,
720 															m_transform_feedback_buffer_size, GL_MAP_READ_BIT);
721 
722 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map the buffer object into process space");
723 
724 	/* Verify data extracted from transfrom feedback */
725 	result = verifyResult(transform_feedback_data);
726 
727 	/* Unmap transform feedback buffer */
728 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
729 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error unmapping the buffer object");
730 
731 	/* Verify results */
732 	if (true != result)
733 	{
734 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
735 	}
736 	else
737 	{
738 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
739 	}
740 
741 	return STOP;
742 }
743 
744 /** Logs array of ints
745  *  Format: description ( e1 e2 ... eN )
746  *
747  *  @param data        Array of ints
748  *  @param length      Number of elements to log
749  *  @param description Description string
750  **/
logArray(const glw::GLint * data,unsigned int length,const char * description)751 void GPUShader5TextureGatherOffsetTestBase::logArray(const glw::GLint* data, unsigned int length,
752 													 const char* description)
753 {
754 	/* Message object */
755 	tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;
756 
757 	/* Adds description */
758 	message << description;
759 
760 	/* Begin array */
761 	message << "( ";
762 
763 	/* For each varying */
764 	for (unsigned int i = 0; i < length; ++i)
765 	{
766 		message << data[i] << " ";
767 	}
768 
769 	/* End array */
770 	message << ") ";
771 
772 	message << tcu::TestLog::EndMessage;
773 }
774 
775 /** Logs coordinates for vertex at given index
776  *  Format: Texture coordinates (range [0:1]): [x, y, .. ]
777  *
778  *  @param index Index of vertex
779  **/
logCoordinates(unsigned int index)780 void GPUShader5TextureGatherOffsetTestBase::logCoordinates(unsigned int index)
781 {
782 	/* Message object */
783 	tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;
784 
785 	/* Begin array */
786 	message << "Texture coordinates (range [0:1]): [";
787 
788 	/* Component index */
789 	unsigned int i = 0;
790 
791 	while (1)
792 	{
793 		message << m_coordinates_buffer_data[index * m_n_coordinates_components + i];
794 
795 		i += 1;
796 
797 		if (i >= m_n_coordinates_components)
798 		{
799 			break;
800 		}
801 		else
802 		{
803 			message << ", ";
804 		}
805 	}
806 
807 	/* End array */
808 	message << "]" << tcu::TestLog::EndMessage;
809 }
810 
811 /** Prepare buffers for vertex attributes
812  *
813  **/
prepareProgramInput()814 void GPUShader5TextureGatherOffsetTestBase::prepareProgramInput()
815 {
816 	/* GL */
817 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
818 
819 	/* Get vertex buffer infos from child class */
820 	prepareVertexBuffersData(m_vertex_buffer_infos);
821 
822 	/* Prepare info for coordinates */
823 	prepareVertexBufferInfoForCoordinates();
824 
825 	/* Constant for number of vertex buffers */
826 	const unsigned int n_vertex_buffers = (unsigned int)m_vertex_buffer_infos.size();
827 
828 	/* Prepare storage for vertex buffer ids */
829 	m_vertex_buffer_ids.resize(n_vertex_buffers);
830 
831 	/* Generate buffers */
832 	gl.genBuffers(n_vertex_buffers, &m_vertex_buffer_ids[0]);
833 
834 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create vertex buffers");
835 
836 	/* Setup each vertex buffer */
837 	for (unsigned int i = 0; i < n_vertex_buffers; ++i)
838 	{
839 		/* References for i-th vertex buffer */
840 		glw::GLuint		  vertex_buffer_id   = m_vertex_buffer_ids[i];
841 		VertexBufferInfo& vertex_buffer_info = m_vertex_buffer_infos[i];
842 
843 		/* Get attribute location */
844 		glw::GLint attribute_location =
845 			gl.getAttribLocation(m_program_object_id, m_vertex_buffer_infos[i].attribute_name);
846 
847 		if ((-1 == attribute_location) || (GL_NO_ERROR != gl.getError()))
848 		{
849 			TCU_FAIL("Failed to get location of attribute");
850 		}
851 
852 		/* Setup buffer for offsets attribute */
853 		gl.bindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
854 		gl.bufferData(GL_ARRAY_BUFFER, vertex_buffer_info.data_size, vertex_buffer_info.data, GL_STATIC_DRAW);
855 
856 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to fill vertex buffer with data");
857 
858 		/* Setup attribute */
859 		gl.enableVertexAttribArray(attribute_location);
860 
861 		if (GL_INT == vertex_buffer_info.type)
862 		{
863 			gl.vertexAttribIPointer(attribute_location, vertex_buffer_info.n_components, vertex_buffer_info.type,
864 									0 /* stride */, 0 /* offset */);
865 		}
866 		else
867 		{
868 			gl.vertexAttribPointer(attribute_location, vertex_buffer_info.n_components, vertex_buffer_info.type,
869 								   GL_FALSE /* normalization */, 0 /* stride */, 0 /* offset */);
870 		}
871 
872 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup vertex attribute arrays");
873 	}
874 
875 	/* Get sampler location */
876 	glw::GLint sampler_location = gl.getUniformLocation(m_program_object_id, m_sampler_uniform_name);
877 
878 	if ((-1 == sampler_location) || (GL_NO_ERROR != gl.getError()))
879 	{
880 		TCU_FAIL("Failed to get location of uniform \"sampler\"");
881 	}
882 
883 	/* Set uniform at sampler location value to index of first texture unit */
884 	gl.uniform1i(sampler_location, 0 /* first texture unit */);
885 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set uniform value");
886 
887 	if (GL_CLAMP_TO_EDGE == m_texture_wrap_mode)
888 	{
889 		/* Get reference_sampler location */
890 		glw::GLint reference_sampler_location =
891 			gl.getUniformLocation(m_program_object_id, m_reference_sampler_uniform_name);
892 
893 		if ((-1 == reference_sampler_location) || (GL_NO_ERROR != gl.getError()))
894 		{
895 			TCU_FAIL("Failed to get location of uniform \"reference sampler\"");
896 		}
897 
898 		/* Set uniform at reference_sampler location value to index of second texture unit */
899 		gl.uniform1i(reference_sampler_location, 1 /* second texture unit */);
900 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set uniform value");
901 	}
902 }
903 
904 /** Prepare texture and bind it to sampler
905  *
906  **/
prepareTexture()907 void GPUShader5TextureGatherOffsetTestBase::prepareTexture()
908 {
909 	/* Retrieve ES entrypoints */
910 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
911 
912 	/* Get texture info from child class */
913 	getTextureInfo(m_texture_size, m_texture_internal_format, m_texture_format, m_texture_type,
914 				   m_texture_bytes_per_pixel);
915 
916 	isTextureArray(m_is_texture_array);
917 	getTextureWrapMode(m_texture_wrap_mode);
918 
919 	/* Verify that recieved texture parameters are valid */
920 	glw::GLint max_texture_size = 0;
921 
922 	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
923 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_TEXTURE_SIZE pname");
924 
925 	if (m_texture_size > (glw::GLuint)max_texture_size)
926 	{
927 		throw tcu::NotSupportedError("Required texture dimmensions exceeds GL_MAX_TEXTURE_SIZE limit", "", __FILE__,
928 									 __LINE__);
929 	}
930 
931 	/* Activate first texture unit */
932 	gl.activeTexture(GL_TEXTURE0);
933 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0) failed");
934 
935 	/* Generate and allocate texture */
936 	gl.genTextures(1, &m_texture_object_id);
937 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
938 
939 	if (true == m_is_texture_array)
940 	{
941 		gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture_object_id);
942 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
943 
944 		gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, m_texture_internal_format, m_texture_size, m_texture_size,
945 						m_n_texture_array_length);
946 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
947 	}
948 	else
949 	{
950 		gl.bindTexture(GL_TEXTURE_2D, m_texture_object_id);
951 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
952 
953 		gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, m_texture_internal_format, m_texture_size, m_texture_size);
954 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
955 	}
956 
957 	/* Storage for texture data */
958 	std::vector<glw::GLubyte> texture_data;
959 
960 	texture_data.resize(m_texture_size * m_texture_size * m_texture_bytes_per_pixel);
961 
962 	/* Let child class prepare data for texture */
963 	prepareTextureData(&texture_data[0]);
964 
965 	/* Update texture data */
966 	if (true == m_is_texture_array)
967 	{
968 		for (unsigned int z = 0; z < m_n_texture_array_length; ++z)
969 		{
970 			gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* x */, 0 /* y */, z, m_texture_size,
971 							 m_texture_size, 1 /* depth */, m_texture_format, m_texture_type, &texture_data[0]);
972 
973 			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update texture data");
974 		}
975 	}
976 	else
977 	{
978 		gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, m_texture_size, m_texture_size,
979 						 m_texture_format, m_texture_type, &texture_data[0]);
980 
981 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update texture data");
982 	}
983 
984 	/* Set shadow comparison, filtering and wrap modes */
985 	glw::GLenum texture_target;
986 
987 	if (true == m_is_texture_array)
988 	{
989 		texture_target = GL_TEXTURE_2D_ARRAY;
990 	}
991 	else
992 	{
993 		texture_target = GL_TEXTURE_2D;
994 	}
995 
996 	/* Storage for border color */
997 	glw::GLfloat color[4];
998 
999 	/* Get border color */
1000 	getBorderColor(color);
1001 
1002 	gl.texParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1003 	gl.texParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1004 	gl.texParameteri(texture_target, GL_TEXTURE_WRAP_S, m_texture_wrap_mode);
1005 	gl.texParameteri(texture_target, GL_TEXTURE_WRAP_T, m_texture_wrap_mode);
1006 	gl.texParameteri(texture_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1007 	gl.texParameteri(texture_target, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
1008 
1009 	/* Set border color when "clamp to border" mode is selected */
1010 	if (m_glExtTokens.CLAMP_TO_BORDER == m_texture_wrap_mode)
1011 	{
1012 		gl.texParameterfv(texture_target, m_glExtTokens.TEXTURE_BORDER_COLOR, color);
1013 	}
1014 
1015 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set texture parameters");
1016 
1017 	/* Setup texture unit for reference_sampler */
1018 	if (GL_CLAMP_TO_EDGE == m_texture_wrap_mode)
1019 	{
1020 		/* Activate second texture unit */
1021 		gl.activeTexture(GL_TEXTURE1);
1022 		GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1) failed");
1023 
1024 		/* Bind texture */
1025 		gl.bindTexture(texture_target, m_texture_object_id);
1026 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture failed");
1027 
1028 		/* Generate sampler */
1029 		gl.genSamplers(1, &m_sampler_object_id);
1030 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to generate sampler");
1031 
1032 		/* Bind sampler to second texture unit */
1033 		gl.bindSampler(1, m_sampler_object_id);
1034 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind sampler to unit 1");
1035 
1036 		/* Set sampler parameters */
1037 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1038 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1039 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_WRAP_S, m_glExtTokens.CLAMP_TO_BORDER);
1040 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_WRAP_T, m_glExtTokens.CLAMP_TO_BORDER);
1041 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1042 		gl.samplerParameteri(m_sampler_object_id, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
1043 		gl.samplerParameterfv(m_sampler_object_id, m_glExtTokens.TEXTURE_BORDER_COLOR, color);
1044 
1045 		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set sampler parameters");
1046 	}
1047 }
1048 
1049 /** Prepare buffer for texture coordinates
1050  *
1051  **/
prepareVertexBufferInfoForCoordinates()1052 void GPUShader5TextureGatherOffsetTestBase::prepareVertexBufferInfoForCoordinates()
1053 {
1054 	/* Select proper number of components */
1055 	if (true == m_is_texture_array)
1056 	{
1057 		m_n_coordinates_components = 3;
1058 	}
1059 	else
1060 	{
1061 		m_n_coordinates_components = 2;
1062 	}
1063 
1064 	/* Prepare storage for texture coordinates */
1065 	m_coordinates_buffer_data.resize(m_n_vertices * m_n_coordinates_components);
1066 
1067 	/* Variables for calculation of texture coordiantes' range and offsets */
1068 	const float coordinate_denominator = m_coordinate_resolution;
1069 	int			x_modulus;
1070 	float		x_offset;
1071 	float		x_range;
1072 	int			y_modulus;
1073 	float		y_offset;
1074 	float		y_range;
1075 
1076 	/* Calculation of texture coordiantes' range and offsets */
1077 	x_range = m_max_coordinate_value - m_min_coordinate_value;
1078 	y_range = m_max_coordinate_value - m_min_coordinate_value;
1079 
1080 	x_offset = m_min_coordinate_value;
1081 	y_offset = m_min_coordinate_value;
1082 
1083 	x_range *= coordinate_denominator;
1084 	y_range *= coordinate_denominator;
1085 
1086 	x_modulus = (int)x_range;
1087 	y_modulus = (int)y_range;
1088 
1089 	/* Prepare texture coordinates */
1090 	if (true == m_is_texture_array)
1091 	{
1092 		/* First four coordinates are corners, each comes from unique level */
1093 		setCoordinatesData(0.0f, 0.0f, 0.0f, 0);
1094 		setCoordinatesData(0.0f, 1.0f, 1.0f, 1);
1095 		setCoordinatesData(1.0f, 0.0f, 2.0f, 2);
1096 		setCoordinatesData(1.0f, 1.0f, 3.0f, 3);
1097 
1098 		/* Generate rest of texture coordinates */
1099 		for (unsigned int i = 4; i < m_n_vertices; ++i)
1100 		{
1101 			const glw::GLfloat coord_x = ((float)(rand() % x_modulus)) / coordinate_denominator + x_offset;
1102 			const glw::GLfloat coord_y = ((float)(rand() % y_modulus)) / coordinate_denominator + y_offset;
1103 			const glw::GLfloat coord_z =
1104 				((float)(rand() % m_n_texture_array_length * m_coordinate_resolution)) / coordinate_denominator;
1105 
1106 			setCoordinatesData(coord_x, coord_y, coord_z, i);
1107 		}
1108 	}
1109 	else
1110 	{
1111 		/* First four coordinates are corners */
1112 		setCoordinatesData(0.0f, 0.0f, 0);
1113 		setCoordinatesData(0.0f, 1.0f, 1);
1114 		setCoordinatesData(1.0f, 0.0f, 2);
1115 		setCoordinatesData(1.0f, 1.0f, 3);
1116 
1117 		/* Generate rest of texture coordinates */
1118 		for (unsigned int i = 4; i < m_n_vertices; ++i)
1119 		{
1120 			const glw::GLfloat coord_x = ((float)(rand() % x_modulus)) / coordinate_denominator + x_offset;
1121 			const glw::GLfloat coord_y = ((float)(rand() % y_modulus)) / coordinate_denominator + y_offset;
1122 
1123 			setCoordinatesData(coord_x, coord_y, i);
1124 		}
1125 	}
1126 
1127 	/* Setup coordinates VB info */
1128 	VertexBufferInfo info;
1129 
1130 	info.attribute_name = m_coordinates_attribute_name;
1131 	info.n_components   = m_n_coordinates_components;
1132 	info.type			= GL_FLOAT;
1133 	info.data			= &m_coordinates_buffer_data[0];
1134 	info.data_size		= (glw::GLuint)(m_coordinates_buffer_data.size() * sizeof(glw::GLfloat));
1135 
1136 	/* Store results */
1137 	m_vertex_buffer_infos.push_back(info);
1138 }
1139 
1140 /** Set 2D texture coordinate for vertex at given index
1141  *
1142  *  @param x     X coordinate
1143  *  @param y     Y coordinate
1144  *  @param index Index of vertex
1145  **/
setCoordinatesData(glw::GLfloat x,glw::GLfloat y,unsigned int index)1146 void GPUShader5TextureGatherOffsetTestBase::setCoordinatesData(glw::GLfloat x, glw::GLfloat y, unsigned int index)
1147 {
1148 	const unsigned int vertex_offset = m_n_coordinates_components * index;
1149 
1150 	m_coordinates_buffer_data[vertex_offset + 0] = x;
1151 	m_coordinates_buffer_data[vertex_offset + 1] = y;
1152 }
1153 
1154 /** Set 3D texture coordinate for vertex at given index
1155  *
1156  *  @param x     X coordinate
1157  *  @param y     Y coordinate
1158  *  @param z     Z coordinate
1159  *  @param index Index of vertex
1160  **/
setCoordinatesData(glw::GLfloat x,glw::GLfloat y,glw::GLfloat z,unsigned int index)1161 void GPUShader5TextureGatherOffsetTestBase::setCoordinatesData(glw::GLfloat x, glw::GLfloat y, glw::GLfloat z,
1162 															   unsigned int index)
1163 {
1164 	const unsigned int vertex_offset = m_n_coordinates_components * index;
1165 
1166 	m_coordinates_buffer_data[vertex_offset + 0] = x;
1167 	m_coordinates_buffer_data[vertex_offset + 1] = y;
1168 	m_coordinates_buffer_data[vertex_offset + 2] = z;
1169 }
1170 
1171 /** Constructor
1172  *
1173  * @param context       Test context
1174  * @param name          Test case's name
1175  * @param description   Test case's description
1176  **/
GPUShader5TextureGatherOffsetColorTestBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)1177 GPUShader5TextureGatherOffsetColorTestBase::GPUShader5TextureGatherOffsetColorTestBase(Context&				context,
1178 																					   const ExtParameters& extParams,
1179 																					   const char*			name,
1180 																					   const char*			description)
1181 	: GPUShader5TextureGatherOffsetTestBase(context, extParams, name, description), m_n_varyings_per_vertex(0)
1182 {
1183 	/* Nothing to be done here */
1184 }
1185 
1186 /** Provides color that will be used as border color for "clamp to border" mode
1187  *
1188  * @param out_color Color
1189  **/
getBorderColor(glw::GLfloat out_color[4])1190 void GPUShader5TextureGatherOffsetColorTestBase::getBorderColor(glw::GLfloat out_color[4])
1191 {
1192 	out_color[0] = -1.0f;
1193 	out_color[1] = -1.0f;
1194 	out_color[2] = -1.0f;
1195 	out_color[3] = -1.0f;
1196 }
1197 
1198 /** Provides informations required to create texture
1199  *
1200  *  @param out_size                    Size of texture
1201  *  @param out_texture_internal_format Internal format of texture
1202  *  @param out_texture_format          Format of texture
1203  *  @param out_texture_type            Type of texture
1204  *  @param out_bytes_per_pixel         Bytes per pixel
1205  **/
getTextureInfo(glw::GLuint & out_size,glw::GLenum & out_texture_internal_format,glw::GLenum & out_texture_format,glw::GLenum & out_texture_type,glw::GLuint & out_bytes_per_pixel)1206 void GPUShader5TextureGatherOffsetColorTestBase::getTextureInfo(glw::GLuint& out_size,
1207 																glw::GLenum& out_texture_internal_format,
1208 																glw::GLenum& out_texture_format,
1209 																glw::GLenum& out_texture_type,
1210 																glw::GLuint& out_bytes_per_pixel)
1211 {
1212 	out_size					= m_texture_size;
1213 	out_texture_internal_format = GL_RGBA32I;
1214 	out_texture_format			= GL_RGBA_INTEGER;
1215 	out_texture_type			= GL_INT;
1216 	out_bytes_per_pixel			= 4 * sizeof(glw::GLint); /* RGBA * int */
1217 }
1218 
1219 /** Get wrap mode for texture
1220  *
1221  *  @param out_wrap_mode Wrap mode
1222  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1223 void GPUShader5TextureGatherOffsetColorTestBase::getTextureWrapMode(glw::GLenum& out_wrap_mode)
1224 {
1225 	out_wrap_mode = GL_REPEAT;
1226 }
1227 
1228 /** Get size of buffer used as output from transform feedback and names of varyings
1229  *
1230  *  @param out_buffer_size       Size of buffer
1231  *  @param out_captured_varyings Names of varyings
1232  **/
getTransformFeedBackDetails(glw::GLuint & out_buffer_size,std::vector<const glw::GLchar * > & out_captured_varyings)1233 void GPUShader5TextureGatherOffsetColorTestBase::getTransformFeedBackDetails(
1234 	glw::GLuint& out_buffer_size, std::vector<const glw::GLchar*>& out_captured_varyings)
1235 {
1236 	out_captured_varyings.reserve(8);
1237 	out_captured_varyings.push_back("without_offset_0");
1238 	out_captured_varyings.push_back("with_offset_0");
1239 	out_captured_varyings.push_back("without_offset_1");
1240 	out_captured_varyings.push_back("with_offset_1");
1241 	out_captured_varyings.push_back("without_offset_2");
1242 	out_captured_varyings.push_back("with_offset_2");
1243 	out_captured_varyings.push_back("without_offset_3");
1244 	out_captured_varyings.push_back("with_offset_3");
1245 
1246 	m_n_varyings_per_vertex = (unsigned int)out_captured_varyings.size();
1247 
1248 	out_buffer_size = static_cast<glw::GLuint>(m_n_vertices * m_n_varyings_per_vertex * m_n_components_per_varying *
1249 											   sizeof(glw::GLint));
1250 }
1251 
1252 /** Check if texture array is required
1253  *
1254  *  @param out_is_texture_array Set to true if texture array is required, false otherwise
1255  **/
isTextureArray(bool & out_is_texture_array)1256 void GPUShader5TextureGatherOffsetColorTestBase::isTextureArray(bool& out_is_texture_array)
1257 {
1258 	out_is_texture_array = false;
1259 }
1260 
1261 /** Prepare texture data as expected by all cases in test 9.
1262  *  Each texel is assigned {x, y, x, y}, where x and y are coordinates of texel.
1263  *
1264  *  @param data Storage space for texture data
1265  **/
prepareTextureData(glw::GLubyte * data)1266 void GPUShader5TextureGatherOffsetColorTestBase::prepareTextureData(glw::GLubyte* data)
1267 {
1268 	/* Data pointer */
1269 	glw::GLint* texture_data = (glw::GLint*)data;
1270 
1271 	/* Constants */
1272 	const unsigned int n_components_per_pixel = 4;
1273 	const unsigned int line_size			  = n_components_per_pixel * m_texture_size;
1274 
1275 	/* Prepare texture's data */
1276 	for (unsigned int y = 0; y < m_texture_size; ++y)
1277 	{
1278 		for (unsigned int x = 0; x < m_texture_size; ++x)
1279 		{
1280 			const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
1281 
1282 			/* texel.r = x, texel.g = y */
1283 			texture_data[pixel_offset + 0] = x;
1284 			texture_data[pixel_offset + 1] = y;
1285 
1286 			/* texel.b = x, texel.a = y */
1287 			texture_data[pixel_offset + 2] = x;
1288 			texture_data[pixel_offset + 3] = y;
1289 		}
1290 	}
1291 }
1292 
1293 /** Verification of results
1294  *
1295  *  @param result Pointer to data mapped from transform feedback buffer. Size of
1296  *                data is equal to buffer_size set by getTransformFeedbackBufferSize
1297  *
1298  *  @return true  Result match expected value
1299  *          false Result has wrong value
1300  **/
verifyResult(const void * result_data)1301 bool GPUShader5TextureGatherOffsetColorTestBase::verifyResult(const void* result_data)
1302 {
1303 	/* All data stored in data are ints */
1304 	glw::GLint* results = (glw::GLint*)result_data;
1305 
1306 	/* Verification result */
1307 	bool result = true;
1308 
1309 	/* Constants for data offsets calculation */
1310 	const unsigned int vertex_size_in_results_buffer = m_n_varyings_per_vertex * m_n_components_per_varying;
1311 	const unsigned int bytes_per_varying			 = m_n_components_per_varying * sizeof(glw::GLint);
1312 	const unsigned int vertex_varying_0_offset		 = 0;
1313 	const unsigned int vertex_varying_1_offset		 = vertex_varying_0_offset + 2 * m_n_components_per_varying;
1314 	const unsigned int vertex_varying_2_offset		 = vertex_varying_1_offset + 2 * m_n_components_per_varying;
1315 	const unsigned int vertex_varying_3_offset		 = vertex_varying_2_offset + 2 * m_n_components_per_varying;
1316 	const unsigned int with_offset_offset			 = m_n_components_per_varying;
1317 	const unsigned int without_offset_offset		 = 0;
1318 
1319 	/* For each vertex */
1320 	for (unsigned int vertex = 0; vertex < m_n_vertices; ++vertex)
1321 	{
1322 		CapturedVaryings captured_data;
1323 
1324 		/* Pointers to all varyings for given vertex */
1325 		const glw::GLint* without_offset_0 =
1326 			results + vertex_varying_0_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1327 		const glw::GLint* with_offset_0 =
1328 			results + vertex_varying_0_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1329 
1330 		const glw::GLint* without_offset_1 =
1331 			results + vertex_varying_1_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1332 		const glw::GLint* with_offset_1 =
1333 			results + vertex_varying_1_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1334 
1335 		const glw::GLint* without_offset_2 =
1336 			results + vertex_varying_2_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1337 		const glw::GLint* with_offset_2 =
1338 			results + vertex_varying_2_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1339 
1340 		const glw::GLint* without_offset_3 =
1341 			results + vertex_varying_3_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1342 		const glw::GLint* with_offset_3 =
1343 			results + vertex_varying_3_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1344 
1345 		/* Copy captured varyings to captured_data instance */
1346 		memcpy(captured_data.without_offset_0, without_offset_0, bytes_per_varying);
1347 		memcpy(captured_data.without_offset_1, without_offset_1, bytes_per_varying);
1348 		memcpy(captured_data.without_offset_2, without_offset_2, bytes_per_varying);
1349 		memcpy(captured_data.without_offset_3, without_offset_3, bytes_per_varying);
1350 
1351 		memcpy(captured_data.with_offset_0, with_offset_0, bytes_per_varying);
1352 		memcpy(captured_data.with_offset_1, with_offset_1, bytes_per_varying);
1353 		memcpy(captured_data.with_offset_2, with_offset_2, bytes_per_varying);
1354 		memcpy(captured_data.with_offset_3, with_offset_3, bytes_per_varying);
1355 
1356 		/* Let child class check if result is ok */
1357 		const bool is_result_ok = checkResult(captured_data, vertex, m_texture_size);
1358 
1359 		/* Do not break on first error */
1360 		if (false == is_result_ok)
1361 		{
1362 			result = false;
1363 		}
1364 	}
1365 
1366 	/* Done */
1367 	return result;
1368 }
1369 
1370 /** Logs data captured varyings
1371  *
1372  *  @param varyings Instance of capturedVaryings to be logged
1373  **/
logVaryings(const CapturedVaryings & varyings)1374 void GPUShader5TextureGatherOffsetColorTestBase::logVaryings(const CapturedVaryings& varyings)
1375 {
1376 	logArray(varyings.without_offset_0, m_n_components_per_varying, "Without offset X: ");
1377 
1378 	logArray(varyings.without_offset_1, m_n_components_per_varying, "Without offset Y: ");
1379 
1380 	logArray(varyings.without_offset_2, m_n_components_per_varying, "Without offset Z: ");
1381 
1382 	logArray(varyings.without_offset_3, m_n_components_per_varying, "Without offset W: ");
1383 
1384 	logArray(varyings.with_offset_0, m_n_components_per_varying, "With offset X: ");
1385 
1386 	logArray(varyings.with_offset_1, m_n_components_per_varying, "With offset Y: ");
1387 
1388 	logArray(varyings.with_offset_2, m_n_components_per_varying, "With offset Z: ");
1389 
1390 	logArray(varyings.with_offset_3, m_n_components_per_varying, "With offset W: ");
1391 }
1392 
1393 /** Constructor
1394  *
1395  * @param context       Test context
1396  * @param name          Test case's name
1397  * @param description   Test case's description
1398  **/
GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1399 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(
1400 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1401 	: GPUShader5TextureGatherOffsetColorTestBase(context, extParams, name, description)
1402 {
1403 	/* Nothing to be done here */
1404 }
1405 
1406 /** Get parts of vertex shader
1407  *
1408  *  @param out_vertex_shader_parts Vector of vertex shader parts
1409  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1410 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::getShaderParts(
1411 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
1412 {
1413 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
1414 }
1415 
1416 /** Prepare test specific data, that will be used as vertex attributes
1417  *
1418  *  @param vertex_buffer_infos Vector of vertexBufferInfo instances
1419  **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)1420 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::prepareVertexBuffersData(
1421 	std::vector<VertexBufferInfo>& vertex_buffer_infos)
1422 {
1423 	/* Constats for offsets and size of buffer */
1424 	const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
1425 
1426 	/* Limits used to generate offsets */
1427 	const glw::GLint min_ptgo = m_min_texture_gather_offset;
1428 	const glw::GLint max_ptgo = m_max_texture_gather_offset;
1429 
1430 	/* Storage for offsets */
1431 	m_offsets_buffer_data.resize(n_total_components);
1432 
1433 	/* Set the seed for random number generator */
1434 	randomSeed(1);
1435 
1436 	/* Generate offsets */
1437 	for (unsigned int i = 0; i < n_total_components; ++i)
1438 	{
1439 		m_offsets_buffer_data[i] =
1440 			static_cast<glw::GLint>(randomFormula(static_cast<glw::GLuint>(max_ptgo - min_ptgo + 1))) + min_ptgo;
1441 	}
1442 
1443 	/* Setup offsets VB info */
1444 	VertexBufferInfo info;
1445 
1446 	info.attribute_name = m_offsets_attribute_name;
1447 	info.n_components   = m_n_offsets_components;
1448 	info.type			= GL_INT;
1449 	info.data			= &m_offsets_buffer_data[0];
1450 	info.data_size		= (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
1451 
1452 	/* Add VB info to vector */
1453 	vertex_buffer_infos.push_back(info);
1454 }
1455 
1456 /** Check if data captured for vertex at index are as expected
1457  *
1458  *  @param captured_data Instance of capturedVaryings for vertex at index
1459  *  @param index         Index of vertex
1460  *  @param texture_size  Size of texture
1461  *
1462  *  @return True  Results match expected values
1463  *          False Results do not match expected values
1464  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)1465 bool GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::checkResult(const CapturedVaryings& captured_data,
1466 																	 unsigned int index, unsigned int tex_size)
1467 {
1468 	/* Signed int value has to be used with operator % in order to work as expected */
1469 	const glw::GLint texture_size = (glw::GLint)tex_size;
1470 
1471 	/* Get offsets for vertex */
1472 	glw::GLint x_offset;
1473 	glw::GLint y_offset;
1474 
1475 	getOffsets(x_offset, y_offset, index);
1476 
1477 	/* Roll x offsets around left edge when negative */
1478 	if (0 > x_offset)
1479 	{
1480 		x_offset = x_offset % texture_size;
1481 		x_offset += texture_size;
1482 	}
1483 
1484 	/* Roll y offsets around top edge when negative */
1485 	if (0 > y_offset)
1486 	{
1487 		y_offset = y_offset % texture_size;
1488 		y_offset += texture_size;
1489 	}
1490 
1491 	/* Storage for expected values of with_offset varyings */
1492 	glw::GLint expected_values_0[m_n_components_per_varying];
1493 	glw::GLint expected_values_1[m_n_components_per_varying];
1494 	glw::GLint expected_values_2[m_n_components_per_varying];
1495 	glw::GLint expected_values_3[m_n_components_per_varying];
1496 
1497 	/* Calculate expected values of with_offset varyings */
1498 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1499 	{
1500 		expected_values_0[i] = ((x_offset + captured_data.without_offset_0[i]) % texture_size);
1501 		expected_values_1[i] = ((y_offset + captured_data.without_offset_1[i]) % texture_size);
1502 		expected_values_2[i] = ((x_offset + captured_data.without_offset_2[i]) % texture_size);
1503 		expected_values_3[i] = ((y_offset + captured_data.without_offset_3[i]) % texture_size);
1504 	}
1505 
1506 	/* Verify that expected_values match those in with_offset varyings */
1507 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1508 	{
1509 		if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
1510 			(captured_data.with_offset_1[i] != expected_values_1[i]) ||
1511 			(captured_data.with_offset_2[i] != expected_values_2[i]) ||
1512 			(captured_data.with_offset_3[i] != expected_values_3[i]))
1513 		{
1514 			/* Log invalid results */
1515 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1516 
1517 			logCoordinates(index);
1518 
1519 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1520 
1521 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1522 							   << tcu::TestLog::EndMessage;
1523 
1524 			logVaryings(captured_data);
1525 
1526 			m_testCtx.getLog() << tcu::TestLog::EndSection;
1527 
1528 			/* Done */
1529 			return false;
1530 		}
1531 	}
1532 
1533 	/* Done */
1534 	return true;
1535 }
1536 
1537 /** Get offsets for vertex at index
1538  *
1539  *  @param out_x_offset X offset
1540  *  @param out_y_offset Y offset
1541  *  @param index        Index of vertex
1542  **/
getOffsets(glw::GLint & out_x_offset,glw::GLint & out_y_offset,unsigned int index)1543 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset,
1544 																	unsigned int index)
1545 {
1546 	out_x_offset = m_offsets_buffer_data[index * m_n_offsets_components + 0];
1547 	out_y_offset = m_offsets_buffer_data[index * m_n_offsets_components + 1];
1548 }
1549 
1550 /** Constructor
1551  *
1552  * @param context       Test context
1553  * @param name          Test case's name
1554  * @param description   Test case's description
1555  **/
GPUShader5TextureGatherOffsetColor2DArrayCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1556 GPUShader5TextureGatherOffsetColor2DArrayCaseTest::GPUShader5TextureGatherOffsetColor2DArrayCaseTest(
1557 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1558 	: GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1559 {
1560 	/* Nothing to be done here */
1561 }
1562 
1563 /** Get parts of vertex shader
1564  *
1565  *  @param out_vertex_shader_parts Vector of vertex shader parts
1566  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1567 void GPUShader5TextureGatherOffsetColor2DArrayCaseTest::getShaderParts(
1568 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
1569 {
1570 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
1571 }
1572 
1573 /** Check if texture array is required
1574  *
1575  *  @param out_is_texture_array Set to true if texture array is required, false otherwise
1576  **/
isTextureArray(bool & out_is_texture_array)1577 void GPUShader5TextureGatherOffsetColor2DArrayCaseTest::isTextureArray(bool& out_is_texture_array)
1578 {
1579 	out_is_texture_array = true;
1580 }
1581 
1582 /** Constructor
1583  *
1584  * @param context       Test context
1585  * @param name          Test case's name
1586  * @param description   Test case's description
1587  **/
GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1588 GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(
1589 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1590 	: GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1591 {
1592 	/* Nothing to be done here */
1593 }
1594 
1595 /** Get wrap mode for texture
1596  *
1597  *  @param out_wrap_mode Wrap mode
1598  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1599 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::getTextureWrapMode(glw::GLenum& out_wrap_mode)
1600 {
1601 	out_wrap_mode = m_glExtTokens.CLAMP_TO_BORDER;
1602 }
1603 
1604 /** Get parts of vertex shader
1605  *
1606  *  @param out_vertex_shader_parts Vector of vertex shader parts
1607  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1608 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::getShaderParts(
1609 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
1610 {
1611 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
1612 }
1613 
1614 /** Check if data captured for vertex at index are as expected
1615  *
1616  *  @param captured_data Instance of capturedVaryings for vertex at index
1617  *  @param index         Index of vertex
1618  *  @param texture_size  Size of texture
1619  *
1620  *  @return True  Results match expected values
1621  *          False Results do not match expected values
1622  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)1623 bool GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::checkResult(const CapturedVaryings& captured_data,
1624 																			unsigned int			index,
1625 																			unsigned int			texture_size)
1626 {
1627 	/* Get offsets for vertex */
1628 	glw::GLint x_offset;
1629 	glw::GLint y_offset;
1630 
1631 	getOffsets(x_offset, y_offset, index);
1632 
1633 	/* Storage for expected values of with_offset varyings */
1634 	glw::GLint expected_values_0[m_n_components_per_varying];
1635 	glw::GLint expected_values_1[m_n_components_per_varying];
1636 	glw::GLint expected_values_2[m_n_components_per_varying];
1637 	glw::GLint expected_values_3[m_n_components_per_varying];
1638 
1639 	/* Storage for with_offset values */
1640 	glw::GLint with_offset_0[m_n_components_per_varying];
1641 	glw::GLint with_offset_1[m_n_components_per_varying];
1642 	glw::GLint with_offset_2[m_n_components_per_varying];
1643 	glw::GLint with_offset_3[m_n_components_per_varying];
1644 
1645 	/* Index of first not clamped texel in without_offset set*/
1646 	int not_clamped_texel_index = -1;
1647 
1648 	/* X and Y offsets of texels in 2x2 set */
1649 	static const glw::GLint gather_offsets_x[] = { 0, 1, 1, 0 };
1650 	static const glw::GLint gather_offsets_y[] = { 1, 1, 0, 0 };
1651 
1652 	/* Find first not clamped texel in without_offset set */
1653 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1654 	{
1655 		if ((0 <= captured_data.without_offset_0[i]) && (0 <= captured_data.without_offset_1[i]))
1656 		{
1657 			not_clamped_texel_index = i;
1658 			break;
1659 		}
1660 	}
1661 
1662 	if (-1 == not_clamped_texel_index)
1663 	{
1664 		/* Log problem with sampler */
1665 		m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
1666 
1667 		logCoordinates(index);
1668 
1669 		m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1670 
1671 		m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1672 						   << tcu::TestLog::EndMessage;
1673 
1674 		logVaryings(captured_data);
1675 
1676 		m_testCtx.getLog() << tcu::TestLog::EndSection;
1677 
1678 		TCU_FAIL("Unexpected sampling results");
1679 	}
1680 
1681 	/* Fraction part of position for lower left texel without_offset set */
1682 	const glw::GLint fract_position_x =
1683 		captured_data.without_offset_0[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
1684 	const glw::GLint fract_position_y =
1685 		captured_data.without_offset_1[not_clamped_texel_index] - gather_offsets_y[not_clamped_texel_index];
1686 
1687 	/* Absolute position of lower left corner in without_offset set */
1688 	const glw::GLint absolute_position_x = fract_position_x + captured_data.without_offset_2[0] * (int)texture_size;
1689 	const glw::GLint absolute_position_y = fract_position_y + captured_data.without_offset_3[0] * (int)texture_size;
1690 
1691 	/* Calculate absolute position for all texels in without_offset set */
1692 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1693 	{
1694 		expected_values_0[i] = absolute_position_x + gather_offsets_x[i];
1695 		expected_values_1[i] = absolute_position_y + gather_offsets_y[i];
1696 		expected_values_2[i] = absolute_position_x + gather_offsets_x[i];
1697 		expected_values_3[i] = absolute_position_y + gather_offsets_y[i];
1698 	}
1699 
1700 	/* Modify "border color" to -1 in with_offset set */
1701 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1702 	{
1703 		with_offset_0[i] = 0 <= captured_data.with_offset_0[i] ? captured_data.with_offset_0[i] : -1;
1704 		with_offset_1[i] = 0 <= captured_data.with_offset_1[i] ? captured_data.with_offset_1[i] : -1;
1705 		with_offset_2[i] = 0 <= captured_data.with_offset_2[i] ? captured_data.with_offset_2[i] : -1;
1706 		with_offset_3[i] = 0 <= captured_data.with_offset_3[i] ? captured_data.with_offset_3[i] : -1;
1707 	}
1708 
1709 	/* Apply offsets to absolute positions of without_offset */
1710 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1711 	{
1712 		expected_values_0[i] += x_offset;
1713 		expected_values_1[i] += y_offset;
1714 		expected_values_2[i] += x_offset;
1715 		expected_values_3[i] += y_offset;
1716 
1717 		/* Set to -1, when point defined by expected_values_01 is outside of texture */
1718 		if ((0 > expected_values_0[i]) || (((glw::GLint)texture_size) <= expected_values_0[i]) ||
1719 			(0 > expected_values_1[i]) || (((glw::GLint)texture_size) <= expected_values_1[i]))
1720 		{
1721 			expected_values_0[i] = -1;
1722 			expected_values_1[i] = -1;
1723 		}
1724 
1725 		/* Set to -1, when point defined by expected_values_23 is outside of texture */
1726 		if ((0 > expected_values_2[i]) || (((glw::GLint)texture_size) <= expected_values_2[i]) ||
1727 			(0 > expected_values_3[i]) || (((glw::GLint)texture_size) <= expected_values_3[i]))
1728 		{
1729 			expected_values_2[i] = -1;
1730 			expected_values_3[i] = -1;
1731 		}
1732 	}
1733 
1734 	/* Verify that expected_values match those in with_offset varyings */
1735 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1736 	{
1737 		if ((with_offset_0[i] != expected_values_0[i]) || (with_offset_1[i] != expected_values_1[i]) ||
1738 			(with_offset_2[i] != expected_values_2[i]) || (with_offset_3[i] != expected_values_3[i]))
1739 		{
1740 			/* Log invalid results */
1741 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1742 
1743 			logCoordinates(index);
1744 
1745 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1746 
1747 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1748 							   << tcu::TestLog::EndMessage;
1749 
1750 			logVaryings(captured_data);
1751 
1752 			m_testCtx.getLog() << tcu::TestLog::EndSection;
1753 
1754 			/* Done */
1755 			return false;
1756 		}
1757 	}
1758 
1759 	/* Done */
1760 	return true;
1761 }
1762 
1763 /** Initializes GLES objects used during the test.
1764  *
1765  */
initTest(void)1766 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::initTest(void)
1767 {
1768 	/* Check if texture_border_clamp extension is supported */
1769 	if (!m_is_texture_border_clamp_supported)
1770 	{
1771 		throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
1772 	}
1773 
1774 	GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::initTest();
1775 }
1776 
1777 /** Constructor
1778  *
1779  * @param context       Test context
1780  * @param name          Test case's name
1781  * @param description   Test case's description
1782  **/
GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1783 GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(
1784 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1785 	: GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1786 {
1787 	/* Nothing to be done here */
1788 }
1789 
1790 /** Get wrap mode for texture
1791  *
1792  *  @param out_wrap_mode Wrap mode
1793  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1794 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::getTextureWrapMode(glw::GLenum& out_wrap_mode)
1795 {
1796 	out_wrap_mode = GL_CLAMP_TO_EDGE;
1797 }
1798 
1799 /** Get parts of vertex shader
1800  *
1801  *  @param out_vertex_shader_parts Vector of vertex shader parts
1802  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1803 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::getShaderParts(
1804 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
1805 {
1806 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
1807 }
1808 
1809 /** Clamps value to specified range
1810  *
1811  * @param value Value to be clamped
1812  * @param min   Minimum of range
1813  * @param max   Maximum of range
1814  **/
1815 template <typename T>
clamp(T & value,const T min,const T max)1816 void clamp(T& value, const T min, const T max)
1817 {
1818 	if (min > value)
1819 	{
1820 		value = min;
1821 	}
1822 	else if (max < value)
1823 	{
1824 		value = max;
1825 	}
1826 }
1827 
1828 /** Check if data captured for vertex at index are as expected
1829  *
1830  *  @param captured_data Instance of capturedVaryings for vertex at index
1831  *  @param index         Index of vertex
1832  *  @param texture_size Size of texture
1833  *
1834  *  @return True  Results match expected values
1835  *          False Results do not match expected values
1836  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)1837 bool GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::checkResult(const CapturedVaryings& captured_data,
1838 																		  unsigned int index, unsigned int texture_size)
1839 {
1840 	/* Get offsets for vertex */
1841 	glw::GLint x_offset;
1842 	glw::GLint y_offset;
1843 
1844 	getOffsets(x_offset, y_offset, index);
1845 
1846 	/* Storage for expected values of with_offset varyings */
1847 	glw::GLint expected_values_0[m_n_components_per_varying];
1848 	glw::GLint expected_values_1[m_n_components_per_varying];
1849 	glw::GLint expected_values_2[m_n_components_per_varying];
1850 	glw::GLint expected_values_3[m_n_components_per_varying];
1851 
1852 	/* Index of first not clamped texel in without_offset set*/
1853 	int not_clamped_texel_index = -1;
1854 
1855 	/* X and Y offsets of texels in 2x2 set */
1856 	static const glw::GLint gather_offsets_x[] = { 0, 1, 1, 0 };
1857 	static const glw::GLint gather_offsets_y[] = { 1, 1, 0, 0 };
1858 
1859 	/* Find first not clamped texel in without_offset set */
1860 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1861 	{
1862 		if ((0 <= captured_data.without_offset_0[i]) && (0 <= captured_data.without_offset_1[i]))
1863 		{
1864 			not_clamped_texel_index = i;
1865 			break;
1866 		}
1867 	}
1868 
1869 	if (-1 == not_clamped_texel_index)
1870 	{
1871 		/* Log problem with sampler */
1872 		m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
1873 
1874 		logCoordinates(index);
1875 
1876 		m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1877 
1878 		m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1879 						   << tcu::TestLog::EndMessage;
1880 
1881 		logVaryings(captured_data);
1882 
1883 		m_testCtx.getLog() << tcu::TestLog::EndSection;
1884 
1885 		TCU_FAIL("Unexpected sampling results");
1886 	}
1887 
1888 	/* Fraction part of position for lower left texel without_offset set */
1889 	const glw::GLint fract_position_x =
1890 		captured_data.without_offset_0[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
1891 	const glw::GLint fract_position_y =
1892 		captured_data.without_offset_1[not_clamped_texel_index] - gather_offsets_y[not_clamped_texel_index];
1893 
1894 	/* Absolute position of lower left corner in without_offset set */
1895 	const glw::GLint absolute_position_x = fract_position_x + captured_data.without_offset_2[0] * (int)texture_size;
1896 	const glw::GLint absolute_position_y = fract_position_y + captured_data.without_offset_3[0] * (int)texture_size;
1897 
1898 	/* Calculate absolute position for all texels in without_offset set */
1899 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1900 	{
1901 		expected_values_0[i] = absolute_position_x + gather_offsets_x[i];
1902 		expected_values_1[i] = absolute_position_y + gather_offsets_y[i];
1903 		expected_values_2[i] = absolute_position_x + gather_offsets_x[i];
1904 		expected_values_3[i] = absolute_position_y + gather_offsets_y[i];
1905 	}
1906 
1907 	/* Apply offsets to absolute positions of without_offset */
1908 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1909 	{
1910 		expected_values_0[i] += x_offset;
1911 		expected_values_1[i] += y_offset;
1912 		expected_values_2[i] += x_offset;
1913 		expected_values_3[i] += y_offset;
1914 
1915 		/* Clamp value when point is outside of texture */
1916 		clamp(expected_values_0[i], 0, ((glw::GLint)texture_size) - 1);
1917 		clamp(expected_values_1[i], 0, ((glw::GLint)texture_size) - 1);
1918 		clamp(expected_values_2[i], 0, ((glw::GLint)texture_size) - 1);
1919 		clamp(expected_values_3[i], 0, ((glw::GLint)texture_size) - 1);
1920 	}
1921 
1922 	/* Verify that expected_values match those in with_offset varyings */
1923 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1924 	{
1925 		if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
1926 			(captured_data.with_offset_1[i] != expected_values_1[i]) ||
1927 			(captured_data.with_offset_2[i] != expected_values_2[i]) ||
1928 			(captured_data.with_offset_3[i] != expected_values_3[i]))
1929 		{
1930 			/* Log invalid results */
1931 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1932 
1933 			logCoordinates(index);
1934 
1935 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1936 
1937 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1938 							   << tcu::TestLog::EndMessage;
1939 
1940 			logVaryings(captured_data);
1941 
1942 			m_testCtx.getLog() << tcu::TestLog::EndSection;
1943 
1944 			/* Done */
1945 			return false;
1946 		}
1947 	}
1948 
1949 	/* Done */
1950 	return true;
1951 }
1952 
1953 /** Constructor
1954  *
1955  * @param context       Test context
1956  * @param name          Test case's name
1957  * @param description   Test case's description
1958  **/
GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1959 GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(
1960 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
1961 	: GPUShader5TextureGatherOffsetColorTestBase(context, extParams, name, description)
1962 {
1963 	/* Nothing to be done here */
1964 }
1965 
1966 /** Get parts of vertex shader
1967  *
1968  *  @param out_vertex_shader_parts Vector of vertex shader parts
1969  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1970 void GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::getShaderParts(
1971 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
1972 {
1973 	std::stringstream stream;
1974 
1975 	stream << "           ivec2[4]( ivec2( " << m_min_texture_gather_offset << ", " << m_min_texture_gather_offset
1976 		   << "),\n";
1977 	stream << "                     ivec2( " << m_min_texture_gather_offset << ", " << m_max_texture_gather_offset
1978 		   << "),\n";
1979 	stream << "                     ivec2( " << m_max_texture_gather_offset << ", " << m_min_texture_gather_offset
1980 		   << "),\n";
1981 	stream << "                     ivec2( " << m_max_texture_gather_offset << ", " << m_max_texture_gather_offset
1982 		   << "));\n";
1983 
1984 	m_vertex_shader_code_offsets = stream.str();
1985 
1986 	out_vertex_shader_parts.push_back(m_vertex_shader_code_preamble);
1987 	out_vertex_shader_parts.push_back(m_vertex_shader_code_offsets.c_str());
1988 	out_vertex_shader_parts.push_back(m_vertex_shader_code_body);
1989 }
1990 
1991 /** Prepare test specific data, that will be used as vertex attributes
1992  *
1993  *  @param vertex_buffer_infos Vector of vertexBufferInfo instances
1994  **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)1995 void GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::prepareVertexBuffersData(
1996 	std::vector<VertexBufferInfo>& vertex_buffer_infos)
1997 {
1998 	DE_UNREF(vertex_buffer_infos);
1999 
2000 	/* Nothing to be done here */
2001 }
2002 
2003 /** Check if data captured for vertex at index are as expected
2004  *
2005  *  @param captured_data Instance of capturedVaryings for vertex at index
2006  *  @param index         Index of vertex
2007  *  @param texture_size  Size of texture
2008  *
2009  *  @return True  Results match expected values
2010  *          False Results do not match expected values
2011  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2012 bool GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::checkResult(const CapturedVaryings& captured_data,
2013 																	  unsigned int index, unsigned int tex_size)
2014 {
2015 	/* Signed int value has to be used with operator % in order to work as expected */
2016 	const glw::GLint texture_size = (glw::GLint)tex_size;
2017 
2018 	/* X and Y offsets */
2019 	glw::GLint x_offsets[m_n_components_per_varying] = {
2020 		m_min_texture_gather_offset, m_min_texture_gather_offset, m_max_texture_gather_offset,
2021 		m_max_texture_gather_offset,
2022 	};
2023 
2024 	glw::GLint y_offsets[m_n_components_per_varying] = {
2025 		m_min_texture_gather_offset, m_max_texture_gather_offset, m_min_texture_gather_offset,
2026 		m_max_texture_gather_offset,
2027 	};
2028 
2029 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2030 	{
2031 		/* Roll x offsets around left edge when negative */
2032 		if (0 > x_offsets[i])
2033 		{
2034 			x_offsets[i] = x_offsets[i] % texture_size;
2035 			x_offsets[i] += texture_size;
2036 		}
2037 
2038 		/* Roll y offsets around top edge when negative */
2039 		if (0 > y_offsets[i])
2040 		{
2041 			y_offsets[i] = y_offsets[i] % texture_size;
2042 			y_offsets[i] += texture_size;
2043 		}
2044 	}
2045 
2046 	/* Storage for expected values of with_offset varyings */
2047 	glw::GLint expected_values_0[m_n_components_per_varying];
2048 	glw::GLint expected_values_1[m_n_components_per_varying];
2049 	glw::GLint expected_values_2[m_n_components_per_varying];
2050 	glw::GLint expected_values_3[m_n_components_per_varying];
2051 
2052 	/* Calculate expected values of with_offset varyings */
2053 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2054 	{
2055 		expected_values_0[i] = ((x_offsets[i] + captured_data.without_offset_0[3]) % texture_size);
2056 		expected_values_1[i] = ((y_offsets[i] + captured_data.without_offset_1[3]) % texture_size);
2057 		expected_values_2[i] = ((x_offsets[i] + captured_data.without_offset_2[3]) % texture_size);
2058 		expected_values_3[i] = ((y_offsets[i] + captured_data.without_offset_3[3]) % texture_size);
2059 	}
2060 
2061 	/* Verify that expected_values match those in with_offset varyings */
2062 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2063 	{
2064 		if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
2065 			(captured_data.with_offset_1[i] != expected_values_1[i]) ||
2066 			(captured_data.with_offset_2[i] != expected_values_2[i]) ||
2067 			(captured_data.with_offset_3[i] != expected_values_3[i]))
2068 		{
2069 			/* Log invalid results */
2070 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2071 
2072 			logCoordinates(index);
2073 
2074 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2075 
2076 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: "
2077 							   << "(" << x_offsets[0] << ", " << y_offsets[0] << ") "
2078 							   << "(" << x_offsets[1] << ", " << y_offsets[1] << ") "
2079 							   << "(" << x_offsets[2] << ", " << y_offsets[2] << ") "
2080 							   << "(" << x_offsets[3] << ", " << y_offsets[3] << ") " << tcu::TestLog::EndMessage;
2081 
2082 			logVaryings(captured_data);
2083 
2084 			m_testCtx.getLog() << tcu::TestLog::EndSection;
2085 
2086 			/* Done */
2087 			return false;
2088 		}
2089 	}
2090 
2091 	/* Done */
2092 	return true;
2093 }
2094 
2095 /** Initializes GLES objects used during the test.
2096  *
2097  */
initTest(void)2098 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::initTest(void)
2099 {
2100 	/* Check if texture_border_clamp extension is supported */
2101 	if (!m_is_texture_border_clamp_supported)
2102 	{
2103 		throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
2104 	}
2105 
2106 	GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::initTest();
2107 }
2108 
2109 /** Constructor
2110  *
2111  * @param context       Test context
2112  * @param name          Test case's name
2113  * @param description   Test case's description
2114  **/
GPUShader5TextureGatherOffsetDepthTestBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)2115 GPUShader5TextureGatherOffsetDepthTestBase::GPUShader5TextureGatherOffsetDepthTestBase(Context&				context,
2116 																					   const ExtParameters& extParams,
2117 																					   const char*			name,
2118 																					   const char*			description)
2119 	: GPUShader5TextureGatherOffsetTestBase(context, extParams, name, description), m_n_varyings_per_vertex(0)
2120 {
2121 	/* Nothing to be done here */
2122 }
2123 
2124 /** Provides color that will be used as border color for "clamp to border" mode
2125  *
2126  * @param out_color Color
2127  **/
getBorderColor(glw::GLfloat out_color[4])2128 void GPUShader5TextureGatherOffsetDepthTestBase::getBorderColor(glw::GLfloat out_color[4])
2129 {
2130 	out_color[0] = 1.0f;
2131 	out_color[1] = 1.0f;
2132 	out_color[2] = 1.0f;
2133 	out_color[3] = 1.0f;
2134 }
2135 
2136 /** Provides informations required to create texture
2137  *
2138  *  @param out_width                   Size of texture
2139  *  @param out_texture_internal_format Internal format of texture
2140  *  @param out_texture_format          Format of texture
2141  *  @param out_texture_type            Type of texture
2142  *  @param out_bytes_per_pixel         Bytes per pixel
2143  **/
getTextureInfo(glw::GLuint & out_width,glw::GLenum & out_texture_internal_format,glw::GLenum & out_texture_format,glw::GLenum & out_texture_type,glw::GLuint & out_bytes_per_pixel)2144 void GPUShader5TextureGatherOffsetDepthTestBase::getTextureInfo(glw::GLuint& out_width,
2145 																glw::GLenum& out_texture_internal_format,
2146 																glw::GLenum& out_texture_format,
2147 																glw::GLenum& out_texture_type,
2148 																glw::GLuint& out_bytes_per_pixel)
2149 {
2150 	out_width					= m_texture_size;
2151 	out_texture_internal_format = GL_DEPTH_COMPONENT32F;
2152 	out_texture_format			= GL_DEPTH_COMPONENT;
2153 	out_texture_type			= GL_FLOAT;
2154 	out_bytes_per_pixel			= 1 * sizeof(glw::GLfloat); /* Depth * float */
2155 }
2156 
2157 /** Get wrap mode for texture
2158  *
2159  *  @param out_wrap_mode Wrap mode
2160  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2161 void GPUShader5TextureGatherOffsetDepthTestBase::getTextureWrapMode(glw::GLenum& out_wrap_mode)
2162 {
2163 	out_wrap_mode = GL_REPEAT;
2164 }
2165 
2166 /** Get size of buffer used as output from transform feedback and names of varyings
2167  *
2168  *  @param out_buffer_size       Size of buffer
2169  *  @param out_captured_varyings Names of varyings
2170  **/
getTransformFeedBackDetails(glw::GLuint & out_buffer_size,std::vector<const glw::GLchar * > & out_captured_varyings)2171 void GPUShader5TextureGatherOffsetDepthTestBase::getTransformFeedBackDetails(
2172 	glw::GLuint& out_buffer_size, std::vector<const glw::GLchar*>& out_captured_varyings)
2173 {
2174 	getVaryings(out_captured_varyings);
2175 
2176 	m_n_varyings_per_vertex = (unsigned int)out_captured_varyings.size();
2177 
2178 	out_buffer_size = static_cast<glw::GLuint>(m_n_vertices * m_n_varyings_per_vertex * m_n_components_per_varying *
2179 											   sizeof(glw::GLint));
2180 }
2181 
2182 /** Check if texture array is required
2183  *
2184  *  @param out_is_texture_array Set to true if texture array is required, false otherwise
2185  **/
isTextureArray(bool & out_is_texture_array)2186 void GPUShader5TextureGatherOffsetDepthTestBase::isTextureArray(bool& out_is_texture_array)
2187 {
2188 	out_is_texture_array = false;
2189 }
2190 
2191 /** Prepare texture data as expected by all cases in test 10.
2192  *  Each texel is assigned value of { x / texture_size }
2193  *
2194  *  @param data Storage space for texture data
2195  **/
prepareTextureData(glw::GLubyte * data)2196 void GPUShader5TextureGatherOffsetDepthTestBase::prepareTextureData(glw::GLubyte* data)
2197 {
2198 	/* Data pointer */
2199 	glw::GLfloat* texture_data = (glw::GLfloat*)data;
2200 
2201 	/* Constants */
2202 	const unsigned int n_components_per_pixel = 1;
2203 	const unsigned int line_size			  = n_components_per_pixel * m_texture_size;
2204 	const glw::GLfloat step					  = 1.0f / ((float)m_texture_size);
2205 
2206 	/* Prepare texture's data */
2207 	for (unsigned int y = 0; y < m_texture_size; ++y)
2208 	{
2209 		for (unsigned int x = 0; x < m_texture_size; ++x)
2210 		{
2211 			const glw::GLfloat depth		= ((float)x) * step;
2212 			const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
2213 
2214 			/* texel.depth = depth */
2215 			texture_data[pixel_offset] = depth;
2216 		}
2217 	}
2218 }
2219 
2220 /** Verification of results
2221  *
2222  *  @param result Pointer to data mapped from transform feedback buffer.
2223  *                Size of data is equal to buffer_size set by getTransformFeedbackBufferSize
2224  *
2225  *  @return true  Result match expected value
2226  *          false Result has wrong value
2227  **/
verifyResult(const void * result_data)2228 bool GPUShader5TextureGatherOffsetDepthTestBase::verifyResult(const void* result_data)
2229 {
2230 	/* All data stored in data are ints */
2231 	glw::GLint* results = (glw::GLint*)result_data;
2232 
2233 	/* Verification result */
2234 	bool result = true;
2235 
2236 	/* Constants for data offsets calculation */
2237 	const unsigned int bytes_per_varying			 = m_n_components_per_varying * sizeof(glw::GLfloat);
2238 	const unsigned int vertex_size_in_results_buffer = m_n_varyings_per_vertex * m_n_components_per_varying;
2239 	const unsigned int with_offset_offset			 = m_n_components_per_varying;
2240 	const unsigned int without_offset_offset		 = 0;
2241 	const unsigned int floor_tex_coord_offset		 = with_offset_offset + m_n_components_per_varying;
2242 
2243 	/* For each vertex */
2244 	for (unsigned int vertex = 0; vertex < m_n_vertices; ++vertex)
2245 	{
2246 		CapturedVaryings captured_data;
2247 
2248 		/* Pointers to all varyings for given vertex */
2249 		const glw::GLint* without_offset  = results + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
2250 		const glw::GLint* with_offset	 = results + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
2251 		const glw::GLint* floor_tex_coord = results + (vertex * vertex_size_in_results_buffer) + floor_tex_coord_offset;
2252 
2253 		/* Copy captured varyings to captured_data instance */
2254 		memcpy(captured_data.without_offset, without_offset, bytes_per_varying);
2255 		memcpy(captured_data.with_offset, with_offset, bytes_per_varying);
2256 		if (3 <= m_n_varyings_per_vertex)
2257 		{
2258 			memcpy(captured_data.floor_tex_coord, floor_tex_coord, bytes_per_varying);
2259 		}
2260 
2261 		/* Let child class check if result is ok */
2262 		const bool is_result_ok = checkResult(captured_data, vertex, m_texture_size);
2263 
2264 		/* Do not break on first error */
2265 		if (false == is_result_ok)
2266 		{
2267 			result = false;
2268 		}
2269 	}
2270 
2271 	/* Done */
2272 	return result;
2273 }
2274 
2275 /** Provides names of varyings to be captured by test
2276  *
2277  * @param out_captured_varyings Vector of varyings' names
2278  **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2279 void GPUShader5TextureGatherOffsetDepthTestBase::getVaryings(std::vector<const glw::GLchar*>& out_captured_varyings)
2280 {
2281 	out_captured_varyings.push_back("without_offset");
2282 	out_captured_varyings.push_back("with_offset");
2283 }
2284 
2285 /** Logs data captured varyings
2286  *
2287  *  @param varyings Instance of capturedVaryings to be logged
2288  **/
logVaryings(const CapturedVaryings & varyings)2289 void GPUShader5TextureGatherOffsetDepthTestBase::logVaryings(const CapturedVaryings& varyings)
2290 {
2291 	logArray(varyings.without_offset, m_n_components_per_varying, "Without offset: ");
2292 
2293 	logArray(varyings.with_offset, m_n_components_per_varying, "With offset: ");
2294 }
2295 
2296 /** Constructor
2297  *
2298  * @param context       Test context
2299  * @param name          Test case's name
2300  * @param description   Test case's description
2301  **/
GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2302 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(
2303 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2304 	: GPUShader5TextureGatherOffsetDepthTestBase(context, extParams, name, description)
2305 {
2306 	/* Nothing to be done here */
2307 }
2308 
2309 /** Get parts of vertex shader
2310  *
2311  *  @param out_vertex_shader_parts Vector of vertex shader parts
2312  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2313 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::getShaderParts(
2314 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
2315 {
2316 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
2317 }
2318 
2319 /** Prepare test specific data, that will be used as vertex attributes
2320  *
2321  *  @param vertex_buffer_infos Vector of vertexBufferInfo instances
2322  **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)2323 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::prepareVertexBuffersData(
2324 	std::vector<VertexBufferInfo>& vertex_buffer_infos)
2325 {
2326 	/* Constants for offsets and size of buffer */
2327 	const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
2328 
2329 	/* Limits used to generate offsets */
2330 	const glw::GLint min_ptgo = m_min_texture_gather_offset;
2331 	const glw::GLint max_ptgo = m_max_texture_gather_offset;
2332 
2333 	/* Storage for offsets */
2334 	m_offsets_buffer_data.resize(n_total_components);
2335 
2336 	/* Generate offsets */
2337 	for (unsigned int i = 0; i < n_total_components; ++i)
2338 	{
2339 		m_offsets_buffer_data[i] = (rand() % (max_ptgo - min_ptgo + 1)) + min_ptgo;
2340 	}
2341 
2342 	/* Setup offsets VB info */
2343 	VertexBufferInfo info;
2344 
2345 	info.attribute_name = m_offsets_attribute_name;
2346 	info.n_components   = m_n_offsets_components;
2347 	info.type			= GL_INT;
2348 	info.data			= &m_offsets_buffer_data[0];
2349 	info.data_size		= (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
2350 
2351 	/* Add VB info to vector */
2352 	vertex_buffer_infos.push_back(info);
2353 }
2354 
2355 /** Check if data captured for vertex at index are as expected
2356  *
2357  *  @param captured_data Instance of capturedVaryings for vertex at index
2358  *  @param index         Index of vertex
2359  *  @param texture_size  Size of texture
2360  *
2361  *  @return True  Results match expected values
2362  *          False Results do not match expected values
2363  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2364 bool GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::checkResult(const CapturedVaryings& captured_data,
2365 																	 unsigned int index, unsigned int tex_size)
2366 {
2367 	/* Signed int value has to be used with operator % in order to work as expected */
2368 	const glw::GLint texture_size = (glw::GLint)tex_size;
2369 
2370 	/* Get offsets for vertex */
2371 	glw::GLint x_offset;
2372 	glw::GLint y_offset;
2373 
2374 	getOffsets(x_offset, y_offset, index);
2375 
2376 	/* Roll x offsets around left edge when negative */
2377 	if (0 > x_offset)
2378 	{
2379 		x_offset = x_offset % texture_size;
2380 		x_offset += texture_size;
2381 	}
2382 
2383 	/* Storage for expected values of with_offset varyings */
2384 	glw::GLint expected_values[m_n_components_per_varying];
2385 
2386 	/* Calculate expected values of with_offset varyings */
2387 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2388 	{
2389 		expected_values[i] = ((x_offset + captured_data.without_offset[i]) % texture_size);
2390 	}
2391 
2392 	/* Verify that expected_values match those in with_offset varyings */
2393 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2394 	{
2395 		if (captured_data.with_offset[i] != expected_values[i])
2396 		{
2397 			/* Log invalid results */
2398 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2399 
2400 			logCoordinates(index);
2401 
2402 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2403 
2404 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2405 							   << tcu::TestLog::EndMessage;
2406 
2407 			logVaryings(captured_data);
2408 
2409 			m_testCtx.getLog() << tcu::TestLog::EndSection;
2410 
2411 			/* Done */
2412 			return false;
2413 		}
2414 	}
2415 
2416 	/* Done */
2417 	return true;
2418 }
2419 
2420 /** Get offsets for vertex at index
2421  *
2422  *  @param out_x_offset X offset
2423  *  @param out_y_offset Y offset
2424  *  @param index        Index of vertex
2425  **/
getOffsets(glw::GLint & out_x_offset,glw::GLint & out_y_offset,unsigned int index)2426 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::getOffsets(glw::GLint& out_x_offset, glw::GLint& out_y_offset,
2427 																	unsigned int index)
2428 {
2429 	out_x_offset = m_offsets_buffer_data[index * m_n_offsets_components + 0];
2430 	out_y_offset = m_offsets_buffer_data[index * m_n_offsets_components + 1];
2431 }
2432 
2433 /** Constructor
2434  *
2435  * @param context       Test context
2436  * @param name          Test case's name
2437  * @param description   Test case's description
2438  **/
GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2439 GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(
2440 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2441 	: GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2442 {
2443 	/* Nothing to be done here */
2444 }
2445 
2446 /** Get parts of vertex shader
2447  *
2448  *  @param out_vertex_shader_parts Vector of vertex shader parts
2449  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2450 void GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::getShaderParts(
2451 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
2452 {
2453 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
2454 }
2455 
2456 /** Prepare texture data as expected by case "Repeat the same test for Y axis." of test 10.
2457  *  Each texel is assigned value of { y / texture_size }
2458  *
2459  *  @param data Storage space for texture data
2460  **/
prepareTextureData(glw::GLubyte * data)2461 void GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::prepareTextureData(glw::GLubyte* data)
2462 {
2463 	/* Data pointer */
2464 	glw::GLfloat* texture_data = (glw::GLfloat*)data;
2465 
2466 	/* Get texture info from GPUShader5TextureGatherOffsetDepthTestBase */
2467 	glw::GLuint texture_size;
2468 	glw::GLenum ignored_texture_internal_format;
2469 	glw::GLenum ignored_texture_format;
2470 	glw::GLenum ignored_texture_type;
2471 	glw::GLuint ignored_bytes_per_pixel;
2472 
2473 	getTextureInfo(texture_size, ignored_texture_internal_format, ignored_texture_format, ignored_texture_type,
2474 				   ignored_bytes_per_pixel);
2475 
2476 	/* Constants */
2477 	const unsigned int n_components_per_pixel = 1;
2478 	const unsigned int line_size			  = n_components_per_pixel * texture_size;
2479 	const glw::GLfloat step					  = 1.0f / ((float)texture_size);
2480 
2481 	/* Prepare texture's data */
2482 	for (unsigned int y = 0; y < texture_size; ++y)
2483 	{
2484 		const glw::GLfloat depth = ((float)y) * step;
2485 
2486 		for (unsigned int x = 0; x < texture_size; ++x)
2487 		{
2488 			const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
2489 
2490 			/* texel.depth = depth */
2491 			texture_data[pixel_offset] = depth;
2492 		}
2493 	}
2494 }
2495 
2496 /** Check if data captured for vertex at index are as expected
2497  *
2498  *  @param captured_data Instance of capturedVaryings for vertex at index
2499  *  @param index         Index of vertex
2500  *  @param texture_size  Size of texture
2501  *
2502  *  @return True  Results match expected values
2503  *          False Results do not match expected values
2504  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2505 bool GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::checkResult(const CapturedVaryings& captured_data,
2506 																	  unsigned int index, unsigned int tex_size)
2507 {
2508 	/* Signed int value has to be used with operator % in order to work as expected */
2509 	const glw::GLint texture_size = (glw::GLint)tex_size;
2510 
2511 	/* Get offsets for vertex */
2512 	glw::GLint x_offset;
2513 	glw::GLint y_offset;
2514 
2515 	getOffsets(x_offset, y_offset, index);
2516 
2517 	/* Roll y offsets around left edge when negative */
2518 	if (0 > y_offset)
2519 	{
2520 		y_offset = y_offset % texture_size;
2521 		y_offset += texture_size;
2522 	}
2523 
2524 	/* Storage for expected values of with_offset varyings */
2525 	glw::GLint expected_values[m_n_components_per_varying];
2526 
2527 	/* Calculate expected values of with_offset varyings */
2528 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2529 	{
2530 		expected_values[i] = ((y_offset + captured_data.without_offset[i]) % texture_size);
2531 	}
2532 
2533 	/* Verify that expected_values match those in with_offset varyings */
2534 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2535 	{
2536 		if (captured_data.with_offset[i] != expected_values[i])
2537 		{
2538 			/* Log invalid results */
2539 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2540 
2541 			logCoordinates(index);
2542 
2543 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2544 
2545 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2546 							   << tcu::TestLog::EndMessage;
2547 
2548 			logVaryings(captured_data);
2549 
2550 			m_testCtx.getLog() << tcu::TestLog::EndSection;
2551 
2552 			/* Done */
2553 			return false;
2554 		}
2555 	}
2556 
2557 	/* Done */
2558 	return true;
2559 }
2560 
2561 /** Constructor
2562  *
2563  * @param context       Test context
2564  * @param name          Test case's name
2565  * @param description   Test case's description
2566  **/
GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2567 GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(
2568 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2569 	: GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2570 {
2571 	/* Nothing to be done here */
2572 }
2573 
2574 /** Get parts of vertex shader
2575  *
2576  *  @param out_vertex_shader_parts Vector of vertex shader parts
2577  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2578 void GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::getShaderParts(
2579 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
2580 {
2581 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
2582 }
2583 
2584 /** Check if texture array is required
2585  *
2586  *  @param out_is_texture_array Set to true if texture array is required, false otherwise
2587  **/
isTextureArray(bool & out_is_texture_array)2588 void GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::isTextureArray(bool& out_is_texture_array)
2589 {
2590 	out_is_texture_array = true;
2591 }
2592 
2593 /** Constructor
2594  *
2595  * @param context       Test context
2596  * @param name          Test case's name
2597  * @param description   Test case's description
2598  **/
GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2599 GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(
2600 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2601 	: GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2602 {
2603 	/* Nothing to be done here */
2604 }
2605 
2606 /** Get wrap mode for texture
2607  *
2608  *  @param out_wrap_mode Wrap mode
2609  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2610 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getTextureWrapMode(glw::GLenum& out_wrap_mode)
2611 {
2612 	out_wrap_mode = m_glExtTokens.CLAMP_TO_BORDER;
2613 }
2614 
2615 /** Provides names of varyings to be captured by test
2616  *
2617  * @param out_captured_varyings Vector of varyings' names
2618  **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2619 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getVaryings(
2620 	std::vector<const glw::GLchar*>& out_captured_varyings)
2621 {
2622 	out_captured_varyings.push_back("without_offset");
2623 	out_captured_varyings.push_back("with_offset");
2624 	out_captured_varyings.push_back("floor_tex_coord");
2625 }
2626 
2627 /** Get parts of vertex shader
2628  *
2629  *  @param out_vertex_shader_parts Vector of vertex shader parts
2630  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2631 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getShaderParts(
2632 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
2633 {
2634 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
2635 }
2636 
2637 /** Prepare test specific data, that will be used as vertex attributes
2638  *
2639  *  @param vertex_buffer_infos Vector of vertexBufferInfo instances
2640  **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)2641 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::prepareVertexBuffersData(
2642 	std::vector<VertexBufferInfo>& vertex_buffer_infos)
2643 {
2644 	/* Constats for offsets and size of buffer */
2645 	const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
2646 
2647 	/* Limits used to generate offsets */
2648 	const glw::GLint min_ptgo = m_min_texture_gather_offset;
2649 	const glw::GLint max_ptgo = m_max_texture_gather_offset;
2650 
2651 	/* Storage for offsets */
2652 	m_offsets_buffer_data.resize(n_total_components);
2653 
2654 	/* Generate offsets */
2655 	for (unsigned int i = 0; i < n_total_components; ++i)
2656 	{
2657 		if (0 == i % 2)
2658 		{
2659 			m_offsets_buffer_data[i] = (rand() % (max_ptgo - min_ptgo + 1)) + min_ptgo;
2660 		}
2661 		else
2662 		{
2663 			/* y offsets must be set to 0*/
2664 			m_offsets_buffer_data[i] = 0;
2665 		}
2666 	}
2667 
2668 	/* Setup offsets VB info */
2669 	VertexBufferInfo info;
2670 
2671 	info.attribute_name = m_offsets_attribute_name;
2672 	info.n_components   = m_n_offsets_components;
2673 	info.type			= GL_INT;
2674 	info.data			= &m_offsets_buffer_data[0];
2675 	info.data_size		= (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
2676 
2677 	/* Add VB info to vector */
2678 	vertex_buffer_infos.push_back(info);
2679 }
2680 
2681 /** Check if data captured for vertex at index are as expected
2682  *
2683  *  @param captured_data Instance of capturedVaryings for vertex at index
2684  *  @param index         Index of vertex
2685  *  @param texture_size  Size of texture
2686  *
2687  *  @return True  Results match expected values
2688  *          False Results do not match expected values
2689  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)2690 bool GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::checkResult(const CapturedVaryings& captured_data,
2691 																			unsigned int			index,
2692 																			unsigned int			texture_size)
2693 {
2694 	/* Get offsets for vertex */
2695 	glw::GLint x_offset;
2696 	glw::GLint y_offset;
2697 
2698 	getOffsets(x_offset, y_offset, index);
2699 
2700 	/* Storage for expected values of with_offset varyings */
2701 	glw::GLint expected_values[m_n_components_per_varying];
2702 
2703 	/* Index of first not clamped texel in without_offset set*/
2704 	int not_clamped_texel_index = -1;
2705 
2706 	/* X offsets of texels in 2x2 set */
2707 	static const glw::GLint gather_offsets_x[] = { 0, 1, 1, 0 };
2708 
2709 	/* Find first not clamped texel in without_offset set */
2710 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2711 	{
2712 		if ((int)texture_size != captured_data.without_offset[i])
2713 		{
2714 			not_clamped_texel_index = i;
2715 			break;
2716 		}
2717 	}
2718 
2719 	if (-1 == not_clamped_texel_index)
2720 	{
2721 		/* Log problem with sampler */
2722 		m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
2723 
2724 		logCoordinates(index);
2725 
2726 		m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2727 
2728 		m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2729 						   << tcu::TestLog::EndMessage;
2730 
2731 		logVaryings(captured_data);
2732 
2733 		m_testCtx.getLog() << tcu::TestLog::EndSection;
2734 
2735 		TCU_FAIL("Unexpected sampling results");
2736 	}
2737 
2738 	/* Fraction part of position for lower left texel without_offset set */
2739 	const glw::GLint fract_position_x =
2740 		captured_data.without_offset[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
2741 
2742 	/* Absolute position of lower left corner in without_offset set */
2743 	const glw::GLint absolute_position_x = fract_position_x + captured_data.floor_tex_coord[0] * (int)texture_size;
2744 
2745 	/* Wraping matrix */
2746 	glw::GLint wrap_matrix[4] = { 0 };
2747 
2748 	/* Index of value in without_offset set, that should be check for being clamped */
2749 	glw::GLint wrap_value_to_check_indices[4] = { 3, 2, 1, 0 };
2750 
2751 	/* Get value from without_offset to check for clamping */
2752 	glw::GLint wrap_value_to_check = captured_data.without_offset[wrap_value_to_check_indices[not_clamped_texel_index]];
2753 
2754 	/* Setup wrap_matrix */
2755 	switch (not_clamped_texel_index)
2756 	{
2757 	case 0:
2758 	case 1:
2759 		wrap_matrix[0] = 0;
2760 		wrap_matrix[1] = 0;
2761 
2762 		if ((glw::GLint)texture_size == wrap_value_to_check)
2763 		{
2764 			wrap_matrix[2] = -1;
2765 			wrap_matrix[3] = -1;
2766 		}
2767 		break;
2768 	case 2:
2769 	case 3:
2770 		wrap_matrix[2] = 0;
2771 		wrap_matrix[3] = 0;
2772 
2773 		if ((glw::GLint)texture_size == wrap_value_to_check)
2774 		{
2775 			wrap_matrix[0] = 1;
2776 			wrap_matrix[1] = 1;
2777 		}
2778 		break;
2779 	}
2780 
2781 	/* Apply integral part of texture coordinates to wrap_matrix */
2782 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2783 	{
2784 		wrap_matrix[i] += captured_data.floor_tex_coord[1];
2785 	}
2786 
2787 	/* For each texel in without_offset set calculate absolute position and apply offset */
2788 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2789 	{
2790 		expected_values[i] = absolute_position_x + gather_offsets_x[i];
2791 		expected_values[i] += x_offset;
2792 
2793 		/* Set to texture_size when point is outside of texture */
2794 		if ((0 > expected_values[i]) || (((glw::GLint)texture_size) < expected_values[i]) || (0 != wrap_matrix[i]))
2795 		{
2796 			expected_values[i] = texture_size;
2797 		}
2798 	}
2799 
2800 	/* Verify that expected_values match those in with_offset varyings */
2801 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2802 	{
2803 		if (captured_data.with_offset[i] != expected_values[i])
2804 		{
2805 			/* Log invalid results */
2806 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2807 
2808 			logCoordinates(index);
2809 
2810 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2811 
2812 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2813 							   << tcu::TestLog::EndMessage;
2814 
2815 			logVaryings(captured_data);
2816 
2817 			m_testCtx.getLog() << tcu::TestLog::EndSection;
2818 
2819 			/* Done */
2820 			return false;
2821 		}
2822 	}
2823 
2824 	/* Done */
2825 	return true;
2826 }
2827 
2828 /** Initializes GLES objects used during the test.
2829  *
2830  */
initTest(void)2831 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::initTest(void)
2832 {
2833 	/* Check if texture_border_clamp extension is supported */
2834 	if (!m_is_texture_border_clamp_supported)
2835 	{
2836 		throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
2837 	}
2838 
2839 	GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::initTest();
2840 }
2841 
2842 /** Constructor
2843  *
2844  * @param context       Test context
2845  * @param name          Test case's name
2846  * @param description   Test case's description
2847  **/
GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2848 GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(
2849 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
2850 	: GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2851 {
2852 	/* Nothing to be done here */
2853 }
2854 
2855 /** Get wrap mode for texture
2856  *
2857  *  @param out_wrap_mode Wrap mode
2858  **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2859 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getTextureWrapMode(glw::GLenum& out_wrap_mode)
2860 {
2861 	out_wrap_mode = GL_CLAMP_TO_EDGE;
2862 }
2863 
2864 /** Get parts of vertex shader
2865  *
2866  *  @param out_vertex_shader_parts Vector of vertex shader parts
2867  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2868 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getShaderParts(
2869 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
2870 {
2871 	out_vertex_shader_parts.push_back(m_vertex_shader_code);
2872 }
2873 
2874 /** Check if data captured for vertex at index are as expected
2875  *
2876  *  @param captured_data Instance of capturedVaryings for vertex at index
2877  *  @param index         Index of vertex
2878  *  @param texture_size  Size of texture
2879  *
2880  *  @return True  Results match expected values
2881  *          False Results do not match expected values
2882  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)2883 bool GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::checkResult(const CapturedVaryings& captured_data,
2884 																		  unsigned int index, unsigned int texture_size)
2885 {
2886 	/* Get offsets for vertex */
2887 	glw::GLint x_offset;
2888 	glw::GLint y_offset;
2889 
2890 	getOffsets(x_offset, y_offset, index);
2891 
2892 	/* Storage for expected values of with_offset varyings */
2893 	glw::GLint expected_values[m_n_components_per_varying];
2894 
2895 	/* Index of first not clamped texel in without_offset set*/
2896 	int not_clamped_texel_index = -1;
2897 
2898 	/* X offsets of texels in 2x2 set */
2899 	static const glw::GLint gather_offsets_x[] = { 0, 1, 1, 0 };
2900 
2901 	/* Find first not clamped texel in without_offset set */
2902 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2903 	{
2904 		if ((int)texture_size != captured_data.without_offset[i])
2905 		{
2906 			not_clamped_texel_index = i;
2907 			break;
2908 		}
2909 	}
2910 
2911 	if (-1 == not_clamped_texel_index)
2912 	{
2913 		/* Log problem with sampler */
2914 		m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
2915 
2916 		logCoordinates(index);
2917 
2918 		m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2919 
2920 		m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2921 						   << tcu::TestLog::EndMessage;
2922 
2923 		logVaryings(captured_data);
2924 
2925 		m_testCtx.getLog() << tcu::TestLog::EndSection;
2926 
2927 		TCU_FAIL("Unexpected sampling results");
2928 	}
2929 
2930 	/* Fraction part of position for lower left texel without_offset set */
2931 	const glw::GLint fract_position_x =
2932 		captured_data.without_offset[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
2933 
2934 	/* Absolute position of lower left corner in without_offset set */
2935 	const glw::GLint absolute_position_x = fract_position_x + captured_data.floor_tex_coord[0] * (int)texture_size;
2936 
2937 	/* Calculate expected values of with_offset varyings */
2938 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2939 	{
2940 		expected_values[i] = absolute_position_x + gather_offsets_x[i];
2941 		expected_values[i] += x_offset;
2942 
2943 		/* Clamp when point is outside of texture */
2944 		clamp(expected_values[i], 0, ((glw::GLint)texture_size) - 1);
2945 	}
2946 
2947 	/* Verify that expected_values match those in with_offset varyings */
2948 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2949 	{
2950 		if (captured_data.with_offset[i] != expected_values[i])
2951 		{
2952 			/* Log invalid results */
2953 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2954 
2955 			logCoordinates(index);
2956 
2957 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2958 
2959 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2960 							   << tcu::TestLog::EndMessage;
2961 
2962 			logVaryings(captured_data);
2963 
2964 			m_testCtx.getLog() << tcu::TestLog::EndSection;
2965 
2966 			/* Done */
2967 			return false;
2968 		}
2969 	}
2970 
2971 	/* Done */
2972 	return true;
2973 }
2974 
2975 /** Provides names of varyings to be captured by test
2976  *
2977  * @param out_captured_varyings Vector of varyings' names
2978  **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2979 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getVaryings(
2980 	std::vector<const glw::GLchar*>& out_captured_varyings)
2981 {
2982 	out_captured_varyings.push_back("without_offset");
2983 	out_captured_varyings.push_back("with_offset");
2984 	out_captured_varyings.push_back("floor_tex_coord");
2985 }
2986 
2987 /** Initializes GLES objects used during the test.
2988  *
2989  */
initTest(void)2990 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::initTest(void)
2991 {
2992 	/* Check if texture_border_clamp extension is supported */
2993 	if (!m_is_texture_border_clamp_supported)
2994 	{
2995 		throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
2996 	}
2997 
2998 	GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::initTest();
2999 }
3000 
3001 /** Constructor
3002  *
3003  * @param context       Test context
3004  * @param name          Test case's name
3005  * @param description   Test case's description
3006  **/
GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)3007 GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(
3008 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
3009 	: GPUShader5TextureGatherOffsetDepthTestBase(context, extParams, name, description)
3010 {
3011 	/* Nothing to be done here */
3012 }
3013 
3014 /** Get parts of vertex shader
3015  *
3016  *  @param out_vertex_shader_parts Vector of vertex shader parts
3017  **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)3018 void GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::getShaderParts(
3019 	std::vector<const glw::GLchar*>& out_vertex_shader_parts)
3020 {
3021 	std::stringstream stream;
3022 
3023 	stream << "           ivec2[4]( ivec2( " << m_min_texture_gather_offset << ", " << m_min_texture_gather_offset
3024 		   << "),\n";
3025 	stream << "                     ivec2( " << m_min_texture_gather_offset << ", " << m_max_texture_gather_offset
3026 		   << "),\n";
3027 	stream << "                     ivec2( " << m_max_texture_gather_offset << ", " << m_min_texture_gather_offset
3028 		   << "),\n";
3029 	stream << "                     ivec2( " << m_max_texture_gather_offset << ", " << m_max_texture_gather_offset
3030 		   << "));\n";
3031 
3032 	m_vertex_shader_code_offsets = stream.str();
3033 
3034 	out_vertex_shader_parts.push_back(m_vertex_shader_code_preamble);
3035 	out_vertex_shader_parts.push_back(m_vertex_shader_code_offsets.c_str());
3036 	out_vertex_shader_parts.push_back(m_vertex_shader_code_body);
3037 }
3038 
3039 /** Prepare test specific data, that will be used as vertex attributes
3040  *
3041  *  @param vertex_buffer_infos Vector of vertexBufferInfo instances
3042  **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)3043 void GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::prepareVertexBuffersData(
3044 	std::vector<VertexBufferInfo>& vertex_buffer_infos)
3045 {
3046 	DE_UNREF(vertex_buffer_infos);
3047 
3048 	/* Nothing to be done here */
3049 }
3050 
3051 /** Check if data captured for vertex at index are as expected
3052  *
3053  *  @param captured_data Instance of capturedVaryings for vertex at index
3054  *  @param index         Index of vertex
3055  *  @param texture_size  Size of texture
3056  *
3057  *  @return True  Results match expected values
3058  *          False Results do not match expected values
3059  **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)3060 bool GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::checkResult(const CapturedVaryings& captured_data,
3061 																	  unsigned int index, unsigned int tex_size)
3062 {
3063 	/* Signed int value has to be used with operator % in order to work as expected */
3064 	const glw::GLint texture_size = (glw::GLint)tex_size;
3065 
3066 	/* X and Y offsets */
3067 	glw::GLint x_offsets[m_n_components_per_varying] = {
3068 		m_min_texture_gather_offset, m_min_texture_gather_offset, m_max_texture_gather_offset,
3069 		m_max_texture_gather_offset,
3070 	};
3071 
3072 	glw::GLint y_offsets[m_n_components_per_varying] = {
3073 		m_min_texture_gather_offset, m_max_texture_gather_offset, m_min_texture_gather_offset,
3074 		m_max_texture_gather_offset,
3075 	};
3076 
3077 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3078 	{
3079 		/* Roll x offsets around left edge when negative */
3080 		if (0 > x_offsets[i])
3081 		{
3082 			x_offsets[i] = x_offsets[i] % texture_size;
3083 			x_offsets[i] += texture_size;
3084 		}
3085 	}
3086 
3087 	/* Storage for expected values of with_offset varyings */
3088 	glw::GLint expected_values[m_n_components_per_varying];
3089 
3090 	/* Calculate expected values of with_offset varyings */
3091 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3092 	{
3093 		expected_values[i] = ((x_offsets[i] + captured_data.without_offset[3]) % texture_size);
3094 	}
3095 
3096 	/* Verify that expected_values match those in with_offset varyings */
3097 	for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3098 	{
3099 		if (captured_data.with_offset[i] != expected_values[i])
3100 		{
3101 			/* Log invalid results */
3102 			m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
3103 
3104 			logCoordinates(index);
3105 
3106 			m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
3107 
3108 			m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: "
3109 							   << "(" << x_offsets[0] << ", " << y_offsets[0] << ") "
3110 							   << "(" << x_offsets[1] << ", " << y_offsets[1] << ") "
3111 							   << "(" << x_offsets[2] << ", " << y_offsets[2] << ") "
3112 							   << "(" << x_offsets[3] << ", " << y_offsets[3] << ") " << tcu::TestLog::EndMessage;
3113 
3114 			logVaryings(captured_data);
3115 
3116 			m_testCtx.getLog() << tcu::TestLog::EndSection;
3117 
3118 			/* Done */
3119 			return false;
3120 		}
3121 	}
3122 
3123 	/* Done */
3124 	return true;
3125 }
3126 
3127 } /* glcts */
3128