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)
1182 , m_n_varyings_per_vertex(0)
1183 {
1184 /* Nothing to be done here */
1185 }
1186
1187 /** Provides color that will be used as border color for "clamp to border" mode
1188 *
1189 * @param out_color Color
1190 **/
getBorderColor(glw::GLfloat out_color[4])1191 void GPUShader5TextureGatherOffsetColorTestBase::getBorderColor(glw::GLfloat out_color[4])
1192 {
1193 out_color[0] = -1.0f;
1194 out_color[1] = -1.0f;
1195 out_color[2] = -1.0f;
1196 out_color[3] = -1.0f;
1197 }
1198
1199 /** Provides informations required to create texture
1200 *
1201 * @param out_size Size of texture
1202 * @param out_texture_internal_format Internal format of texture
1203 * @param out_texture_format Format of texture
1204 * @param out_texture_type Type of texture
1205 * @param out_bytes_per_pixel Bytes per pixel
1206 **/
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)1207 void GPUShader5TextureGatherOffsetColorTestBase::getTextureInfo(glw::GLuint &out_size,
1208 glw::GLenum &out_texture_internal_format,
1209 glw::GLenum &out_texture_format,
1210 glw::GLenum &out_texture_type,
1211 glw::GLuint &out_bytes_per_pixel)
1212 {
1213 out_size = m_texture_size;
1214 out_texture_internal_format = GL_RGBA32I;
1215 out_texture_format = GL_RGBA_INTEGER;
1216 out_texture_type = GL_INT;
1217 out_bytes_per_pixel = 4 * sizeof(glw::GLint); /* RGBA * int */
1218 }
1219
1220 /** Get wrap mode for texture
1221 *
1222 * @param out_wrap_mode Wrap mode
1223 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1224 void GPUShader5TextureGatherOffsetColorTestBase::getTextureWrapMode(glw::GLenum &out_wrap_mode)
1225 {
1226 out_wrap_mode = GL_REPEAT;
1227 }
1228
1229 /** Get size of buffer used as output from transform feedback and names of varyings
1230 *
1231 * @param out_buffer_size Size of buffer
1232 * @param out_captured_varyings Names of varyings
1233 **/
getTransformFeedBackDetails(glw::GLuint & out_buffer_size,std::vector<const glw::GLchar * > & out_captured_varyings)1234 void GPUShader5TextureGatherOffsetColorTestBase::getTransformFeedBackDetails(
1235 glw::GLuint &out_buffer_size, std::vector<const glw::GLchar *> &out_captured_varyings)
1236 {
1237 out_captured_varyings.reserve(8);
1238 out_captured_varyings.push_back("without_offset_0");
1239 out_captured_varyings.push_back("with_offset_0");
1240 out_captured_varyings.push_back("without_offset_1");
1241 out_captured_varyings.push_back("with_offset_1");
1242 out_captured_varyings.push_back("without_offset_2");
1243 out_captured_varyings.push_back("with_offset_2");
1244 out_captured_varyings.push_back("without_offset_3");
1245 out_captured_varyings.push_back("with_offset_3");
1246
1247 m_n_varyings_per_vertex = (unsigned int)out_captured_varyings.size();
1248
1249 out_buffer_size = static_cast<glw::GLuint>(m_n_vertices * m_n_varyings_per_vertex * m_n_components_per_varying *
1250 sizeof(glw::GLint));
1251 }
1252
1253 /** Check if texture array is required
1254 *
1255 * @param out_is_texture_array Set to true if texture array is required, false otherwise
1256 **/
isTextureArray(bool & out_is_texture_array)1257 void GPUShader5TextureGatherOffsetColorTestBase::isTextureArray(bool &out_is_texture_array)
1258 {
1259 out_is_texture_array = false;
1260 }
1261
1262 /** Prepare texture data as expected by all cases in test 9.
1263 * Each texel is assigned {x, y, x, y}, where x and y are coordinates of texel.
1264 *
1265 * @param data Storage space for texture data
1266 **/
prepareTextureData(glw::GLubyte * data)1267 void GPUShader5TextureGatherOffsetColorTestBase::prepareTextureData(glw::GLubyte *data)
1268 {
1269 /* Data pointer */
1270 glw::GLint *texture_data = (glw::GLint *)data;
1271
1272 /* Constants */
1273 const unsigned int n_components_per_pixel = 4;
1274 const unsigned int line_size = n_components_per_pixel * m_texture_size;
1275
1276 /* Prepare texture's data */
1277 for (unsigned int y = 0; y < m_texture_size; ++y)
1278 {
1279 for (unsigned int x = 0; x < m_texture_size; ++x)
1280 {
1281 const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
1282
1283 /* texel.r = x, texel.g = y */
1284 texture_data[pixel_offset + 0] = x;
1285 texture_data[pixel_offset + 1] = y;
1286
1287 /* texel.b = x, texel.a = y */
1288 texture_data[pixel_offset + 2] = x;
1289 texture_data[pixel_offset + 3] = y;
1290 }
1291 }
1292 }
1293
1294 /** Verification of results
1295 *
1296 * @param result Pointer to data mapped from transform feedback buffer. Size of
1297 * data is equal to buffer_size set by getTransformFeedbackBufferSize
1298 *
1299 * @return true Result match expected value
1300 * false Result has wrong value
1301 **/
verifyResult(const void * result_data)1302 bool GPUShader5TextureGatherOffsetColorTestBase::verifyResult(const void *result_data)
1303 {
1304 /* All data stored in data are ints */
1305 glw::GLint *results = (glw::GLint *)result_data;
1306
1307 /* Verification result */
1308 bool result = true;
1309
1310 /* Constants for data offsets calculation */
1311 const unsigned int vertex_size_in_results_buffer = m_n_varyings_per_vertex * m_n_components_per_varying;
1312 const unsigned int bytes_per_varying = m_n_components_per_varying * sizeof(glw::GLint);
1313 const unsigned int vertex_varying_0_offset = 0;
1314 const unsigned int vertex_varying_1_offset = vertex_varying_0_offset + 2 * m_n_components_per_varying;
1315 const unsigned int vertex_varying_2_offset = vertex_varying_1_offset + 2 * m_n_components_per_varying;
1316 const unsigned int vertex_varying_3_offset = vertex_varying_2_offset + 2 * m_n_components_per_varying;
1317 const unsigned int with_offset_offset = m_n_components_per_varying;
1318 const unsigned int without_offset_offset = 0;
1319
1320 /* For each vertex */
1321 for (unsigned int vertex = 0; vertex < m_n_vertices; ++vertex)
1322 {
1323 CapturedVaryings captured_data;
1324
1325 /* Pointers to all varyings for given vertex */
1326 const glw::GLint *without_offset_0 =
1327 results + vertex_varying_0_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1328 const glw::GLint *with_offset_0 =
1329 results + vertex_varying_0_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1330
1331 const glw::GLint *without_offset_1 =
1332 results + vertex_varying_1_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1333 const glw::GLint *with_offset_1 =
1334 results + vertex_varying_1_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1335
1336 const glw::GLint *without_offset_2 =
1337 results + vertex_varying_2_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1338 const glw::GLint *with_offset_2 =
1339 results + vertex_varying_2_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1340
1341 const glw::GLint *without_offset_3 =
1342 results + vertex_varying_3_offset + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
1343 const glw::GLint *with_offset_3 =
1344 results + vertex_varying_3_offset + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
1345
1346 /* Copy captured varyings to captured_data instance */
1347 memcpy(captured_data.without_offset_0, without_offset_0, bytes_per_varying);
1348 memcpy(captured_data.without_offset_1, without_offset_1, bytes_per_varying);
1349 memcpy(captured_data.without_offset_2, without_offset_2, bytes_per_varying);
1350 memcpy(captured_data.without_offset_3, without_offset_3, bytes_per_varying);
1351
1352 memcpy(captured_data.with_offset_0, with_offset_0, bytes_per_varying);
1353 memcpy(captured_data.with_offset_1, with_offset_1, bytes_per_varying);
1354 memcpy(captured_data.with_offset_2, with_offset_2, bytes_per_varying);
1355 memcpy(captured_data.with_offset_3, with_offset_3, bytes_per_varying);
1356
1357 /* Let child class check if result is ok */
1358 const bool is_result_ok = checkResult(captured_data, vertex, m_texture_size);
1359
1360 /* Do not break on first error */
1361 if (false == is_result_ok)
1362 {
1363 result = false;
1364 }
1365 }
1366
1367 /* Done */
1368 return result;
1369 }
1370
1371 /** Logs data captured varyings
1372 *
1373 * @param varyings Instance of capturedVaryings to be logged
1374 **/
logVaryings(const CapturedVaryings & varyings)1375 void GPUShader5TextureGatherOffsetColorTestBase::logVaryings(const CapturedVaryings &varyings)
1376 {
1377 logArray(varyings.without_offset_0, m_n_components_per_varying, "Without offset X: ");
1378
1379 logArray(varyings.without_offset_1, m_n_components_per_varying, "Without offset Y: ");
1380
1381 logArray(varyings.without_offset_2, m_n_components_per_varying, "Without offset Z: ");
1382
1383 logArray(varyings.without_offset_3, m_n_components_per_varying, "Without offset W: ");
1384
1385 logArray(varyings.with_offset_0, m_n_components_per_varying, "With offset X: ");
1386
1387 logArray(varyings.with_offset_1, m_n_components_per_varying, "With offset Y: ");
1388
1389 logArray(varyings.with_offset_2, m_n_components_per_varying, "With offset Z: ");
1390
1391 logArray(varyings.with_offset_3, m_n_components_per_varying, "With offset W: ");
1392 }
1393
1394 /** Constructor
1395 *
1396 * @param context Test context
1397 * @param name Test case's name
1398 * @param description Test case's description
1399 **/
GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1400 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(
1401 Context &context, const ExtParameters &extParams, const char *name, const char *description)
1402 : GPUShader5TextureGatherOffsetColorTestBase(context, extParams, name, description)
1403 {
1404 /* Nothing to be done here */
1405 }
1406
1407 /** Get parts of vertex shader
1408 *
1409 * @param out_vertex_shader_parts Vector of vertex shader parts
1410 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1411 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::getShaderParts(
1412 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
1413 {
1414 out_vertex_shader_parts.push_back(m_vertex_shader_code);
1415 }
1416
1417 /** Prepare test specific data, that will be used as vertex attributes
1418 *
1419 * @param vertex_buffer_infos Vector of vertexBufferInfo instances
1420 **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)1421 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::prepareVertexBuffersData(
1422 std::vector<VertexBufferInfo> &vertex_buffer_infos)
1423 {
1424 /* Constats for offsets and size of buffer */
1425 const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
1426
1427 /* Limits used to generate offsets */
1428 const glw::GLint min_ptgo = m_min_texture_gather_offset;
1429 const glw::GLint max_ptgo = m_max_texture_gather_offset;
1430
1431 /* Storage for offsets */
1432 m_offsets_buffer_data.resize(n_total_components);
1433
1434 /* Set the seed for random number generator */
1435 randomSeed(1);
1436
1437 /* Generate offsets */
1438 for (unsigned int i = 0; i < n_total_components; ++i)
1439 {
1440 m_offsets_buffer_data[i] =
1441 static_cast<glw::GLint>(randomFormula(static_cast<glw::GLuint>(max_ptgo - min_ptgo + 1))) + min_ptgo;
1442 }
1443
1444 /* Setup offsets VB info */
1445 VertexBufferInfo info;
1446
1447 info.attribute_name = m_offsets_attribute_name;
1448 info.n_components = m_n_offsets_components;
1449 info.type = GL_INT;
1450 info.data = &m_offsets_buffer_data[0];
1451 info.data_size = (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
1452
1453 /* Add VB info to vector */
1454 vertex_buffer_infos.push_back(info);
1455 }
1456
1457 /** Check if data captured for vertex at index are as expected
1458 *
1459 * @param captured_data Instance of capturedVaryings for vertex at index
1460 * @param index Index of vertex
1461 * @param texture_size Size of texture
1462 *
1463 * @return True Results match expected values
1464 * False Results do not match expected values
1465 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)1466 bool GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::checkResult(const CapturedVaryings &captured_data,
1467 unsigned int index, unsigned int tex_size)
1468 {
1469 /* Signed int value has to be used with operator % in order to work as expected */
1470 const glw::GLint texture_size = (glw::GLint)tex_size;
1471
1472 /* Get offsets for vertex */
1473 glw::GLint x_offset;
1474 glw::GLint y_offset;
1475
1476 getOffsets(x_offset, y_offset, index);
1477
1478 /* Roll x offsets around left edge when negative */
1479 if (0 > x_offset)
1480 {
1481 x_offset = x_offset % texture_size;
1482 x_offset += texture_size;
1483 }
1484
1485 /* Roll y offsets around top edge when negative */
1486 if (0 > y_offset)
1487 {
1488 y_offset = y_offset % texture_size;
1489 y_offset += texture_size;
1490 }
1491
1492 /* Storage for expected values of with_offset varyings */
1493 glw::GLint expected_values_0[m_n_components_per_varying];
1494 glw::GLint expected_values_1[m_n_components_per_varying];
1495 glw::GLint expected_values_2[m_n_components_per_varying];
1496 glw::GLint expected_values_3[m_n_components_per_varying];
1497
1498 /* Calculate expected values of with_offset varyings */
1499 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1500 {
1501 expected_values_0[i] = ((x_offset + captured_data.without_offset_0[i]) % texture_size);
1502 expected_values_1[i] = ((y_offset + captured_data.without_offset_1[i]) % texture_size);
1503 expected_values_2[i] = ((x_offset + captured_data.without_offset_2[i]) % texture_size);
1504 expected_values_3[i] = ((y_offset + captured_data.without_offset_3[i]) % texture_size);
1505 }
1506
1507 /* Verify that expected_values match those in with_offset varyings */
1508 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1509 {
1510 if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
1511 (captured_data.with_offset_1[i] != expected_values_1[i]) ||
1512 (captured_data.with_offset_2[i] != expected_values_2[i]) ||
1513 (captured_data.with_offset_3[i] != expected_values_3[i]))
1514 {
1515 /* Log invalid results */
1516 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1517
1518 logCoordinates(index);
1519
1520 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1521
1522 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1523 << tcu::TestLog::EndMessage;
1524
1525 logVaryings(captured_data);
1526
1527 m_testCtx.getLog() << tcu::TestLog::EndSection;
1528
1529 /* Done */
1530 return false;
1531 }
1532 }
1533
1534 /* Done */
1535 return true;
1536 }
1537
1538 /** Get offsets for vertex at index
1539 *
1540 * @param out_x_offset X offset
1541 * @param out_y_offset Y offset
1542 * @param index Index of vertex
1543 **/
getOffsets(glw::GLint & out_x_offset,glw::GLint & out_y_offset,unsigned int index)1544 void GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::getOffsets(glw::GLint &out_x_offset, glw::GLint &out_y_offset,
1545 unsigned int index)
1546 {
1547 out_x_offset = m_offsets_buffer_data[index * m_n_offsets_components + 0];
1548 out_y_offset = m_offsets_buffer_data[index * m_n_offsets_components + 1];
1549 }
1550
1551 /** Constructor
1552 *
1553 * @param context Test context
1554 * @param name Test case's name
1555 * @param description Test case's description
1556 **/
GPUShader5TextureGatherOffsetColor2DArrayCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1557 GPUShader5TextureGatherOffsetColor2DArrayCaseTest::GPUShader5TextureGatherOffsetColor2DArrayCaseTest(
1558 Context &context, const ExtParameters &extParams, const char *name, const char *description)
1559 : GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1560 {
1561 /* Nothing to be done here */
1562 }
1563
1564 /** Get parts of vertex shader
1565 *
1566 * @param out_vertex_shader_parts Vector of vertex shader parts
1567 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1568 void GPUShader5TextureGatherOffsetColor2DArrayCaseTest::getShaderParts(
1569 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
1570 {
1571 out_vertex_shader_parts.push_back(m_vertex_shader_code);
1572 }
1573
1574 /** Check if texture array is required
1575 *
1576 * @param out_is_texture_array Set to true if texture array is required, false otherwise
1577 **/
isTextureArray(bool & out_is_texture_array)1578 void GPUShader5TextureGatherOffsetColor2DArrayCaseTest::isTextureArray(bool &out_is_texture_array)
1579 {
1580 out_is_texture_array = true;
1581 }
1582
1583 /** Constructor
1584 *
1585 * @param context Test context
1586 * @param name Test case's name
1587 * @param description Test case's description
1588 **/
GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1589 GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest(
1590 Context &context, const ExtParameters &extParams, const char *name, const char *description)
1591 : GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1592 {
1593 /* Nothing to be done here */
1594 }
1595
1596 /** Get wrap mode for texture
1597 *
1598 * @param out_wrap_mode Wrap mode
1599 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1600 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::getTextureWrapMode(glw::GLenum &out_wrap_mode)
1601 {
1602 out_wrap_mode = m_glExtTokens.CLAMP_TO_BORDER;
1603 }
1604
1605 /** Get parts of vertex shader
1606 *
1607 * @param out_vertex_shader_parts Vector of vertex shader parts
1608 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1609 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::getShaderParts(
1610 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
1611 {
1612 out_vertex_shader_parts.push_back(m_vertex_shader_code);
1613 }
1614
1615 /** Check if data captured for vertex at index are as expected
1616 *
1617 * @param captured_data Instance of capturedVaryings for vertex at index
1618 * @param index Index of vertex
1619 * @param texture_size Size of texture
1620 *
1621 * @return True Results match expected values
1622 * False Results do not match expected values
1623 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)1624 bool GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::checkResult(const CapturedVaryings &captured_data,
1625 unsigned int index,
1626 unsigned int texture_size)
1627 {
1628 /* Get offsets for vertex */
1629 glw::GLint x_offset;
1630 glw::GLint y_offset;
1631
1632 getOffsets(x_offset, y_offset, index);
1633
1634 /* Storage for expected values of with_offset varyings */
1635 glw::GLint expected_values_0[m_n_components_per_varying];
1636 glw::GLint expected_values_1[m_n_components_per_varying];
1637 glw::GLint expected_values_2[m_n_components_per_varying];
1638 glw::GLint expected_values_3[m_n_components_per_varying];
1639
1640 /* Storage for with_offset values */
1641 glw::GLint with_offset_0[m_n_components_per_varying];
1642 glw::GLint with_offset_1[m_n_components_per_varying];
1643 glw::GLint with_offset_2[m_n_components_per_varying];
1644 glw::GLint with_offset_3[m_n_components_per_varying];
1645
1646 /* Index of first not clamped texel in without_offset set*/
1647 int not_clamped_texel_index = -1;
1648
1649 /* X and Y offsets of texels in 2x2 set */
1650 static const glw::GLint gather_offsets_x[] = {0, 1, 1, 0};
1651 static const glw::GLint gather_offsets_y[] = {1, 1, 0, 0};
1652
1653 /* Find first not clamped texel in without_offset set */
1654 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1655 {
1656 if ((0 <= captured_data.without_offset_0[i]) && (0 <= captured_data.without_offset_1[i]))
1657 {
1658 not_clamped_texel_index = i;
1659 break;
1660 }
1661 }
1662
1663 if (-1 == not_clamped_texel_index)
1664 {
1665 /* Log problem with sampler */
1666 m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
1667
1668 logCoordinates(index);
1669
1670 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1671
1672 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1673 << tcu::TestLog::EndMessage;
1674
1675 logVaryings(captured_data);
1676
1677 m_testCtx.getLog() << tcu::TestLog::EndSection;
1678
1679 TCU_FAIL("Unexpected sampling results");
1680 }
1681
1682 /* Fraction part of position for lower left texel without_offset set */
1683 const glw::GLint fract_position_x =
1684 captured_data.without_offset_0[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
1685 const glw::GLint fract_position_y =
1686 captured_data.without_offset_1[not_clamped_texel_index] - gather_offsets_y[not_clamped_texel_index];
1687
1688 /* Absolute position of lower left corner in without_offset set */
1689 const glw::GLint absolute_position_x = fract_position_x + captured_data.without_offset_2[0] * (int)texture_size;
1690 const glw::GLint absolute_position_y = fract_position_y + captured_data.without_offset_3[0] * (int)texture_size;
1691
1692 /* Calculate absolute position for all texels in without_offset set */
1693 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1694 {
1695 expected_values_0[i] = absolute_position_x + gather_offsets_x[i];
1696 expected_values_1[i] = absolute_position_y + gather_offsets_y[i];
1697 expected_values_2[i] = absolute_position_x + gather_offsets_x[i];
1698 expected_values_3[i] = absolute_position_y + gather_offsets_y[i];
1699 }
1700
1701 /* Modify "border color" to -1 in with_offset set */
1702 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1703 {
1704 with_offset_0[i] = 0 <= captured_data.with_offset_0[i] ? captured_data.with_offset_0[i] : -1;
1705 with_offset_1[i] = 0 <= captured_data.with_offset_1[i] ? captured_data.with_offset_1[i] : -1;
1706 with_offset_2[i] = 0 <= captured_data.with_offset_2[i] ? captured_data.with_offset_2[i] : -1;
1707 with_offset_3[i] = 0 <= captured_data.with_offset_3[i] ? captured_data.with_offset_3[i] : -1;
1708 }
1709
1710 /* Apply offsets to absolute positions of without_offset */
1711 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1712 {
1713 expected_values_0[i] += x_offset;
1714 expected_values_1[i] += y_offset;
1715 expected_values_2[i] += x_offset;
1716 expected_values_3[i] += y_offset;
1717
1718 /* Set to -1, when point defined by expected_values_01 is outside of texture */
1719 if ((0 > expected_values_0[i]) || (((glw::GLint)texture_size) <= expected_values_0[i]) ||
1720 (0 > expected_values_1[i]) || (((glw::GLint)texture_size) <= expected_values_1[i]))
1721 {
1722 expected_values_0[i] = -1;
1723 expected_values_1[i] = -1;
1724 }
1725
1726 /* Set to -1, when point defined by expected_values_23 is outside of texture */
1727 if ((0 > expected_values_2[i]) || (((glw::GLint)texture_size) <= expected_values_2[i]) ||
1728 (0 > expected_values_3[i]) || (((glw::GLint)texture_size) <= expected_values_3[i]))
1729 {
1730 expected_values_2[i] = -1;
1731 expected_values_3[i] = -1;
1732 }
1733 }
1734
1735 /* Verify that expected_values match those in with_offset varyings */
1736 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1737 {
1738 if ((with_offset_0[i] != expected_values_0[i]) || (with_offset_1[i] != expected_values_1[i]) ||
1739 (with_offset_2[i] != expected_values_2[i]) || (with_offset_3[i] != expected_values_3[i]))
1740 {
1741 /* Log invalid results */
1742 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1743
1744 logCoordinates(index);
1745
1746 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1747
1748 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1749 << tcu::TestLog::EndMessage;
1750
1751 logVaryings(captured_data);
1752
1753 m_testCtx.getLog() << tcu::TestLog::EndSection;
1754
1755 /* Done */
1756 return false;
1757 }
1758 }
1759
1760 /* Done */
1761 return true;
1762 }
1763
1764 /** Initializes GLES objects used during the test.
1765 *
1766 */
initTest(void)1767 void GPUShader5TextureGatherOffsetColor2DClampToBorderCaseTest::initTest(void)
1768 {
1769 /* Check if texture_border_clamp extension is supported */
1770 if (!m_is_texture_border_clamp_supported)
1771 {
1772 throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
1773 }
1774
1775 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::initTest();
1776 }
1777
1778 /** Constructor
1779 *
1780 * @param context Test context
1781 * @param name Test case's name
1782 * @param description Test case's description
1783 **/
GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1784 GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest(
1785 Context &context, const ExtParameters &extParams, const char *name, const char *description)
1786 : GPUShader5TextureGatherOffsetColor2DRepeatCaseTest(context, extParams, name, description)
1787 {
1788 /* Nothing to be done here */
1789 }
1790
1791 /** Get wrap mode for texture
1792 *
1793 * @param out_wrap_mode Wrap mode
1794 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)1795 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::getTextureWrapMode(glw::GLenum &out_wrap_mode)
1796 {
1797 out_wrap_mode = GL_CLAMP_TO_EDGE;
1798 }
1799
1800 /** Get parts of vertex shader
1801 *
1802 * @param out_vertex_shader_parts Vector of vertex shader parts
1803 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1804 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::getShaderParts(
1805 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
1806 {
1807 out_vertex_shader_parts.push_back(m_vertex_shader_code);
1808 }
1809
1810 /** Clamps value to specified range
1811 *
1812 * @param value Value to be clamped
1813 * @param min Minimum of range
1814 * @param max Maximum of range
1815 **/
1816 template <typename T>
clamp(T & value,const T min,const T max)1817 void clamp(T &value, const T min, const T max)
1818 {
1819 if (min > value)
1820 {
1821 value = min;
1822 }
1823 else if (max < value)
1824 {
1825 value = max;
1826 }
1827 }
1828
1829 /** Check if data captured for vertex at index are as expected
1830 *
1831 * @param captured_data Instance of capturedVaryings for vertex at index
1832 * @param index Index of vertex
1833 * @param texture_size Size of texture
1834 *
1835 * @return True Results match expected values
1836 * False Results do not match expected values
1837 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)1838 bool GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::checkResult(const CapturedVaryings &captured_data,
1839 unsigned int index, unsigned int texture_size)
1840 {
1841 /* Get offsets for vertex */
1842 glw::GLint x_offset;
1843 glw::GLint y_offset;
1844
1845 getOffsets(x_offset, y_offset, index);
1846
1847 /* Storage for expected values of with_offset varyings */
1848 glw::GLint expected_values_0[m_n_components_per_varying];
1849 glw::GLint expected_values_1[m_n_components_per_varying];
1850 glw::GLint expected_values_2[m_n_components_per_varying];
1851 glw::GLint expected_values_3[m_n_components_per_varying];
1852
1853 /* Index of first not clamped texel in without_offset set*/
1854 int not_clamped_texel_index = -1;
1855
1856 /* X and Y offsets of texels in 2x2 set */
1857 static const glw::GLint gather_offsets_x[] = {0, 1, 1, 0};
1858 static const glw::GLint gather_offsets_y[] = {1, 1, 0, 0};
1859
1860 /* Find first not clamped texel in without_offset set */
1861 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1862 {
1863 if ((0 <= captured_data.without_offset_0[i]) && (0 <= captured_data.without_offset_1[i]))
1864 {
1865 not_clamped_texel_index = i;
1866 break;
1867 }
1868 }
1869
1870 if (-1 == not_clamped_texel_index)
1871 {
1872 /* Log problem with sampler */
1873 m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
1874
1875 logCoordinates(index);
1876
1877 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1878
1879 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1880 << tcu::TestLog::EndMessage;
1881
1882 logVaryings(captured_data);
1883
1884 m_testCtx.getLog() << tcu::TestLog::EndSection;
1885
1886 TCU_FAIL("Unexpected sampling results");
1887 }
1888
1889 /* Fraction part of position for lower left texel without_offset set */
1890 const glw::GLint fract_position_x =
1891 captured_data.without_offset_0[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
1892 const glw::GLint fract_position_y =
1893 captured_data.without_offset_1[not_clamped_texel_index] - gather_offsets_y[not_clamped_texel_index];
1894
1895 /* Absolute position of lower left corner in without_offset set */
1896 const glw::GLint absolute_position_x = fract_position_x + captured_data.without_offset_2[0] * (int)texture_size;
1897 const glw::GLint absolute_position_y = fract_position_y + captured_data.without_offset_3[0] * (int)texture_size;
1898
1899 /* Calculate absolute position for all texels in without_offset set */
1900 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1901 {
1902 expected_values_0[i] = absolute_position_x + gather_offsets_x[i];
1903 expected_values_1[i] = absolute_position_y + gather_offsets_y[i];
1904 expected_values_2[i] = absolute_position_x + gather_offsets_x[i];
1905 expected_values_3[i] = absolute_position_y + gather_offsets_y[i];
1906 }
1907
1908 /* Apply offsets to absolute positions of without_offset */
1909 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1910 {
1911 expected_values_0[i] += x_offset;
1912 expected_values_1[i] += y_offset;
1913 expected_values_2[i] += x_offset;
1914 expected_values_3[i] += y_offset;
1915
1916 /* Clamp value when point is outside of texture */
1917 clamp(expected_values_0[i], 0, ((glw::GLint)texture_size) - 1);
1918 clamp(expected_values_1[i], 0, ((glw::GLint)texture_size) - 1);
1919 clamp(expected_values_2[i], 0, ((glw::GLint)texture_size) - 1);
1920 clamp(expected_values_3[i], 0, ((glw::GLint)texture_size) - 1);
1921 }
1922
1923 /* Verify that expected_values match those in with_offset varyings */
1924 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
1925 {
1926 if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
1927 (captured_data.with_offset_1[i] != expected_values_1[i]) ||
1928 (captured_data.with_offset_2[i] != expected_values_2[i]) ||
1929 (captured_data.with_offset_3[i] != expected_values_3[i]))
1930 {
1931 /* Log invalid results */
1932 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
1933
1934 logCoordinates(index);
1935
1936 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
1937
1938 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
1939 << tcu::TestLog::EndMessage;
1940
1941 logVaryings(captured_data);
1942
1943 m_testCtx.getLog() << tcu::TestLog::EndSection;
1944
1945 /* Done */
1946 return false;
1947 }
1948 }
1949
1950 /* Done */
1951 return true;
1952 }
1953
1954 /** Constructor
1955 *
1956 * @param context Test context
1957 * @param name Test case's name
1958 * @param description Test case's description
1959 **/
GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1960 GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest(
1961 Context &context, const ExtParameters &extParams, const char *name, const char *description)
1962 : GPUShader5TextureGatherOffsetColorTestBase(context, extParams, name, description)
1963 {
1964 /* Nothing to be done here */
1965 }
1966
1967 /** Get parts of vertex shader
1968 *
1969 * @param out_vertex_shader_parts Vector of vertex shader parts
1970 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)1971 void GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::getShaderParts(
1972 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
1973 {
1974 std::stringstream stream;
1975
1976 stream << " ivec2[4]( ivec2( " << m_min_texture_gather_offset << ", " << m_min_texture_gather_offset
1977 << "),\n";
1978 stream << " ivec2( " << m_min_texture_gather_offset << ", " << m_max_texture_gather_offset
1979 << "),\n";
1980 stream << " ivec2( " << m_max_texture_gather_offset << ", " << m_min_texture_gather_offset
1981 << "),\n";
1982 stream << " ivec2( " << m_max_texture_gather_offset << ", " << m_max_texture_gather_offset
1983 << "));\n";
1984
1985 m_vertex_shader_code_offsets = stream.str();
1986
1987 out_vertex_shader_parts.push_back(m_vertex_shader_code_preamble);
1988 out_vertex_shader_parts.push_back(m_vertex_shader_code_offsets.c_str());
1989 out_vertex_shader_parts.push_back(m_vertex_shader_code_body);
1990 }
1991
1992 /** Prepare test specific data, that will be used as vertex attributes
1993 *
1994 * @param vertex_buffer_infos Vector of vertexBufferInfo instances
1995 **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)1996 void GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::prepareVertexBuffersData(
1997 std::vector<VertexBufferInfo> &vertex_buffer_infos)
1998 {
1999 DE_UNREF(vertex_buffer_infos);
2000
2001 /* Nothing to be done here */
2002 }
2003
2004 /** Check if data captured for vertex at index are as expected
2005 *
2006 * @param captured_data Instance of capturedVaryings for vertex at index
2007 * @param index Index of vertex
2008 * @param texture_size Size of texture
2009 *
2010 * @return True Results match expected values
2011 * False Results do not match expected values
2012 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2013 bool GPUShader5TextureGatherOffsetColor2DOffsetsCaseTest::checkResult(const CapturedVaryings &captured_data,
2014 unsigned int index, unsigned int tex_size)
2015 {
2016 /* Signed int value has to be used with operator % in order to work as expected */
2017 const glw::GLint texture_size = (glw::GLint)tex_size;
2018
2019 /* X and Y offsets */
2020 glw::GLint x_offsets[m_n_components_per_varying] = {
2021 m_min_texture_gather_offset,
2022 m_min_texture_gather_offset,
2023 m_max_texture_gather_offset,
2024 m_max_texture_gather_offset,
2025 };
2026
2027 glw::GLint y_offsets[m_n_components_per_varying] = {
2028 m_min_texture_gather_offset,
2029 m_max_texture_gather_offset,
2030 m_min_texture_gather_offset,
2031 m_max_texture_gather_offset,
2032 };
2033
2034 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2035 {
2036 /* Roll x offsets around left edge when negative */
2037 if (0 > x_offsets[i])
2038 {
2039 x_offsets[i] = x_offsets[i] % texture_size;
2040 x_offsets[i] += texture_size;
2041 }
2042
2043 /* Roll y offsets around top edge when negative */
2044 if (0 > y_offsets[i])
2045 {
2046 y_offsets[i] = y_offsets[i] % texture_size;
2047 y_offsets[i] += texture_size;
2048 }
2049 }
2050
2051 /* Storage for expected values of with_offset varyings */
2052 glw::GLint expected_values_0[m_n_components_per_varying];
2053 glw::GLint expected_values_1[m_n_components_per_varying];
2054 glw::GLint expected_values_2[m_n_components_per_varying];
2055 glw::GLint expected_values_3[m_n_components_per_varying];
2056
2057 /* Calculate expected values of with_offset varyings */
2058 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2059 {
2060 expected_values_0[i] = ((x_offsets[i] + captured_data.without_offset_0[3]) % texture_size);
2061 expected_values_1[i] = ((y_offsets[i] + captured_data.without_offset_1[3]) % texture_size);
2062 expected_values_2[i] = ((x_offsets[i] + captured_data.without_offset_2[3]) % texture_size);
2063 expected_values_3[i] = ((y_offsets[i] + captured_data.without_offset_3[3]) % texture_size);
2064 }
2065
2066 /* Verify that expected_values match those in with_offset varyings */
2067 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2068 {
2069 if ((captured_data.with_offset_0[i] != expected_values_0[i]) ||
2070 (captured_data.with_offset_1[i] != expected_values_1[i]) ||
2071 (captured_data.with_offset_2[i] != expected_values_2[i]) ||
2072 (captured_data.with_offset_3[i] != expected_values_3[i]))
2073 {
2074 /* Log invalid results */
2075 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2076
2077 logCoordinates(index);
2078
2079 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2080
2081 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: "
2082 << "(" << x_offsets[0] << ", " << y_offsets[0] << ") "
2083 << "(" << x_offsets[1] << ", " << y_offsets[1] << ") "
2084 << "(" << x_offsets[2] << ", " << y_offsets[2] << ") "
2085 << "(" << x_offsets[3] << ", " << y_offsets[3] << ") " << tcu::TestLog::EndMessage;
2086
2087 logVaryings(captured_data);
2088
2089 m_testCtx.getLog() << tcu::TestLog::EndSection;
2090
2091 /* Done */
2092 return false;
2093 }
2094 }
2095
2096 /* Done */
2097 return true;
2098 }
2099
2100 /** Initializes GLES objects used during the test.
2101 *
2102 */
initTest(void)2103 void GPUShader5TextureGatherOffsetColor2DClampToEdgeCaseTest::initTest(void)
2104 {
2105 /* Check if texture_border_clamp extension is supported */
2106 if (!m_is_texture_border_clamp_supported)
2107 {
2108 throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
2109 }
2110
2111 GPUShader5TextureGatherOffsetColor2DRepeatCaseTest::initTest();
2112 }
2113
2114 /** Constructor
2115 *
2116 * @param context Test context
2117 * @param name Test case's name
2118 * @param description Test case's description
2119 **/
GPUShader5TextureGatherOffsetDepthTestBase(Context & context,const ExtParameters & extParams,const char * name,const char * description)2120 GPUShader5TextureGatherOffsetDepthTestBase::GPUShader5TextureGatherOffsetDepthTestBase(Context &context,
2121 const ExtParameters &extParams,
2122 const char *name,
2123 const char *description)
2124 : GPUShader5TextureGatherOffsetTestBase(context, extParams, name, description)
2125 , m_n_varyings_per_vertex(0)
2126 {
2127 /* Nothing to be done here */
2128 }
2129
2130 /** Provides color that will be used as border color for "clamp to border" mode
2131 *
2132 * @param out_color Color
2133 **/
getBorderColor(glw::GLfloat out_color[4])2134 void GPUShader5TextureGatherOffsetDepthTestBase::getBorderColor(glw::GLfloat out_color[4])
2135 {
2136 out_color[0] = 1.0f;
2137 out_color[1] = 1.0f;
2138 out_color[2] = 1.0f;
2139 out_color[3] = 1.0f;
2140 }
2141
2142 /** Provides informations required to create texture
2143 *
2144 * @param out_width Size of texture
2145 * @param out_texture_internal_format Internal format of texture
2146 * @param out_texture_format Format of texture
2147 * @param out_texture_type Type of texture
2148 * @param out_bytes_per_pixel Bytes per pixel
2149 **/
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)2150 void GPUShader5TextureGatherOffsetDepthTestBase::getTextureInfo(glw::GLuint &out_width,
2151 glw::GLenum &out_texture_internal_format,
2152 glw::GLenum &out_texture_format,
2153 glw::GLenum &out_texture_type,
2154 glw::GLuint &out_bytes_per_pixel)
2155 {
2156 out_width = m_texture_size;
2157 out_texture_internal_format = GL_DEPTH_COMPONENT32F;
2158 out_texture_format = GL_DEPTH_COMPONENT;
2159 out_texture_type = GL_FLOAT;
2160 out_bytes_per_pixel = 1 * sizeof(glw::GLfloat); /* Depth * float */
2161 }
2162
2163 /** Get wrap mode for texture
2164 *
2165 * @param out_wrap_mode Wrap mode
2166 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2167 void GPUShader5TextureGatherOffsetDepthTestBase::getTextureWrapMode(glw::GLenum &out_wrap_mode)
2168 {
2169 out_wrap_mode = GL_REPEAT;
2170 }
2171
2172 /** Get size of buffer used as output from transform feedback and names of varyings
2173 *
2174 * @param out_buffer_size Size of buffer
2175 * @param out_captured_varyings Names of varyings
2176 **/
getTransformFeedBackDetails(glw::GLuint & out_buffer_size,std::vector<const glw::GLchar * > & out_captured_varyings)2177 void GPUShader5TextureGatherOffsetDepthTestBase::getTransformFeedBackDetails(
2178 glw::GLuint &out_buffer_size, std::vector<const glw::GLchar *> &out_captured_varyings)
2179 {
2180 getVaryings(out_captured_varyings);
2181
2182 m_n_varyings_per_vertex = (unsigned int)out_captured_varyings.size();
2183
2184 out_buffer_size = static_cast<glw::GLuint>(m_n_vertices * m_n_varyings_per_vertex * m_n_components_per_varying *
2185 sizeof(glw::GLint));
2186 }
2187
2188 /** Check if texture array is required
2189 *
2190 * @param out_is_texture_array Set to true if texture array is required, false otherwise
2191 **/
isTextureArray(bool & out_is_texture_array)2192 void GPUShader5TextureGatherOffsetDepthTestBase::isTextureArray(bool &out_is_texture_array)
2193 {
2194 out_is_texture_array = false;
2195 }
2196
2197 /** Prepare texture data as expected by all cases in test 10.
2198 * Each texel is assigned value of { x / texture_size }
2199 *
2200 * @param data Storage space for texture data
2201 **/
prepareTextureData(glw::GLubyte * data)2202 void GPUShader5TextureGatherOffsetDepthTestBase::prepareTextureData(glw::GLubyte *data)
2203 {
2204 /* Data pointer */
2205 glw::GLfloat *texture_data = (glw::GLfloat *)data;
2206
2207 /* Constants */
2208 const unsigned int n_components_per_pixel = 1;
2209 const unsigned int line_size = n_components_per_pixel * m_texture_size;
2210 const glw::GLfloat step = 1.0f / ((float)m_texture_size);
2211
2212 /* Prepare texture's data */
2213 for (unsigned int y = 0; y < m_texture_size; ++y)
2214 {
2215 for (unsigned int x = 0; x < m_texture_size; ++x)
2216 {
2217 const glw::GLfloat depth = ((float)x) * step;
2218 const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
2219
2220 /* texel.depth = depth */
2221 texture_data[pixel_offset] = depth;
2222 }
2223 }
2224 }
2225
2226 /** Verification of results
2227 *
2228 * @param result Pointer to data mapped from transform feedback buffer.
2229 * Size of data is equal to buffer_size set by getTransformFeedbackBufferSize
2230 *
2231 * @return true Result match expected value
2232 * false Result has wrong value
2233 **/
verifyResult(const void * result_data)2234 bool GPUShader5TextureGatherOffsetDepthTestBase::verifyResult(const void *result_data)
2235 {
2236 /* All data stored in data are ints */
2237 glw::GLint *results = (glw::GLint *)result_data;
2238
2239 /* Verification result */
2240 bool result = true;
2241
2242 /* Constants for data offsets calculation */
2243 const unsigned int bytes_per_varying = m_n_components_per_varying * sizeof(glw::GLfloat);
2244 const unsigned int vertex_size_in_results_buffer = m_n_varyings_per_vertex * m_n_components_per_varying;
2245 const unsigned int with_offset_offset = m_n_components_per_varying;
2246 const unsigned int without_offset_offset = 0;
2247 const unsigned int floor_tex_coord_offset = with_offset_offset + m_n_components_per_varying;
2248
2249 /* For each vertex */
2250 for (unsigned int vertex = 0; vertex < m_n_vertices; ++vertex)
2251 {
2252 CapturedVaryings captured_data;
2253
2254 /* Pointers to all varyings for given vertex */
2255 const glw::GLint *without_offset = results + (vertex * vertex_size_in_results_buffer) + without_offset_offset;
2256 const glw::GLint *with_offset = results + (vertex * vertex_size_in_results_buffer) + with_offset_offset;
2257 const glw::GLint *floor_tex_coord = results + (vertex * vertex_size_in_results_buffer) + floor_tex_coord_offset;
2258
2259 /* Copy captured varyings to captured_data instance */
2260 memcpy(captured_data.without_offset, without_offset, bytes_per_varying);
2261 memcpy(captured_data.with_offset, with_offset, bytes_per_varying);
2262 if (3 <= m_n_varyings_per_vertex)
2263 {
2264 memcpy(captured_data.floor_tex_coord, floor_tex_coord, bytes_per_varying);
2265 }
2266
2267 /* Let child class check if result is ok */
2268 const bool is_result_ok = checkResult(captured_data, vertex, m_texture_size);
2269
2270 /* Do not break on first error */
2271 if (false == is_result_ok)
2272 {
2273 result = false;
2274 }
2275 }
2276
2277 /* Done */
2278 return result;
2279 }
2280
2281 /** Provides names of varyings to be captured by test
2282 *
2283 * @param out_captured_varyings Vector of varyings' names
2284 **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2285 void GPUShader5TextureGatherOffsetDepthTestBase::getVaryings(std::vector<const glw::GLchar *> &out_captured_varyings)
2286 {
2287 out_captured_varyings.push_back("without_offset");
2288 out_captured_varyings.push_back("with_offset");
2289 }
2290
2291 /** Logs data captured varyings
2292 *
2293 * @param varyings Instance of capturedVaryings to be logged
2294 **/
logVaryings(const CapturedVaryings & varyings)2295 void GPUShader5TextureGatherOffsetDepthTestBase::logVaryings(const CapturedVaryings &varyings)
2296 {
2297 logArray(varyings.without_offset, m_n_components_per_varying, "Without offset: ");
2298
2299 logArray(varyings.with_offset, m_n_components_per_varying, "With offset: ");
2300 }
2301
2302 /** Constructor
2303 *
2304 * @param context Test context
2305 * @param name Test case's name
2306 * @param description Test case's description
2307 **/
GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2308 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(
2309 Context &context, const ExtParameters &extParams, const char *name, const char *description)
2310 : GPUShader5TextureGatherOffsetDepthTestBase(context, extParams, name, description)
2311 {
2312 /* Nothing to be done here */
2313 }
2314
2315 /** Get parts of vertex shader
2316 *
2317 * @param out_vertex_shader_parts Vector of vertex shader parts
2318 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2319 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::getShaderParts(
2320 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
2321 {
2322 out_vertex_shader_parts.push_back(m_vertex_shader_code);
2323 }
2324
2325 /** Prepare test specific data, that will be used as vertex attributes
2326 *
2327 * @param vertex_buffer_infos Vector of vertexBufferInfo instances
2328 **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)2329 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::prepareVertexBuffersData(
2330 std::vector<VertexBufferInfo> &vertex_buffer_infos)
2331 {
2332 /* Constants for offsets and size of buffer */
2333 const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
2334
2335 /* Limits used to generate offsets */
2336 const glw::GLint min_ptgo = m_min_texture_gather_offset;
2337 const glw::GLint max_ptgo = m_max_texture_gather_offset;
2338
2339 /* Storage for offsets */
2340 m_offsets_buffer_data.resize(n_total_components);
2341
2342 /* Generate offsets */
2343 for (unsigned int i = 0; i < n_total_components; ++i)
2344 {
2345 m_offsets_buffer_data[i] = (rand() % (max_ptgo - min_ptgo + 1)) + min_ptgo;
2346 }
2347
2348 /* Setup offsets VB info */
2349 VertexBufferInfo info;
2350
2351 info.attribute_name = m_offsets_attribute_name;
2352 info.n_components = m_n_offsets_components;
2353 info.type = GL_INT;
2354 info.data = &m_offsets_buffer_data[0];
2355 info.data_size = (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
2356
2357 /* Add VB info to vector */
2358 vertex_buffer_infos.push_back(info);
2359 }
2360
2361 /** Check if data captured for vertex at index are as expected
2362 *
2363 * @param captured_data Instance of capturedVaryings for vertex at index
2364 * @param index Index of vertex
2365 * @param texture_size Size of texture
2366 *
2367 * @return True Results match expected values
2368 * False Results do not match expected values
2369 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2370 bool GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::checkResult(const CapturedVaryings &captured_data,
2371 unsigned int index, unsigned int tex_size)
2372 {
2373 /* Signed int value has to be used with operator % in order to work as expected */
2374 const glw::GLint texture_size = (glw::GLint)tex_size;
2375
2376 /* Get offsets for vertex */
2377 glw::GLint x_offset;
2378 glw::GLint y_offset;
2379
2380 getOffsets(x_offset, y_offset, index);
2381
2382 /* Roll x offsets around left edge when negative */
2383 if (0 > x_offset)
2384 {
2385 x_offset = x_offset % texture_size;
2386 x_offset += texture_size;
2387 }
2388
2389 /* Storage for expected values of with_offset varyings */
2390 glw::GLint expected_values[m_n_components_per_varying];
2391
2392 /* Calculate expected values of with_offset varyings */
2393 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2394 {
2395 expected_values[i] = ((x_offset + captured_data.without_offset[i]) % texture_size);
2396 }
2397
2398 /* Verify that expected_values match those in with_offset varyings */
2399 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2400 {
2401 if (captured_data.with_offset[i] != expected_values[i])
2402 {
2403 /* Log invalid results */
2404 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2405
2406 logCoordinates(index);
2407
2408 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2409
2410 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2411 << tcu::TestLog::EndMessage;
2412
2413 logVaryings(captured_data);
2414
2415 m_testCtx.getLog() << tcu::TestLog::EndSection;
2416
2417 /* Done */
2418 return false;
2419 }
2420 }
2421
2422 /* Done */
2423 return true;
2424 }
2425
2426 /** Get offsets for vertex at index
2427 *
2428 * @param out_x_offset X offset
2429 * @param out_y_offset Y offset
2430 * @param index Index of vertex
2431 **/
getOffsets(glw::GLint & out_x_offset,glw::GLint & out_y_offset,unsigned int index)2432 void GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::getOffsets(glw::GLint &out_x_offset, glw::GLint &out_y_offset,
2433 unsigned int index)
2434 {
2435 out_x_offset = m_offsets_buffer_data[index * m_n_offsets_components + 0];
2436 out_y_offset = m_offsets_buffer_data[index * m_n_offsets_components + 1];
2437 }
2438
2439 /** Constructor
2440 *
2441 * @param context Test context
2442 * @param name Test case's name
2443 * @param description Test case's description
2444 **/
GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2445 GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest(
2446 Context &context, const ExtParameters &extParams, const char *name, const char *description)
2447 : GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2448 {
2449 /* Nothing to be done here */
2450 }
2451
2452 /** Get parts of vertex shader
2453 *
2454 * @param out_vertex_shader_parts Vector of vertex shader parts
2455 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2456 void GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::getShaderParts(
2457 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
2458 {
2459 out_vertex_shader_parts.push_back(m_vertex_shader_code);
2460 }
2461
2462 /** Prepare texture data as expected by case "Repeat the same test for Y axis." of test 10.
2463 * Each texel is assigned value of { y / texture_size }
2464 *
2465 * @param data Storage space for texture data
2466 **/
prepareTextureData(glw::GLubyte * data)2467 void GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::prepareTextureData(glw::GLubyte *data)
2468 {
2469 /* Data pointer */
2470 glw::GLfloat *texture_data = (glw::GLfloat *)data;
2471
2472 /* Get texture info from GPUShader5TextureGatherOffsetDepthTestBase */
2473 glw::GLuint texture_size;
2474 glw::GLenum ignored_texture_internal_format;
2475 glw::GLenum ignored_texture_format;
2476 glw::GLenum ignored_texture_type;
2477 glw::GLuint ignored_bytes_per_pixel;
2478
2479 getTextureInfo(texture_size, ignored_texture_internal_format, ignored_texture_format, ignored_texture_type,
2480 ignored_bytes_per_pixel);
2481
2482 /* Constants */
2483 const unsigned int n_components_per_pixel = 1;
2484 const unsigned int line_size = n_components_per_pixel * texture_size;
2485 const glw::GLfloat step = 1.0f / ((float)texture_size);
2486
2487 /* Prepare texture's data */
2488 for (unsigned int y = 0; y < texture_size; ++y)
2489 {
2490 const glw::GLfloat depth = ((float)y) * step;
2491
2492 for (unsigned int x = 0; x < texture_size; ++x)
2493 {
2494 const unsigned int pixel_offset = y * line_size + x * n_components_per_pixel;
2495
2496 /* texel.depth = depth */
2497 texture_data[pixel_offset] = depth;
2498 }
2499 }
2500 }
2501
2502 /** Check if data captured for vertex at index are as expected
2503 *
2504 * @param captured_data Instance of capturedVaryings for vertex at index
2505 * @param index Index of vertex
2506 * @param texture_size Size of texture
2507 *
2508 * @return True Results match expected values
2509 * False Results do not match expected values
2510 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)2511 bool GPUShader5TextureGatherOffsetDepth2DRepeatYCaseTest::checkResult(const CapturedVaryings &captured_data,
2512 unsigned int index, unsigned int tex_size)
2513 {
2514 /* Signed int value has to be used with operator % in order to work as expected */
2515 const glw::GLint texture_size = (glw::GLint)tex_size;
2516
2517 /* Get offsets for vertex */
2518 glw::GLint x_offset;
2519 glw::GLint y_offset;
2520
2521 getOffsets(x_offset, y_offset, index);
2522
2523 /* Roll y offsets around left edge when negative */
2524 if (0 > y_offset)
2525 {
2526 y_offset = y_offset % texture_size;
2527 y_offset += texture_size;
2528 }
2529
2530 /* Storage for expected values of with_offset varyings */
2531 glw::GLint expected_values[m_n_components_per_varying];
2532
2533 /* Calculate expected values of with_offset varyings */
2534 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2535 {
2536 expected_values[i] = ((y_offset + captured_data.without_offset[i]) % texture_size);
2537 }
2538
2539 /* Verify that expected_values match those in with_offset varyings */
2540 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2541 {
2542 if (captured_data.with_offset[i] != expected_values[i])
2543 {
2544 /* Log invalid results */
2545 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2546
2547 logCoordinates(index);
2548
2549 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2550
2551 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2552 << tcu::TestLog::EndMessage;
2553
2554 logVaryings(captured_data);
2555
2556 m_testCtx.getLog() << tcu::TestLog::EndSection;
2557
2558 /* Done */
2559 return false;
2560 }
2561 }
2562
2563 /* Done */
2564 return true;
2565 }
2566
2567 /** Constructor
2568 *
2569 * @param context Test context
2570 * @param name Test case's name
2571 * @param description Test case's description
2572 **/
GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2573 GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::GPUShader5TextureGatherOffsetDepth2DArrayCaseTest(
2574 Context &context, const ExtParameters &extParams, const char *name, const char *description)
2575 : GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2576 {
2577 /* Nothing to be done here */
2578 }
2579
2580 /** Get parts of vertex shader
2581 *
2582 * @param out_vertex_shader_parts Vector of vertex shader parts
2583 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2584 void GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::getShaderParts(
2585 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
2586 {
2587 out_vertex_shader_parts.push_back(m_vertex_shader_code);
2588 }
2589
2590 /** Check if texture array is required
2591 *
2592 * @param out_is_texture_array Set to true if texture array is required, false otherwise
2593 **/
isTextureArray(bool & out_is_texture_array)2594 void GPUShader5TextureGatherOffsetDepth2DArrayCaseTest::isTextureArray(bool &out_is_texture_array)
2595 {
2596 out_is_texture_array = true;
2597 }
2598
2599 /** Constructor
2600 *
2601 * @param context Test context
2602 * @param name Test case's name
2603 * @param description Test case's description
2604 **/
GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2605 GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest(
2606 Context &context, const ExtParameters &extParams, const char *name, const char *description)
2607 : GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2608 {
2609 /* Nothing to be done here */
2610 }
2611
2612 /** Get wrap mode for texture
2613 *
2614 * @param out_wrap_mode Wrap mode
2615 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2616 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getTextureWrapMode(glw::GLenum &out_wrap_mode)
2617 {
2618 out_wrap_mode = m_glExtTokens.CLAMP_TO_BORDER;
2619 }
2620
2621 /** Provides names of varyings to be captured by test
2622 *
2623 * @param out_captured_varyings Vector of varyings' names
2624 **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2625 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getVaryings(
2626 std::vector<const glw::GLchar *> &out_captured_varyings)
2627 {
2628 out_captured_varyings.push_back("without_offset");
2629 out_captured_varyings.push_back("with_offset");
2630 out_captured_varyings.push_back("floor_tex_coord");
2631 }
2632
2633 /** Get parts of vertex shader
2634 *
2635 * @param out_vertex_shader_parts Vector of vertex shader parts
2636 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2637 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::getShaderParts(
2638 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
2639 {
2640 out_vertex_shader_parts.push_back(m_vertex_shader_code);
2641 }
2642
2643 /** Prepare test specific data, that will be used as vertex attributes
2644 *
2645 * @param vertex_buffer_infos Vector of vertexBufferInfo instances
2646 **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)2647 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::prepareVertexBuffersData(
2648 std::vector<VertexBufferInfo> &vertex_buffer_infos)
2649 {
2650 /* Constats for offsets and size of buffer */
2651 const unsigned int n_total_components = m_n_vertices * m_n_offsets_components;
2652
2653 /* Limits used to generate offsets */
2654 const glw::GLint min_ptgo = m_min_texture_gather_offset;
2655 const glw::GLint max_ptgo = m_max_texture_gather_offset;
2656
2657 /* Storage for offsets */
2658 m_offsets_buffer_data.resize(n_total_components);
2659
2660 /* Generate offsets */
2661 for (unsigned int i = 0; i < n_total_components; ++i)
2662 {
2663 if (0 == i % 2)
2664 {
2665 m_offsets_buffer_data[i] = (rand() % (max_ptgo - min_ptgo + 1)) + min_ptgo;
2666 }
2667 else
2668 {
2669 /* y offsets must be set to 0*/
2670 m_offsets_buffer_data[i] = 0;
2671 }
2672 }
2673
2674 /* Setup offsets VB info */
2675 VertexBufferInfo info;
2676
2677 info.attribute_name = m_offsets_attribute_name;
2678 info.n_components = m_n_offsets_components;
2679 info.type = GL_INT;
2680 info.data = &m_offsets_buffer_data[0];
2681 info.data_size = (glw::GLuint)(m_offsets_buffer_data.size() * sizeof(glw::GLint));
2682
2683 /* Add VB info to vector */
2684 vertex_buffer_infos.push_back(info);
2685 }
2686
2687 /** Check if data captured for vertex at index are as expected
2688 *
2689 * @param captured_data Instance of capturedVaryings for vertex at index
2690 * @param index Index of vertex
2691 * @param texture_size Size of texture
2692 *
2693 * @return True Results match expected values
2694 * False Results do not match expected values
2695 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)2696 bool GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::checkResult(const CapturedVaryings &captured_data,
2697 unsigned int index,
2698 unsigned int texture_size)
2699 {
2700 /* Get offsets for vertex */
2701 glw::GLint x_offset;
2702 glw::GLint y_offset;
2703
2704 getOffsets(x_offset, y_offset, index);
2705
2706 /* Storage for expected values of with_offset varyings */
2707 glw::GLint expected_values[m_n_components_per_varying];
2708
2709 /* Index of first not clamped texel in without_offset set*/
2710 int not_clamped_texel_index = -1;
2711
2712 /* X offsets of texels in 2x2 set */
2713 static const glw::GLint gather_offsets_x[] = {0, 1, 1, 0};
2714
2715 /* Find first not clamped texel in without_offset set */
2716 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2717 {
2718 if ((int)texture_size != captured_data.without_offset[i])
2719 {
2720 not_clamped_texel_index = i;
2721 break;
2722 }
2723 }
2724
2725 if (-1 == not_clamped_texel_index)
2726 {
2727 /* Log problem with sampler */
2728 m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
2729
2730 logCoordinates(index);
2731
2732 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2733
2734 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2735 << tcu::TestLog::EndMessage;
2736
2737 logVaryings(captured_data);
2738
2739 m_testCtx.getLog() << tcu::TestLog::EndSection;
2740
2741 TCU_FAIL("Unexpected sampling results");
2742 }
2743
2744 /* Fraction part of position for lower left texel without_offset set */
2745 const glw::GLint fract_position_x =
2746 captured_data.without_offset[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
2747
2748 /* Absolute position of lower left corner in without_offset set */
2749 const glw::GLint absolute_position_x = fract_position_x + captured_data.floor_tex_coord[0] * (int)texture_size;
2750
2751 /* Wraping matrix */
2752 glw::GLint wrap_matrix[4] = {0};
2753
2754 /* Index of value in without_offset set, that should be check for being clamped */
2755 glw::GLint wrap_value_to_check_indices[4] = {3, 2, 1, 0};
2756
2757 /* Get value from without_offset to check for clamping */
2758 glw::GLint wrap_value_to_check = captured_data.without_offset[wrap_value_to_check_indices[not_clamped_texel_index]];
2759
2760 /* Setup wrap_matrix */
2761 switch (not_clamped_texel_index)
2762 {
2763 case 0:
2764 case 1:
2765 wrap_matrix[0] = 0;
2766 wrap_matrix[1] = 0;
2767
2768 if ((glw::GLint)texture_size == wrap_value_to_check)
2769 {
2770 wrap_matrix[2] = -1;
2771 wrap_matrix[3] = -1;
2772 }
2773 break;
2774 case 2:
2775 case 3:
2776 wrap_matrix[2] = 0;
2777 wrap_matrix[3] = 0;
2778
2779 if ((glw::GLint)texture_size == wrap_value_to_check)
2780 {
2781 wrap_matrix[0] = 1;
2782 wrap_matrix[1] = 1;
2783 }
2784 break;
2785 }
2786
2787 /* Apply integral part of texture coordinates to wrap_matrix */
2788 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2789 {
2790 wrap_matrix[i] += captured_data.floor_tex_coord[1];
2791 }
2792
2793 /* For each texel in without_offset set calculate absolute position and apply offset */
2794 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2795 {
2796 expected_values[i] = absolute_position_x + gather_offsets_x[i];
2797 expected_values[i] += x_offset;
2798
2799 /* Set to texture_size when point is outside of texture */
2800 if ((0 > expected_values[i]) || (((glw::GLint)texture_size) < expected_values[i]) || (0 != wrap_matrix[i]))
2801 {
2802 expected_values[i] = texture_size;
2803 }
2804 }
2805
2806 /* Verify that expected_values match those in with_offset varyings */
2807 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2808 {
2809 if (captured_data.with_offset[i] != expected_values[i])
2810 {
2811 /* Log invalid results */
2812 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2813
2814 logCoordinates(index);
2815
2816 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2817
2818 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2819 << tcu::TestLog::EndMessage;
2820
2821 logVaryings(captured_data);
2822
2823 m_testCtx.getLog() << tcu::TestLog::EndSection;
2824
2825 /* Done */
2826 return false;
2827 }
2828 }
2829
2830 /* Done */
2831 return true;
2832 }
2833
2834 /** Initializes GLES objects used during the test.
2835 *
2836 */
initTest(void)2837 void GPUShader5TextureGatherOffsetDepth2DClampToBorderCaseTest::initTest(void)
2838 {
2839 /* Check if texture_border_clamp extension is supported */
2840 if (!m_is_texture_border_clamp_supported)
2841 {
2842 throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
2843 }
2844
2845 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::initTest();
2846 }
2847
2848 /** Constructor
2849 *
2850 * @param context Test context
2851 * @param name Test case's name
2852 * @param description Test case's description
2853 **/
GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)2854 GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest(
2855 Context &context, const ExtParameters &extParams, const char *name, const char *description)
2856 : GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest(context, extParams, name, description)
2857 {
2858 /* Nothing to be done here */
2859 }
2860
2861 /** Get wrap mode for texture
2862 *
2863 * @param out_wrap_mode Wrap mode
2864 **/
getTextureWrapMode(glw::GLenum & out_wrap_mode)2865 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getTextureWrapMode(glw::GLenum &out_wrap_mode)
2866 {
2867 out_wrap_mode = GL_CLAMP_TO_EDGE;
2868 }
2869
2870 /** Get parts of vertex shader
2871 *
2872 * @param out_vertex_shader_parts Vector of vertex shader parts
2873 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)2874 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getShaderParts(
2875 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
2876 {
2877 out_vertex_shader_parts.push_back(m_vertex_shader_code);
2878 }
2879
2880 /** Check if data captured for vertex at index are as expected
2881 *
2882 * @param captured_data Instance of capturedVaryings for vertex at index
2883 * @param index Index of vertex
2884 * @param texture_size Size of texture
2885 *
2886 * @return True Results match expected values
2887 * False Results do not match expected values
2888 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int texture_size)2889 bool GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::checkResult(const CapturedVaryings &captured_data,
2890 unsigned int index, unsigned int texture_size)
2891 {
2892 /* Get offsets for vertex */
2893 glw::GLint x_offset;
2894 glw::GLint y_offset;
2895
2896 getOffsets(x_offset, y_offset, index);
2897
2898 /* Storage for expected values of with_offset varyings */
2899 glw::GLint expected_values[m_n_components_per_varying];
2900
2901 /* Index of first not clamped texel in without_offset set*/
2902 int not_clamped_texel_index = -1;
2903
2904 /* X offsets of texels in 2x2 set */
2905 static const glw::GLint gather_offsets_x[] = {0, 1, 1, 0};
2906
2907 /* Find first not clamped texel in without_offset set */
2908 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2909 {
2910 if ((int)texture_size != captured_data.without_offset[i])
2911 {
2912 not_clamped_texel_index = i;
2913 break;
2914 }
2915 }
2916
2917 if (-1 == not_clamped_texel_index)
2918 {
2919 /* Log problem with sampler */
2920 m_testCtx.getLog() << tcu::TestLog::Section("Unexpected sampling results", "");
2921
2922 logCoordinates(index);
2923
2924 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2925
2926 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2927 << tcu::TestLog::EndMessage;
2928
2929 logVaryings(captured_data);
2930
2931 m_testCtx.getLog() << tcu::TestLog::EndSection;
2932
2933 TCU_FAIL("Unexpected sampling results");
2934 }
2935
2936 /* Fraction part of position for lower left texel without_offset set */
2937 const glw::GLint fract_position_x =
2938 captured_data.without_offset[not_clamped_texel_index] - gather_offsets_x[not_clamped_texel_index];
2939
2940 /* Absolute position of lower left corner in without_offset set */
2941 const glw::GLint absolute_position_x = fract_position_x + captured_data.floor_tex_coord[0] * (int)texture_size;
2942
2943 /* Calculate expected values of with_offset varyings */
2944 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2945 {
2946 expected_values[i] = absolute_position_x + gather_offsets_x[i];
2947 expected_values[i] += x_offset;
2948
2949 /* Clamp when point is outside of texture */
2950 clamp(expected_values[i], 0, ((glw::GLint)texture_size) - 1);
2951 }
2952
2953 /* Verify that expected_values match those in with_offset varyings */
2954 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
2955 {
2956 if (captured_data.with_offset[i] != expected_values[i])
2957 {
2958 /* Log invalid results */
2959 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
2960
2961 logCoordinates(index);
2962
2963 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
2964
2965 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: " << x_offset << ", " << y_offset
2966 << tcu::TestLog::EndMessage;
2967
2968 logVaryings(captured_data);
2969
2970 m_testCtx.getLog() << tcu::TestLog::EndSection;
2971
2972 /* Done */
2973 return false;
2974 }
2975 }
2976
2977 /* Done */
2978 return true;
2979 }
2980
2981 /** Provides names of varyings to be captured by test
2982 *
2983 * @param out_captured_varyings Vector of varyings' names
2984 **/
getVaryings(std::vector<const glw::GLchar * > & out_captured_varyings)2985 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::getVaryings(
2986 std::vector<const glw::GLchar *> &out_captured_varyings)
2987 {
2988 out_captured_varyings.push_back("without_offset");
2989 out_captured_varyings.push_back("with_offset");
2990 out_captured_varyings.push_back("floor_tex_coord");
2991 }
2992
2993 /** Initializes GLES objects used during the test.
2994 *
2995 */
initTest(void)2996 void GPUShader5TextureGatherOffsetDepth2DClampToEdgeCaseTest::initTest(void)
2997 {
2998 /* Check if texture_border_clamp extension is supported */
2999 if (!m_is_texture_border_clamp_supported)
3000 {
3001 throw tcu::NotSupportedError(TEXTURE_BORDER_CLAMP_NOT_SUPPORTED, "", __FILE__, __LINE__);
3002 }
3003
3004 GPUShader5TextureGatherOffsetDepth2DRepeatCaseTest::initTest();
3005 }
3006
3007 /** Constructor
3008 *
3009 * @param context Test context
3010 * @param name Test case's name
3011 * @param description Test case's description
3012 **/
GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)3013 GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest(
3014 Context &context, const ExtParameters &extParams, const char *name, const char *description)
3015 : GPUShader5TextureGatherOffsetDepthTestBase(context, extParams, name, description)
3016 {
3017 /* Nothing to be done here */
3018 }
3019
3020 /** Get parts of vertex shader
3021 *
3022 * @param out_vertex_shader_parts Vector of vertex shader parts
3023 **/
getShaderParts(std::vector<const glw::GLchar * > & out_vertex_shader_parts)3024 void GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::getShaderParts(
3025 std::vector<const glw::GLchar *> &out_vertex_shader_parts)
3026 {
3027 std::stringstream stream;
3028
3029 stream << " ivec2[4]( ivec2( " << m_min_texture_gather_offset << ", " << m_min_texture_gather_offset
3030 << "),\n";
3031 stream << " ivec2( " << m_min_texture_gather_offset << ", " << m_max_texture_gather_offset
3032 << "),\n";
3033 stream << " ivec2( " << m_max_texture_gather_offset << ", " << m_min_texture_gather_offset
3034 << "),\n";
3035 stream << " ivec2( " << m_max_texture_gather_offset << ", " << m_max_texture_gather_offset
3036 << "));\n";
3037
3038 m_vertex_shader_code_offsets = stream.str();
3039
3040 out_vertex_shader_parts.push_back(m_vertex_shader_code_preamble);
3041 out_vertex_shader_parts.push_back(m_vertex_shader_code_offsets.c_str());
3042 out_vertex_shader_parts.push_back(m_vertex_shader_code_body);
3043 }
3044
3045 /** Prepare test specific data, that will be used as vertex attributes
3046 *
3047 * @param vertex_buffer_infos Vector of vertexBufferInfo instances
3048 **/
prepareVertexBuffersData(std::vector<VertexBufferInfo> & vertex_buffer_infos)3049 void GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::prepareVertexBuffersData(
3050 std::vector<VertexBufferInfo> &vertex_buffer_infos)
3051 {
3052 DE_UNREF(vertex_buffer_infos);
3053
3054 /* Nothing to be done here */
3055 }
3056
3057 /** Check if data captured for vertex at index are as expected
3058 *
3059 * @param captured_data Instance of capturedVaryings for vertex at index
3060 * @param index Index of vertex
3061 * @param texture_size Size of texture
3062 *
3063 * @return True Results match expected values
3064 * False Results do not match expected values
3065 **/
checkResult(const CapturedVaryings & captured_data,unsigned int index,unsigned int tex_size)3066 bool GPUShader5TextureGatherOffsetDepth2DOffsetsCaseTest::checkResult(const CapturedVaryings &captured_data,
3067 unsigned int index, unsigned int tex_size)
3068 {
3069 /* Signed int value has to be used with operator % in order to work as expected */
3070 const glw::GLint texture_size = (glw::GLint)tex_size;
3071
3072 /* X and Y offsets */
3073 glw::GLint x_offsets[m_n_components_per_varying] = {
3074 m_min_texture_gather_offset,
3075 m_min_texture_gather_offset,
3076 m_max_texture_gather_offset,
3077 m_max_texture_gather_offset,
3078 };
3079
3080 glw::GLint y_offsets[m_n_components_per_varying] = {
3081 m_min_texture_gather_offset,
3082 m_max_texture_gather_offset,
3083 m_min_texture_gather_offset,
3084 m_max_texture_gather_offset,
3085 };
3086
3087 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3088 {
3089 /* Roll x offsets around left edge when negative */
3090 if (0 > x_offsets[i])
3091 {
3092 x_offsets[i] = x_offsets[i] % texture_size;
3093 x_offsets[i] += texture_size;
3094 }
3095 }
3096
3097 /* Storage for expected values of with_offset varyings */
3098 glw::GLint expected_values[m_n_components_per_varying];
3099
3100 /* Calculate expected values of with_offset varyings */
3101 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3102 {
3103 expected_values[i] = ((x_offsets[i] + captured_data.without_offset[3]) % texture_size);
3104 }
3105
3106 /* Verify that expected_values match those in with_offset varyings */
3107 for (unsigned int i = 0; i < m_n_components_per_varying; ++i)
3108 {
3109 if (captured_data.with_offset[i] != expected_values[i])
3110 {
3111 /* Log invalid results */
3112 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
3113
3114 logCoordinates(index);
3115
3116 m_testCtx.getLog() << tcu::TestLog::Message << "Texture size: " << texture_size << tcu::TestLog::EndMessage;
3117
3118 m_testCtx.getLog() << tcu::TestLog::Message << "Offsets: "
3119 << "(" << x_offsets[0] << ", " << y_offsets[0] << ") "
3120 << "(" << x_offsets[1] << ", " << y_offsets[1] << ") "
3121 << "(" << x_offsets[2] << ", " << y_offsets[2] << ") "
3122 << "(" << x_offsets[3] << ", " << y_offsets[3] << ") " << tcu::TestLog::EndMessage;
3123
3124 logVaryings(captured_data);
3125
3126 m_testCtx.getLog() << tcu::TestLog::EndSection;
3127
3128 /* Done */
3129 return false;
3130 }
3131 }
3132
3133 /* Done */
3134 return true;
3135 }
3136
3137 } // namespace glcts
3138