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