1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2015-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 gl3TextureSwizzleTests.cpp
26 * \brief Implements conformance tests for "Texture Swizzle" functionality.
27 */ /*-------------------------------------------------------------------*/
28
29 #include "gl3cTextureSwizzleTests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluStrUtil.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuFloat.hpp"
34 #include "tcuTestLog.hpp"
35
36 #include "deMath.h"
37 #include <cmath>
38
39 #define ENABLE_DEBUG 0 /* Selects if debug callback is installed */
40 #define FUNCTIONAL_TEST_ALL_FORMATS 1 /* Selects if all formats should be tested */
41 #define FUNCTIONAL_TEST_ALL_TARGETS 1 /* Selects if all targets should be tested */
42 #define FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES 0 /* Selects if all texture access routines should be tested */
43 #define FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS 0 /* Selects if all swizzle combinations should be tested */
44
45 namespace gl3cts
46 {
47 namespace TextureSwizzle
48 {
49 /* Static constants use by tests */
50 /* One and zero */
51 static const glw::GLhalf data_float16_one[] = {tcu::Float16(1.0).bits()};
52 static const glw::GLhalf data_float16_zero[] = {tcu::Float16(0.0).bits()};
53 static const glw::GLfloat data_float32_one[] = {1.0f};
54 static const glw::GLfloat data_float32_zero[] = {0.0f};
55 static const glw::GLbyte data_snorm8_zero[] = {0};
56 static const glw::GLbyte data_snorm8_one[] = {127};
57 static const glw::GLshort data_snorm16_one[] = {32767};
58 static const glw::GLshort data_snorm16_zero[] = {0};
59 static const glw::GLubyte data_unorm8_one[] = {255};
60 static const glw::GLubyte data_unorm8_zero[] = {0};
61 static const glw::GLushort data_unorm16_one[] = {65535};
62 static const glw::GLushort data_unorm16_zero[] = {0};
63 static const glw::GLbyte data_sint8_zero[] = {0};
64 static const glw::GLbyte data_sint8_one[] = {1};
65 static const glw::GLshort data_sint16_one[] = {1};
66 static const glw::GLshort data_sint16_zero[] = {0};
67 static const glw::GLint data_sint32_one[] = {1};
68 static const glw::GLint data_sint32_zero[] = {0};
69 static const glw::GLubyte data_uint8_one[] = {1};
70 static const glw::GLubyte data_uint8_zero[] = {0};
71 static const glw::GLushort data_uint16_one[] = {1};
72 static const glw::GLushort data_uint16_zero[] = {0};
73 static const glw::GLuint data_uint32_one[] = {1};
74 static const glw::GLuint data_uint32_zero[] = {0};
75
76 /* Source and expected data */
77 static const glw::GLubyte src_data_r8[] = {123};
78 static const glw::GLbyte src_data_r8_snorm[] = {-123};
79 static const glw::GLushort src_data_r16[] = {12345};
80 static const glw::GLshort src_data_r16_snorm[] = {-12345};
81 static const glw::GLubyte src_data_rg8[] = {123, 231};
82 static const glw::GLbyte src_data_rg8_snorm[] = {-123, -23};
83 static const glw::GLushort src_data_rg16[] = {12345, 54321};
84 static const glw::GLshort src_data_rg16_snorm[] = {-12345, -23451};
85 static const glw::GLubyte src_data_r3_g3_b2[] = {236}; /* 255, 109, 0 */
86 static const glw::GLushort src_data_rgb4[] = {64832}; /* 5_6_5: 255, 170, 0 */
87 static const glw::GLushort src_data_rgb5[] = {64832};
88 static const glw::GLubyte src_data_rgb8[] = {3, 2, 1};
89 static const glw::GLbyte src_data_rgb8_snorm[] = {-1, -2, -3};
90 static const glw::GLushort src_data_rgb16[] = {65535, 32767, 16383};
91 static const glw::GLshort src_data_rgb16_snorm[] = {-32767, -16383, -8191};
92 static const glw::GLushort src_data_rgba4[] = {64005}; /* 255, 170, 0, 85 */
93 static const glw::GLushort src_data_rgb5_a1[] = {64852};
94 static const glw::GLubyte src_data_rgba8[] = {0, 64, 128, 255};
95 static const glw::GLbyte src_data_rgba8_snorm[] = {-127, -63, -32, -16};
96 static const glw::GLuint src_data_rgb10_a2[] = {4291823615u};
97 static const glw::GLushort exp_data_rgb10_a2ui[] = {1023, 256, 511, 3};
98 static const glw::GLushort src_data_rgba16[] = {65535, 32767, 16383, 8191};
99 static const glw::GLshort src_data_rgba16_snorm[] = {-32767, -16383, -8191, -4091};
100 static const glw::GLubyte exp_data_srgb8_alpha8[] = {13, 1, 255, 32}; /* See 4.5 core 8.24 */
101 static const glw::GLubyte src_data_srgb8_alpha8[] = {64, 8, 255, 32};
102 static const glw::GLhalf src_data_r16f[] = {tcu::Float16(1.0).bits()};
103 static const glw::GLhalf src_data_rg16f[] = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits()};
104 static const glw::GLhalf src_data_rgb16f[] = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
105 tcu::Float16(2.0).bits()};
106 static const glw::GLhalf src_data_rgba16f[] = {tcu::Float16(1.0).bits(), tcu::Float16(-1.0).bits(),
107 tcu::Float16(2.0).bits(), tcu::Float16(-2.0).bits()};
108 static const glw::GLfloat src_data_r32f[] = {1.0f};
109 static const glw::GLfloat src_data_rg32f[] = {1.0f, -1.0f};
110 static const glw::GLfloat src_data_rgb32f[] = {1.0f, -1.0f, 2.0f};
111 static const glw::GLfloat src_data_rgba32f[] = {1.0f, -1.0f, 2.0f, -2.0f};
112
113 static const tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> r11f(0.5);
114 static const tcu::Float<uint32_t, 5, 6, 15, tcu::FLOAT_SUPPORT_DENORM> g11f(0.75);
115 static const tcu::Float<uint32_t, 5, 5, 15, tcu::FLOAT_SUPPORT_DENORM> b10f(0.25);
116
117 static const glw::GLhalf exp_data_r11f_g11f_b10f[] = {tcu::Float16(0.5).bits(), tcu::Float16(0.75).bits(),
118 tcu::Float16(0.25).bits()};
119 static const glw::GLuint src_data_r11f_g11f_b10f[] = {(r11f.bits()) | (g11f.bits() << 11) | (b10f.bits() << 22)};
120 static const glw::GLfloat exp_data_rgb9_e5[] = {31.0f, 23.0f, 32.0f};
121 static const glw::GLuint src_data_rgb9_e5[] = {2885775608u};
122 static const glw::GLbyte src_data_r8i[] = {-127};
123 static const glw::GLubyte src_data_r8ui[] = {128};
124 static const glw::GLshort src_data_r16i[] = {-32767};
125 static const glw::GLushort src_data_r16ui[] = {32768};
126 static const glw::GLint src_data_r32i[] = {-1};
127 static const glw::GLuint src_data_r32ui[] = {1};
128 static const glw::GLbyte src_data_rg8i[] = {-127, -126};
129 static const glw::GLubyte src_data_rg8ui[] = {128, 129};
130 static const glw::GLshort src_data_rg16i[] = {-32767, -32766};
131 static const glw::GLushort src_data_rg16ui[] = {32768, 32769};
132 static const glw::GLint src_data_rg32i[] = {-1, -2};
133 static const glw::GLuint src_data_rg32ui[] = {1, 2};
134 static const glw::GLbyte src_data_rgb8i[] = {-127, -126, -125};
135 static const glw::GLubyte src_data_rgb8ui[] = {128, 129, 130};
136 static const glw::GLshort src_data_rgb16i[] = {-32767, -32766, -32765};
137 static const glw::GLushort src_data_rgb16ui[] = {32768, 32769, 32770};
138 static const glw::GLint src_data_rgb32i[] = {-1, -2, -3};
139 static const glw::GLuint src_data_rgb32ui[] = {1, 2, 3};
140 static const glw::GLbyte src_data_rgba8i[] = {-127, -126, -125, -124};
141 static const glw::GLubyte src_data_rgba8ui[] = {128, 129, 130, 131};
142 static const glw::GLshort src_data_rgba16i[] = {-32767, -32766, -32765, -32764};
143 static const glw::GLushort src_data_rgba16ui[] = {32768, 32769, 32770, 32771};
144 static const glw::GLint src_data_rgba32i[] = {-1, -2, -3, -4};
145 static const glw::GLuint src_data_rgba32ui[] = {1, 2, 3, 4};
146 static const glw::GLushort src_data_depth_component16[] = {32768};
147 static const glw::GLfloat exp_data_depth_component32[] = {1.0f};
148 static const glw::GLuint src_data_depth_component32[] = {4294967295u};
149 static const glw::GLfloat src_data_depth_component32f[] = {0.75f};
150 static const glw::GLuint src_data_depth24_stencil8[] = {4294967041u /* 1.0, 1 */};
151 static const glw::GLuint src_data_depth32f_stencil8[] = {1065353216, 1 /* 1.0f, 1 */};
152
153 /* Texture channels */
154 static const glw::GLchar *channels[] = {"r", "g", "b", "a"};
155
156 /* Enumerations of cube map faces */
157 static const glw::GLenum cube_map_faces[] = {GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
158 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
159 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z};
160 static const size_t n_cube_map_faces = sizeof(cube_map_faces) / sizeof(cube_map_faces[0]);
161
162 /* Swizzle states */
163 static const glw::GLenum states[] = {GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B,
164 GL_TEXTURE_SWIZZLE_A};
165 static const size_t n_states = sizeof(states) / sizeof(states[0]);
166
167 /* Sampler descriptor */
168 struct _sampler
169 {
170 const glw::GLchar *m_basic_type;
171 const glw::GLchar *m_sampler_prefix;
172 };
173 static const _sampler isampler = {"int", "i"};
174 static const _sampler usampler = {"uint", "u"};
175 static const _sampler sampler = {"float", ""};
176
177 /* Output channel descriptor */
178 struct _out_ch_desc
179 {
180 glw::GLenum m_internal_format;
181 const glw::GLvoid *m_expected_data;
182 };
183
184 /* Output channel descriptors for one and zero */
185 static const _out_ch_desc zero_ch = {GL_ZERO, 0};
186 static const _out_ch_desc one_ch = {GL_ONE, 0};
187 static const _out_ch_desc float16_zero = {GL_R16F, data_float16_zero};
188 static const _out_ch_desc float16_one = {GL_R16F, data_float16_one};
189 static const _out_ch_desc float32_zero = {GL_R32F, data_float32_zero};
190 static const _out_ch_desc float32_one = {GL_R32F, data_float32_one};
191 static const _out_ch_desc sint8_zero = {GL_R8I, data_sint8_zero};
192 static const _out_ch_desc sint8_one = {GL_R8I, data_sint8_one};
193 static const _out_ch_desc sint16_zero = {GL_R16I, data_sint16_zero};
194 static const _out_ch_desc sint16_one = {GL_R16I, data_sint16_one};
195 static const _out_ch_desc sint32_zero = {GL_R32I, data_sint32_zero};
196 static const _out_ch_desc sint32_one = {GL_R32I, data_sint32_one};
197 static const _out_ch_desc snorm8_zero = {GL_R8_SNORM, data_snorm8_zero};
198 static const _out_ch_desc snorm8_one = {GL_R8_SNORM, data_snorm8_one};
199 static const _out_ch_desc snorm16_zero = {GL_R16_SNORM, data_snorm16_zero};
200 static const _out_ch_desc snorm16_one = {GL_R16_SNORM, data_snorm16_one};
201 static const _out_ch_desc uint8_zero = {GL_R8UI, data_uint8_zero};
202 static const _out_ch_desc uint8_one = {GL_R8UI, data_uint8_one};
203 static const _out_ch_desc uint16_zero = {GL_R16UI, data_uint16_zero};
204 static const _out_ch_desc uint16_one = {GL_R16UI, data_uint16_one};
205 static const _out_ch_desc uint32_zero = {GL_R32UI, data_uint32_zero};
206 static const _out_ch_desc uint32_one = {GL_R32UI, data_uint32_one};
207 static const _out_ch_desc unorm8_zero = {GL_R8, data_unorm8_zero};
208 static const _out_ch_desc unorm8_one = {GL_R8, data_unorm8_one};
209 static const _out_ch_desc unorm16_zero = {GL_R16, data_unorm16_zero};
210 static const _out_ch_desc unorm16_one = {GL_R16, data_unorm16_one};
211
212 /* Texture format descriptor. Maps texture format with output channel descriptors, source data and sampler descriptor */
213 struct _texture_format
214 {
215 const glu::ApiType m_minimum_gl_context;
216 glw::GLenum m_internal_format;
217 glw::GLenum m_format;
218 glw::GLenum m_type;
219 glw::GLenum m_ds_mode;
220 const _sampler &m_sampler;
221 _out_ch_desc m_red_ch;
222 _out_ch_desc m_green_ch;
223 _out_ch_desc m_blue_ch;
224 _out_ch_desc m_alpha_ch;
225 const glw::GLvoid *m_source_data;
226 const _out_ch_desc &m_zero_ch;
227 const _out_ch_desc &m_one_ch;
228 };
229 static const _texture_format texture_formats[] = {
230 /* 0 */ {glu::ApiType::core(3, 0),
231 GL_R8,
232 GL_RED,
233 GL_UNSIGNED_BYTE,
234 GL_DEPTH_COMPONENT,
235 sampler,
236 {GL_R8, nullptr},
237 zero_ch,
238 zero_ch,
239 one_ch,
240 src_data_r8,
241 unorm8_zero,
242 unorm8_one},
243 {glu::ApiType::core(3, 1),
244 GL_R8_SNORM,
245 GL_RED,
246 GL_BYTE,
247 GL_DEPTH_COMPONENT,
248 sampler,
249 {GL_R8_SNORM, nullptr},
250 zero_ch,
251 zero_ch,
252 one_ch,
253 src_data_r8_snorm,
254 snorm8_zero,
255 snorm8_one},
256 {glu::ApiType::core(3, 0),
257 GL_R16,
258 GL_RED,
259 GL_UNSIGNED_SHORT,
260 GL_DEPTH_COMPONENT,
261 sampler,
262 {GL_R16, nullptr},
263 zero_ch,
264 zero_ch,
265 one_ch,
266 src_data_r16,
267 unorm16_zero,
268 unorm16_one},
269 {glu::ApiType::core(3, 1),
270 GL_R16_SNORM,
271 GL_RED,
272 GL_SHORT,
273 GL_DEPTH_COMPONENT,
274 sampler,
275 {GL_R16_SNORM, nullptr},
276 zero_ch,
277 zero_ch,
278 one_ch,
279 src_data_r16_snorm,
280 snorm16_zero,
281 snorm16_one},
282 {glu::ApiType::core(3, 0),
283 GL_RG8,
284 GL_RG,
285 GL_UNSIGNED_BYTE,
286 GL_DEPTH_COMPONENT,
287 sampler,
288 {GL_R8, nullptr},
289 {GL_R8, nullptr},
290 zero_ch,
291 one_ch,
292 src_data_rg8,
293 unorm8_zero,
294 unorm8_one},
295 {glu::ApiType::core(3, 1),
296 GL_RG8_SNORM,
297 GL_RG,
298 GL_BYTE,
299 GL_DEPTH_COMPONENT,
300 sampler,
301 {GL_R8_SNORM, nullptr},
302 {GL_R8_SNORM, nullptr},
303 zero_ch,
304 one_ch,
305 src_data_rg8_snorm,
306 snorm8_zero,
307 snorm8_one},
308 {glu::ApiType::core(3, 0),
309 GL_RG16,
310 GL_RG,
311 GL_UNSIGNED_SHORT,
312 GL_DEPTH_COMPONENT,
313 sampler,
314 {GL_R16, nullptr},
315 {GL_R16, nullptr},
316 zero_ch,
317 one_ch,
318 src_data_rg16,
319 unorm16_zero,
320 unorm16_one},
321 {glu::ApiType::core(3, 1),
322 GL_RG16_SNORM,
323 GL_RG,
324 GL_SHORT,
325 GL_DEPTH_COMPONENT,
326 sampler,
327 {GL_R16_SNORM, nullptr},
328 {GL_R16_SNORM, nullptr},
329 zero_ch,
330 one_ch,
331 src_data_rg16_snorm,
332 snorm16_zero,
333 snorm16_one},
334 /* 8 */
335 {glu::ApiType::core(4, 4),
336 GL_R3_G3_B2,
337 GL_RGB,
338 GL_UNSIGNED_BYTE_3_3_2,
339 GL_DEPTH_COMPONENT,
340 sampler,
341 {GL_R8, nullptr},
342 {GL_R8, nullptr},
343 {GL_R8, nullptr},
344 one_ch,
345 src_data_r3_g3_b2,
346 unorm8_zero,
347 unorm8_one},
348 {glu::ApiType::core(4, 4),
349 GL_RGB4,
350 GL_RGB,
351 GL_UNSIGNED_SHORT_5_6_5,
352 GL_DEPTH_COMPONENT,
353 sampler,
354 {GL_R8, nullptr},
355 {GL_R8, nullptr},
356 {GL_R8, nullptr},
357 one_ch,
358 src_data_rgb4,
359 unorm8_zero,
360 unorm8_one},
361 {glu::ApiType::core(4, 4),
362 GL_RGB5,
363 GL_RGB,
364 GL_UNSIGNED_SHORT_5_6_5,
365 GL_DEPTH_COMPONENT,
366 sampler,
367 {GL_R8, nullptr},
368 {GL_R8, nullptr},
369 {GL_R8, nullptr},
370 one_ch,
371 src_data_rgb5,
372 unorm8_zero,
373 unorm8_one},
374 {glu::ApiType::core(3, 0),
375 GL_RGB8,
376 GL_RGB,
377 GL_UNSIGNED_BYTE,
378 GL_DEPTH_COMPONENT,
379 sampler,
380 {GL_R8, nullptr},
381 {GL_R8, nullptr},
382 {GL_R8, nullptr},
383 one_ch,
384 src_data_rgb8,
385 unorm8_zero,
386 unorm8_one},
387 {glu::ApiType::core(3, 1),
388 GL_RGB8_SNORM,
389 GL_RGB,
390 GL_BYTE,
391 GL_DEPTH_COMPONENT,
392 sampler,
393 {GL_R8_SNORM, nullptr},
394 {GL_R8_SNORM, nullptr},
395 {GL_R8_SNORM, nullptr},
396 one_ch,
397 src_data_rgb8_snorm,
398 snorm8_zero,
399 snorm8_one},
400 {glu::ApiType::core(4, 4),
401 GL_RGB10,
402 GL_RGB,
403 GL_UNSIGNED_SHORT,
404 GL_DEPTH_COMPONENT,
405 sampler,
406 {GL_R16, nullptr},
407 {GL_R16, nullptr},
408 {GL_R16, nullptr},
409 one_ch,
410 src_data_rgb16,
411 unorm16_zero,
412 unorm16_one},
413 {glu::ApiType::core(4, 4),
414 GL_RGB12,
415 GL_RGB,
416 GL_UNSIGNED_SHORT,
417 GL_DEPTH_COMPONENT,
418 sampler,
419 {GL_R16, nullptr},
420 {GL_R16, nullptr},
421 {GL_R16, nullptr},
422 one_ch,
423 src_data_rgb16,
424 unorm16_zero,
425 unorm16_one},
426 {glu::ApiType::core(3, 0),
427 GL_RGB16,
428 GL_RGB,
429 GL_UNSIGNED_SHORT,
430 GL_DEPTH_COMPONENT,
431 sampler,
432 {GL_R16, nullptr},
433 {GL_R16, nullptr},
434 {GL_R16, nullptr},
435 one_ch,
436 src_data_rgb16,
437 unorm16_zero,
438 unorm16_one},
439 /* 16 */
440 {glu::ApiType::core(3, 1),
441 GL_RGB16_SNORM,
442 GL_RGB,
443 GL_SHORT,
444 GL_DEPTH_COMPONENT,
445 sampler,
446 {GL_R16_SNORM, nullptr},
447 {GL_R16_SNORM, nullptr},
448 {GL_R16_SNORM, nullptr},
449 one_ch,
450 src_data_rgb16_snorm,
451 snorm16_zero,
452 snorm16_one},
453 {glu::ApiType::core(4, 4),
454 GL_RGBA2,
455 GL_RGBA,
456 GL_UNSIGNED_SHORT_4_4_4_4,
457 GL_DEPTH_COMPONENT,
458 sampler,
459 {GL_R8, nullptr},
460 {GL_R8, nullptr},
461 {GL_R8, nullptr},
462 {GL_R8, nullptr},
463 src_data_rgba4,
464 unorm8_zero,
465 unorm8_one},
466 {glu::ApiType::core(4, 2),
467 GL_RGBA4,
468 GL_RGBA,
469 GL_UNSIGNED_SHORT_4_4_4_4,
470 GL_DEPTH_COMPONENT,
471 sampler,
472 {GL_R8, nullptr},
473 {GL_R8, nullptr},
474 {GL_R8, nullptr},
475 {GL_R8, nullptr},
476 src_data_rgba4,
477 unorm8_zero,
478 unorm8_one},
479 {glu::ApiType::core(4, 2),
480 GL_RGB5_A1,
481 GL_RGBA,
482 GL_UNSIGNED_SHORT_5_5_5_1,
483 GL_DEPTH_COMPONENT,
484 sampler,
485 {GL_R8, nullptr},
486 {GL_R8, nullptr},
487 {GL_R8, nullptr},
488 {GL_R8, nullptr},
489 src_data_rgb5_a1,
490 unorm8_zero,
491 unorm8_one},
492 {glu::ApiType::core(3, 0),
493 GL_RGBA8,
494 GL_RGBA,
495 GL_UNSIGNED_BYTE,
496 GL_DEPTH_COMPONENT,
497 sampler,
498 {GL_R8, nullptr},
499 {GL_R8, nullptr},
500 {GL_R8, nullptr},
501 {GL_R8, nullptr},
502 src_data_rgba8,
503 unorm8_zero,
504 unorm8_one},
505 {glu::ApiType::core(3, 1),
506 GL_RGBA8_SNORM,
507 GL_RGBA,
508 GL_BYTE,
509 GL_DEPTH_COMPONENT,
510 sampler,
511 {GL_R8_SNORM, nullptr},
512 {GL_R8_SNORM, nullptr},
513 {GL_R8_SNORM, nullptr},
514 {GL_R8_SNORM, nullptr},
515 src_data_rgba8_snorm,
516 snorm8_zero,
517 snorm8_one},
518 {glu::ApiType::core(3, 0),
519 GL_RGB10_A2,
520 GL_RGBA,
521 GL_UNSIGNED_INT_10_10_10_2,
522 GL_DEPTH_COMPONENT,
523 sampler,
524 {GL_R16, nullptr},
525 {GL_R16, nullptr},
526 {GL_R16, nullptr},
527 {GL_R16, nullptr},
528 src_data_rgb10_a2,
529 unorm16_zero,
530 unorm16_one},
531 {glu::ApiType::core(3, 3),
532 GL_RGB10_A2UI,
533 GL_RGBA_INTEGER,
534 GL_UNSIGNED_INT_10_10_10_2,
535 GL_DEPTH_COMPONENT,
536 usampler,
537 {GL_R16UI, exp_data_rgb10_a2ui + 0},
538 {GL_R16UI, exp_data_rgb10_a2ui + 1},
539 {GL_R16UI, exp_data_rgb10_a2ui + 2},
540 {GL_R16UI, exp_data_rgb10_a2ui + 3},
541 src_data_rgb10_a2,
542 uint16_zero,
543 uint16_one},
544 /* 24 */
545 {glu::ApiType::core(4, 4),
546 GL_RGBA12,
547 GL_RGBA,
548 GL_UNSIGNED_SHORT,
549 GL_DEPTH_COMPONENT,
550 sampler,
551 {GL_R16, nullptr},
552 {GL_R16, nullptr},
553 {GL_R16, nullptr},
554 {GL_R16, nullptr},
555 src_data_rgba16,
556 unorm16_zero,
557 unorm16_one},
558 {glu::ApiType::core(3, 0),
559 GL_RGBA16,
560 GL_RGBA,
561 GL_UNSIGNED_SHORT,
562 GL_DEPTH_COMPONENT,
563 sampler,
564 {GL_R16, nullptr},
565 {GL_R16, nullptr},
566 {GL_R16, nullptr},
567 {GL_R16, nullptr},
568 src_data_rgba16,
569 unorm16_zero,
570 unorm16_one},
571 {glu::ApiType::core(3, 1),
572 GL_RGBA16_SNORM,
573 GL_RGBA,
574 GL_SHORT,
575 GL_DEPTH_COMPONENT,
576 sampler,
577 {GL_R16_SNORM, nullptr},
578 {GL_R16_SNORM, nullptr},
579 {GL_R16_SNORM, nullptr},
580 {GL_R16_SNORM, src_data_rgba16_snorm + 3},
581 src_data_rgba16_snorm,
582 snorm16_zero,
583 snorm16_one},
584 {glu::ApiType::core(3, 0),
585 GL_SRGB8,
586 GL_RGB,
587 GL_UNSIGNED_BYTE,
588 GL_DEPTH_COMPONENT,
589 sampler,
590 {GL_R8, exp_data_srgb8_alpha8 + 0},
591 {GL_R8, exp_data_srgb8_alpha8 + 1},
592 {GL_R8, exp_data_srgb8_alpha8 + 2},
593 one_ch,
594 src_data_srgb8_alpha8,
595 unorm8_zero,
596 unorm8_one},
597 {glu::ApiType::core(3, 0),
598 GL_SRGB8_ALPHA8,
599 GL_RGBA,
600 GL_UNSIGNED_BYTE,
601 GL_DEPTH_COMPONENT,
602 sampler,
603 {GL_R8, exp_data_srgb8_alpha8 + 0},
604 {GL_R8, exp_data_srgb8_alpha8 + 1},
605 {GL_R8, exp_data_srgb8_alpha8 + 2},
606 {GL_R8, exp_data_srgb8_alpha8 + 3},
607 src_data_srgb8_alpha8,
608 unorm8_zero,
609 unorm8_one},
610 {glu::ApiType::core(3, 0),
611 GL_R16F,
612 GL_RED,
613 GL_HALF_FLOAT,
614 GL_DEPTH_COMPONENT,
615 sampler,
616 {GL_R16F, src_data_r16f + 0},
617 zero_ch,
618 zero_ch,
619 one_ch,
620 src_data_r16f,
621 float16_zero,
622 float16_one},
623 {glu::ApiType::core(3, 0),
624 GL_RG16F,
625 GL_RG,
626 GL_HALF_FLOAT,
627 GL_DEPTH_COMPONENT,
628 sampler,
629 {GL_R16F, src_data_rg16f + 0},
630 {GL_R16F, src_data_rg16f + 1},
631 zero_ch,
632 one_ch,
633 src_data_rg16f,
634 float16_zero,
635 float16_one},
636 {glu::ApiType::core(3, 0),
637 GL_RGB16F,
638 GL_RGB,
639 GL_HALF_FLOAT,
640 GL_DEPTH_COMPONENT,
641 sampler,
642 {GL_R16F, src_data_rgb16f + 0},
643 {GL_R16F, src_data_rgb16f + 1},
644 {GL_R16F, src_data_rgb16f + 2},
645 one_ch,
646 src_data_rgb16f,
647 float16_zero,
648 float16_one},
649 /* 32 */
650 {glu::ApiType::core(3, 0),
651 GL_RGBA16F,
652 GL_RGBA,
653 GL_HALF_FLOAT,
654 GL_DEPTH_COMPONENT,
655 sampler,
656 {GL_R16F, src_data_rgba16f + 0},
657 {GL_R16F, src_data_rgba16f + 1},
658 {GL_R16F, src_data_rgba16f + 2},
659 {GL_R16F, src_data_rgba16f + 3},
660 src_data_rgba16f,
661 float16_zero,
662 float16_one},
663 {glu::ApiType::core(3, 0),
664 GL_R32F,
665 GL_RED,
666 GL_FLOAT,
667 GL_DEPTH_COMPONENT,
668 sampler,
669 {GL_R32F, src_data_r32f + 0},
670 zero_ch,
671 zero_ch,
672 one_ch,
673 src_data_r32f,
674 float32_zero,
675 float32_one},
676 {glu::ApiType::core(3, 0),
677 GL_RG32F,
678 GL_RG,
679 GL_FLOAT,
680 GL_DEPTH_COMPONENT,
681 sampler,
682 {GL_R32F, src_data_rg32f + 0},
683 {GL_R32F, src_data_rg32f + 1},
684 zero_ch,
685 one_ch,
686 src_data_rg32f,
687 float32_zero,
688 float32_one},
689 {glu::ApiType::core(3, 0),
690 GL_RGB32F,
691 GL_RGB,
692 GL_FLOAT,
693 GL_DEPTH_COMPONENT,
694 sampler,
695 {GL_R32F, src_data_rgb32f + 0},
696 {GL_R32F, src_data_rgb32f + 1},
697 {GL_R32F, src_data_rgb32f + 2},
698 one_ch,
699 src_data_rgb32f,
700 float32_zero,
701 float32_one},
702 {glu::ApiType::core(3, 0),
703 GL_RGBA32F,
704 GL_RGBA,
705 GL_FLOAT,
706 GL_DEPTH_COMPONENT,
707 sampler,
708 {GL_R32F, src_data_rgba32f + 0},
709 {GL_R32F, src_data_rgba32f + 1},
710 {GL_R32F, src_data_rgba32f + 2},
711 {GL_R32F, src_data_rgba32f + 3},
712 src_data_rgba32f,
713 float32_zero,
714 float32_one},
715 {glu::ApiType::core(3, 0),
716 GL_R11F_G11F_B10F,
717 GL_RGB,
718 GL_UNSIGNED_INT_10F_11F_11F_REV,
719 GL_DEPTH_COMPONENT,
720 sampler,
721 {GL_R16F, exp_data_r11f_g11f_b10f + 0},
722 {GL_R16F, exp_data_r11f_g11f_b10f + 1},
723 {GL_R16F, exp_data_r11f_g11f_b10f + 2},
724 one_ch,
725 src_data_r11f_g11f_b10f,
726 float16_zero,
727 float16_one},
728 {glu::ApiType::core(3, 0),
729 GL_RGB9_E5,
730 GL_RGB,
731 GL_UNSIGNED_INT_5_9_9_9_REV,
732 GL_DEPTH_COMPONENT,
733 sampler,
734 {GL_R32F, exp_data_rgb9_e5 + 0},
735 {GL_R32F, exp_data_rgb9_e5 + 1},
736 {GL_R32F, exp_data_rgb9_e5 + 2},
737 one_ch,
738 src_data_rgb9_e5,
739 float32_zero,
740 float32_one},
741 {glu::ApiType::core(3, 0),
742 GL_R8I,
743 GL_RED_INTEGER,
744 GL_BYTE,
745 GL_DEPTH_COMPONENT,
746 isampler,
747 {GL_R8I, src_data_r8i},
748 zero_ch,
749 zero_ch,
750 one_ch,
751 src_data_r8i,
752 sint8_zero,
753 sint8_one},
754 /* 40 */
755 {glu::ApiType::core(3, 0),
756 GL_R8UI,
757 GL_RED_INTEGER,
758 GL_UNSIGNED_BYTE,
759 GL_DEPTH_COMPONENT,
760 usampler,
761 {GL_R8UI, src_data_r8ui},
762 zero_ch,
763 zero_ch,
764 one_ch,
765 src_data_r8ui,
766 uint8_zero,
767 uint8_one},
768 {glu::ApiType::core(3, 0),
769 GL_R16I,
770 GL_RED_INTEGER,
771 GL_SHORT,
772 GL_DEPTH_COMPONENT,
773 isampler,
774 {GL_R16I, src_data_r16i},
775 zero_ch,
776 zero_ch,
777 one_ch,
778 src_data_r16i,
779 sint16_zero,
780 sint16_one},
781 {glu::ApiType::core(3, 0),
782 GL_R16UI,
783 GL_RED_INTEGER,
784 GL_UNSIGNED_SHORT,
785 GL_DEPTH_COMPONENT,
786 usampler,
787 {GL_R16UI, src_data_r16ui},
788 zero_ch,
789 zero_ch,
790 one_ch,
791 src_data_r16ui,
792 uint16_zero,
793 uint16_one},
794 {glu::ApiType::core(3, 0),
795 GL_R32I,
796 GL_RED_INTEGER,
797 GL_INT,
798 GL_DEPTH_COMPONENT,
799 isampler,
800 {GL_R32I, src_data_r32i},
801 zero_ch,
802 zero_ch,
803 one_ch,
804 src_data_r32i,
805 sint32_zero,
806 sint32_one},
807 {glu::ApiType::core(3, 0),
808 GL_R32UI,
809 GL_RED_INTEGER,
810 GL_UNSIGNED_INT,
811 GL_DEPTH_COMPONENT,
812 usampler,
813 {GL_R32UI, src_data_r32ui},
814 zero_ch,
815 zero_ch,
816 one_ch,
817 src_data_r32ui,
818 uint32_zero,
819 uint32_one},
820 {glu::ApiType::core(3, 0),
821 GL_RG8I,
822 GL_RG_INTEGER,
823 GL_BYTE,
824 GL_DEPTH_COMPONENT,
825 isampler,
826 {GL_R8I, src_data_rg8i + 0},
827 {GL_R8I, src_data_rg8i + 1},
828 zero_ch,
829 one_ch,
830 src_data_rg8i,
831 sint8_zero,
832 sint8_one},
833 {glu::ApiType::core(3, 0),
834 GL_RG8UI,
835 GL_RG_INTEGER,
836 GL_UNSIGNED_BYTE,
837 GL_DEPTH_COMPONENT,
838 usampler,
839 {GL_R8UI, src_data_rg8ui + 0},
840 {GL_R8UI, src_data_rg8ui + 1},
841 zero_ch,
842 one_ch,
843 src_data_rg8ui,
844 uint8_zero,
845 uint8_one},
846 {glu::ApiType::core(3, 0),
847 GL_RG16I,
848 GL_RG_INTEGER,
849 GL_SHORT,
850 GL_DEPTH_COMPONENT,
851 isampler,
852 {GL_R16I, src_data_rg16i + 0},
853 {GL_R16I, src_data_rg16i + 1},
854 zero_ch,
855 one_ch,
856 src_data_rg16i,
857 sint16_zero,
858 sint16_one},
859 /* 48 */
860 {glu::ApiType::core(3, 0),
861 GL_RG16UI,
862 GL_RG_INTEGER,
863 GL_UNSIGNED_SHORT,
864 GL_DEPTH_COMPONENT,
865 usampler,
866 {GL_R16UI, src_data_rg16ui + 0},
867 {GL_R16UI, src_data_rg16ui + 1},
868 zero_ch,
869 one_ch,
870 src_data_rg16ui,
871 uint16_zero,
872 uint16_one},
873 {glu::ApiType::core(3, 0),
874 GL_RG32I,
875 GL_RG_INTEGER,
876 GL_INT,
877 GL_DEPTH_COMPONENT,
878 isampler,
879 {GL_R32I, src_data_rg32i + 0},
880 {GL_R32I, src_data_rg32i + 1},
881 zero_ch,
882 one_ch,
883 src_data_rg32i,
884 sint32_zero,
885 sint32_one},
886 {glu::ApiType::core(3, 0),
887 GL_RG32UI,
888 GL_RG_INTEGER,
889 GL_UNSIGNED_INT,
890 GL_DEPTH_COMPONENT,
891 usampler,
892 {GL_R32UI, src_data_rg32ui + 0},
893 {GL_R32UI, src_data_rg32ui + 1},
894 zero_ch,
895 one_ch,
896 src_data_rg32ui,
897 uint32_zero,
898 uint32_one},
899 {glu::ApiType::core(3, 0),
900 GL_RGB8I,
901 GL_RGB_INTEGER,
902 GL_BYTE,
903 GL_DEPTH_COMPONENT,
904 isampler,
905 {GL_R8I, src_data_rgb8i + 0},
906 {GL_R8I, src_data_rgb8i + 1},
907 {GL_R8I, src_data_rgb8i + 2},
908 one_ch,
909 src_data_rgb8i,
910 sint8_zero,
911 sint8_one},
912 {glu::ApiType::core(3, 0),
913 GL_RGB8UI,
914 GL_RGB_INTEGER,
915 GL_UNSIGNED_BYTE,
916 GL_DEPTH_COMPONENT,
917 usampler,
918 {GL_R8UI, src_data_rgb8ui + 0},
919 {GL_R8UI, src_data_rgb8ui + 1},
920 {GL_R8UI, src_data_rgb8ui + 2},
921 one_ch,
922 src_data_rgb8ui,
923 uint8_zero,
924 uint8_one},
925 {glu::ApiType::core(3, 0),
926 GL_RGB16I,
927 GL_RGB_INTEGER,
928 GL_SHORT,
929 GL_DEPTH_COMPONENT,
930 isampler,
931 {GL_R16I, src_data_rgb16i + 0},
932 {GL_R16I, src_data_rgb16i + 1},
933 {GL_R16I, src_data_rgb16i + 2},
934 one_ch,
935 src_data_rgb16i,
936 sint16_zero,
937 sint16_one},
938 {glu::ApiType::core(3, 0),
939 GL_RGB16UI,
940 GL_RGB_INTEGER,
941 GL_UNSIGNED_SHORT,
942 GL_DEPTH_COMPONENT,
943 usampler,
944 {GL_R16UI, src_data_rgb16ui + 0},
945 {GL_R16UI, src_data_rgb16ui + 1},
946 {GL_R16UI, src_data_rgb16ui + 2},
947 one_ch,
948 src_data_rgb16ui,
949 uint16_zero,
950 uint16_one},
951 {glu::ApiType::core(3, 0),
952 GL_RGB32I,
953 GL_RGB_INTEGER,
954 GL_INT,
955 GL_DEPTH_COMPONENT,
956 isampler,
957 {GL_R32I, src_data_rgb32i + 0},
958 {GL_R32I, src_data_rgb32i + 1},
959 {GL_R32I, src_data_rgb32i + 2},
960 one_ch,
961 src_data_rgb32i,
962 sint32_zero,
963 sint32_one},
964 /* 56 */
965 {glu::ApiType::core(3, 0),
966 GL_RGB32UI,
967 GL_RGB_INTEGER,
968 GL_UNSIGNED_INT,
969 GL_DEPTH_COMPONENT,
970 usampler,
971 {GL_R32UI, src_data_rgb32ui + 0},
972 {GL_R32UI, src_data_rgb32ui + 1},
973 {GL_R32UI, src_data_rgb32ui + 2},
974 one_ch,
975 src_data_rgb32ui,
976 uint32_zero,
977 uint32_one},
978 {glu::ApiType::core(3, 0),
979 GL_RGBA8I,
980 GL_RGBA_INTEGER,
981 GL_BYTE,
982 GL_DEPTH_COMPONENT,
983 isampler,
984 {GL_R8I, src_data_rgba8i + 0},
985 {GL_R8I, src_data_rgba8i + 1},
986 {GL_R8I, src_data_rgba8i + 2},
987 {GL_R8I, src_data_rgba8i + 3},
988 src_data_rgba8i,
989 sint8_zero,
990 sint8_one},
991 {glu::ApiType::core(3, 0),
992 GL_RGBA8UI,
993 GL_RGBA_INTEGER,
994 GL_UNSIGNED_BYTE,
995 GL_DEPTH_COMPONENT,
996 usampler,
997 {GL_R8UI, src_data_rgba8ui + 0},
998 {GL_R8UI, src_data_rgba8ui + 1},
999 {GL_R8UI, src_data_rgba8ui + 2},
1000 {GL_R8UI, src_data_rgba8ui + 3},
1001 src_data_rgba8ui,
1002 uint8_zero,
1003 uint8_one},
1004 {glu::ApiType::core(3, 0),
1005 GL_RGBA16I,
1006 GL_RGBA_INTEGER,
1007 GL_SHORT,
1008 GL_DEPTH_COMPONENT,
1009 isampler,
1010 {GL_R16I, src_data_rgba16i + 0},
1011 {GL_R16I, src_data_rgba16i + 1},
1012 {GL_R16I, src_data_rgba16i + 2},
1013 {GL_R16I, src_data_rgba16i + 3},
1014 src_data_rgba16i,
1015 sint16_zero,
1016 sint16_one},
1017 {glu::ApiType::core(3, 0),
1018 GL_RGBA16UI,
1019 GL_RGBA_INTEGER,
1020 GL_UNSIGNED_SHORT,
1021 GL_DEPTH_COMPONENT,
1022 usampler,
1023 {GL_R16UI, src_data_rgba16ui + 0},
1024 {GL_R16UI, src_data_rgba16ui + 1},
1025 {GL_R16UI, src_data_rgba16ui + 2},
1026 {GL_R16UI, src_data_rgba16ui + 3},
1027 src_data_rgba16ui,
1028 uint16_zero,
1029 uint16_one},
1030 {glu::ApiType::core(3, 0),
1031 GL_RGBA32I,
1032 GL_RGBA_INTEGER,
1033 GL_INT,
1034 GL_DEPTH_COMPONENT,
1035 isampler,
1036 {GL_R32I, src_data_rgba32i + 0},
1037 {GL_R32I, src_data_rgba32i + 1},
1038 {GL_R32I, src_data_rgba32i + 2},
1039 {GL_R32I, src_data_rgba32i + 3},
1040 src_data_rgba32i,
1041 sint32_zero,
1042 sint32_one},
1043 {glu::ApiType::core(3, 0),
1044 GL_RGBA32UI,
1045 GL_RGBA_INTEGER,
1046 GL_UNSIGNED_INT,
1047 GL_DEPTH_COMPONENT,
1048 usampler,
1049 {GL_R32UI, src_data_rgba32ui + 0},
1050 {GL_R32UI, src_data_rgba32ui + 1},
1051 {GL_R32UI, src_data_rgba32ui + 2},
1052 {GL_R32UI, src_data_rgba32ui + 3},
1053 src_data_rgba32ui,
1054 uint32_zero,
1055 uint32_one},
1056 {glu::ApiType::core(3, 0),
1057 GL_DEPTH_COMPONENT16,
1058 GL_DEPTH_COMPONENT,
1059 GL_UNSIGNED_SHORT,
1060 GL_DEPTH_COMPONENT,
1061 sampler,
1062 {GL_R16, src_data_depth_component16},
1063 zero_ch,
1064 zero_ch,
1065 one_ch,
1066 src_data_depth_component16,
1067 unorm16_zero,
1068 unorm16_one},
1069 /* 64 */
1070 {glu::ApiType::core(3, 0),
1071 GL_DEPTH_COMPONENT24,
1072 GL_DEPTH_COMPONENT,
1073 GL_UNSIGNED_INT,
1074 GL_DEPTH_COMPONENT,
1075 sampler,
1076 {GL_R32F, exp_data_depth_component32},
1077 zero_ch,
1078 zero_ch,
1079 one_ch,
1080 src_data_depth_component32,
1081 float32_zero,
1082 float32_one},
1083 {glu::ApiType::core(3, 0),
1084 GL_DEPTH_COMPONENT32,
1085 GL_DEPTH_COMPONENT,
1086 GL_UNSIGNED_INT,
1087 GL_DEPTH_COMPONENT,
1088 sampler,
1089 {GL_R32F, exp_data_depth_component32},
1090 zero_ch,
1091 zero_ch,
1092 one_ch,
1093 src_data_depth_component32,
1094 float32_zero,
1095 float32_one},
1096 {glu::ApiType::core(3, 0),
1097 GL_DEPTH_COMPONENT32F,
1098 GL_DEPTH_COMPONENT,
1099 GL_FLOAT,
1100 GL_DEPTH_COMPONENT,
1101 sampler,
1102 {GL_R32F, src_data_depth_component32f},
1103 zero_ch,
1104 zero_ch,
1105 one_ch,
1106 src_data_depth_component32f,
1107 float32_zero,
1108 float32_one},
1109 {glu::ApiType::core(3, 0),
1110 GL_DEPTH24_STENCIL8,
1111 GL_DEPTH_STENCIL,
1112 GL_UNSIGNED_INT_24_8,
1113 GL_DEPTH_COMPONENT,
1114 sampler,
1115 {GL_R32F, exp_data_depth_component32},
1116 zero_ch,
1117 zero_ch,
1118 one_ch,
1119 src_data_depth24_stencil8,
1120 float32_zero,
1121 float32_one},
1122 {glu::ApiType::core(3, 0),
1123 GL_DEPTH32F_STENCIL8,
1124 GL_DEPTH_STENCIL,
1125 GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1126 GL_DEPTH_COMPONENT,
1127 sampler,
1128 {GL_R32F, exp_data_depth_component32},
1129 zero_ch,
1130 zero_ch,
1131 one_ch,
1132 src_data_depth32f_stencil8,
1133 float32_zero,
1134 float32_one},
1135 {glu::ApiType::core(4, 3), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_STENCIL_INDEX, usampler,
1136 one_ch, zero_ch, zero_ch, one_ch, src_data_depth24_stencil8, uint8_zero, uint8_one},
1137 {glu::ApiType::core(4, 3), GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
1138 GL_STENCIL_INDEX, usampler, one_ch, zero_ch, zero_ch, one_ch, src_data_depth32f_stencil8, uint8_zero, uint8_one}};
1139 static const size_t n_texture_formats = sizeof(texture_formats) / sizeof(texture_formats[0]);
1140
1141 /* Texture access routine descriptors */
1142 struct _texture_access
1143 {
1144 const glw::GLchar *m_name;
1145 size_t m_n_coordinates;
1146 bool m_use_derivaties;
1147 bool m_use_integral_coordinates;
1148 bool m_use_lod;
1149 bool m_use_offsets;
1150 bool m_support_multisampling;
1151 };
1152 static const _texture_access texture_access[] = {{"texture", 0, false, false, false, false, false},
1153 {"textureProj", 1, false, false, false, false, false},
1154 {"textureLod", 0, false, false, true, false, false},
1155 {"textureOffset", 0, false, false, false, true, false},
1156 {"texelFetch", 0, false, true, true, false, true},
1157 {"texelFetchOffset", 0, false, true, true, true, false},
1158 {"textureProjOffset", 1, false, false, false, true, false},
1159 {"textureLodOffset", 0, false, false, true, true, false},
1160 {"textureProjLod", 1, false, false, true, false, false},
1161 {"textureProjLodOffset", 1, false, false, true, true, false},
1162 {"textureGrad", 0, true, false, false, false, false},
1163 {"textureGradOffset", 0, true, false, false, true, false},
1164 {"textureProjGrad", 1, true, false, false, false, false},
1165 {"textureProjGradOffset", 1, true, false, false, true, false}};
1166 static const size_t n_texture_access = sizeof(texture_access) / sizeof(texture_access[0]);
1167
1168 /* Texture target descriptor */
1169 struct _texture_target
1170 {
1171 size_t m_n_array_coordinates;
1172 size_t m_n_coordinates;
1173 size_t m_n_derivatives;
1174 const glw::GLchar *m_sampler_type;
1175 bool m_support_integral_coordinates;
1176 bool m_support_lod;
1177 bool m_support_offset;
1178 bool m_supports_proj;
1179 bool m_require_multisampling;
1180 glw::GLenum m_target;
1181 };
1182
1183 static const _texture_target texture_targets[] = {
1184 {0, 1, 1, "1D", true, true, true, true, false, GL_TEXTURE_1D},
1185 {0, 2, 2, "2D", true, true, true, true, false, GL_TEXTURE_2D},
1186 {0, 3, 3, "3D", true, true, true, true, false, GL_TEXTURE_3D},
1187 {1, 1, 1, "1DArray", true, true, true, false, false, GL_TEXTURE_1D_ARRAY},
1188 {1, 2, 2, "2DArray", true, true, true, false, false, GL_TEXTURE_2D_ARRAY},
1189 {0, 2, 2, "2DRect", true, false, true, true, false, GL_TEXTURE_RECTANGLE},
1190 {0, 3, 3, "Cube", false, true, false, false, false, GL_TEXTURE_CUBE_MAP},
1191 {0, 2, 2, "2DMS", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE},
1192 {1, 2, 2, "2DMSArray", true, false, true, true, true, GL_TEXTURE_2D_MULTISAMPLE_ARRAY},
1193 };
1194 static const size_t n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
1195
1196 /* Swizzle valid values */
1197 static const glw::GLint valid_values[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE, GL_ZERO};
1198 static const size_t n_valid_values = sizeof(valid_values) / sizeof(valid_values[0]);
1199
1200 /* Prototypes */
1201 const _out_ch_desc &get_descriptor_for_channel(const _texture_format &format, const size_t channel);
1202
1203 #if ENABLE_DEBUG
1204
1205 /** Debuging procedure. Logs parameters.
1206 *
1207 * @param source As specified in GL spec.
1208 * @param type As specified in GL spec.
1209 * @param id As specified in GL spec.
1210 * @param severity As specified in GL spec.
1211 * @param ignored
1212 * @param message As specified in GL spec.
1213 * @param info Pointer to instance of deqp::Context used by test.
1214 */
debug_proc(glw::GLenum source,glw::GLenum type,glw::GLuint id,glw::GLenum severity,glw::GLsizei,const glw::GLchar * message,void * info)1215 void GLW_APIENTRY debug_proc(glw::GLenum source, glw::GLenum type, glw::GLuint id, glw::GLenum severity,
1216 glw::GLsizei /* length */, const glw::GLchar *message, void *info)
1217 {
1218 Context *ctx = (Context *)info;
1219
1220 const glw::GLchar *source_str = "Unknown";
1221 const glw::GLchar *type_str = "Unknown";
1222 const glw::GLchar *severity_str = "Unknown";
1223
1224 switch (source)
1225 {
1226 case GL_DEBUG_SOURCE_API:
1227 source_str = "API";
1228 break;
1229 case GL_DEBUG_SOURCE_APPLICATION:
1230 source_str = "APP";
1231 break;
1232 case GL_DEBUG_SOURCE_OTHER:
1233 source_str = "OTR";
1234 break;
1235 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1236 source_str = "COM";
1237 break;
1238 case GL_DEBUG_SOURCE_THIRD_PARTY:
1239 source_str = "3RD";
1240 break;
1241 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1242 source_str = "WS";
1243 break;
1244 default:
1245 break;
1246 }
1247
1248 switch (type)
1249 {
1250 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1251 type_str = "DEPRECATED_BEHAVIOR";
1252 break;
1253 case GL_DEBUG_TYPE_ERROR:
1254 type_str = "ERROR";
1255 break;
1256 case GL_DEBUG_TYPE_MARKER:
1257 type_str = "MARKER";
1258 break;
1259 case GL_DEBUG_TYPE_OTHER:
1260 type_str = "OTHER";
1261 break;
1262 case GL_DEBUG_TYPE_PERFORMANCE:
1263 type_str = "PERFORMANCE";
1264 break;
1265 case GL_DEBUG_TYPE_POP_GROUP:
1266 type_str = "POP_GROUP";
1267 break;
1268 case GL_DEBUG_TYPE_PORTABILITY:
1269 type_str = "PORTABILITY";
1270 break;
1271 case GL_DEBUG_TYPE_PUSH_GROUP:
1272 type_str = "PUSH_GROUP";
1273 break;
1274 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1275 type_str = "UNDEFINED_BEHAVIOR";
1276 break;
1277 default:
1278 break;
1279 }
1280
1281 switch (severity)
1282 {
1283 case GL_DEBUG_SEVERITY_HIGH:
1284 severity_str = "H";
1285 break;
1286 case GL_DEBUG_SEVERITY_LOW:
1287 severity_str = "L";
1288 break;
1289 case GL_DEBUG_SEVERITY_MEDIUM:
1290 severity_str = "M";
1291 break;
1292 case GL_DEBUG_SEVERITY_NOTIFICATION:
1293 severity_str = "N";
1294 break;
1295 default:
1296 break;
1297 }
1298
1299 ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|"
1300 << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id
1301 << ": " << message << tcu::TestLog::EndMessage;
1302 }
1303
1304 #endif /* ENABLE_DEBUG */
1305
1306 /** Extracts value of each channel from source data of given format
1307 *
1308 * @param format_idx Index of format
1309 * @param out_ch_rgba Storage for values
1310 **/
calculate_values_from_source(size_t format_idx,double out_ch_rgba[4])1311 void calculate_values_from_source(size_t format_idx, double out_ch_rgba[4])
1312 {
1313 const _texture_format &format = texture_formats[format_idx];
1314
1315 /* */
1316 double ch_rgba[4] = {0.0, 0.0, 0.0, 0.0};
1317 double &ch_r = ch_rgba[0];
1318 double &ch_g = ch_rgba[1];
1319 double &ch_b = ch_rgba[2];
1320 double &ch_a = ch_rgba[3];
1321 size_t n_channels = 0;
1322 bool is_norm = true;
1323
1324 /* Select n_channels and is_norm */
1325 switch (format.m_format)
1326 {
1327 case GL_RED_INTEGER:
1328 is_norm = false;
1329 /* fall through */
1330
1331 case GL_RED:
1332 n_channels = 1;
1333
1334 break;
1335
1336 case GL_RG_INTEGER:
1337 is_norm = false;
1338 /* fall through */
1339
1340 case GL_RG:
1341 n_channels = 2;
1342
1343 break;
1344
1345 case GL_RGB_INTEGER:
1346 is_norm = false;
1347 /* fall through */
1348
1349 case GL_RGB:
1350 n_channels = 3;
1351
1352 break;
1353
1354 case GL_RGBA_INTEGER:
1355 is_norm = false;
1356 /* fall through */
1357
1358 case GL_RGBA:
1359 n_channels = 4;
1360
1361 break;
1362
1363 default:
1364 TCU_FAIL("Unsupported format");
1365 }
1366
1367 /* Calculate rgba values */
1368 if ((GL_SRGB8 == format.m_internal_format) || (GL_SRGB8_ALPHA8 == format.m_internal_format))
1369 {
1370 const glw::GLubyte *ptr = (const glw::GLubyte *)src_data_srgb8_alpha8;
1371 const glw::GLubyte r = ptr[0];
1372 const glw::GLubyte g = ptr[1];
1373 const glw::GLubyte b = ptr[2];
1374 const glw::GLubyte a = ptr[3];
1375
1376 ch_r = r;
1377 ch_g = g;
1378 ch_b = b;
1379 ch_a = a;
1380
1381 ch_r /= 255.0;
1382 ch_g /= 255.0;
1383 ch_b /= 255.0;
1384 ch_a /= 255.0;
1385 }
1386 else if (GL_UNSIGNED_BYTE_3_3_2 == format.m_type)
1387 {
1388 const glw::GLubyte *ptr = (const glw::GLubyte *)format.m_source_data;
1389 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 5);
1390 const glw::GLubyte g = ((*ptr) >> 2) & 7;
1391 const glw::GLubyte b = (*ptr) & 3;
1392
1393 ch_r = r;
1394 ch_g = g;
1395 ch_b = b;
1396
1397 ch_r /= 7.0;
1398 ch_g /= 7.0;
1399 ch_b /= 3.0;
1400 }
1401 else if (GL_UNSIGNED_SHORT_5_6_5 == format.m_type)
1402 {
1403 const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1404 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11);
1405 const glw::GLubyte g = (glw::GLubyte)((*ptr) >> 5) & 63;
1406 const glw::GLubyte b = (*ptr) & 31;
1407
1408 ch_r = r;
1409 ch_g = g;
1410 ch_b = b;
1411
1412 ch_r /= 31.0;
1413 ch_g /= 63.0;
1414 ch_b /= 31.0;
1415 }
1416 else if (GL_UNSIGNED_SHORT_4_4_4_4 == format.m_type)
1417 {
1418 const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1419 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 12);
1420 const glw::GLubyte g = (glw::GLubyte)(((*ptr) >> 8) & 15);
1421 const glw::GLubyte b = (glw::GLubyte)(((*ptr) >> 4) & 15);
1422 const glw::GLubyte a = (glw::GLubyte)((*ptr) & 15);
1423
1424 ch_r = r;
1425 ch_g = g;
1426 ch_b = b;
1427 ch_a = a;
1428
1429 ch_r /= 15.0;
1430 ch_g /= 15.0;
1431 ch_b /= 15.0;
1432 ch_a /= 15.0;
1433 }
1434 else if (GL_UNSIGNED_SHORT_5_5_5_1 == format.m_type)
1435 {
1436 const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1437 const glw::GLubyte r = (glw::GLubyte)((*ptr) >> 11);
1438 const glw::GLubyte g = ((*ptr) >> 6) & 31;
1439 const glw::GLubyte b = ((*ptr) >> 1) & 31;
1440 const glw::GLubyte a = (*ptr) & 1;
1441
1442 ch_r = r;
1443 ch_g = g;
1444 ch_b = b;
1445 ch_a = a;
1446
1447 ch_r /= 31.0;
1448 ch_g /= 31.0;
1449 ch_b /= 31.0;
1450 ch_a /= 1.0;
1451 }
1452 else if (GL_UNSIGNED_INT_10_10_10_2 == format.m_type)
1453 {
1454 const glw::GLuint *ptr = (const glw::GLuint *)format.m_source_data;
1455 const glw::GLushort r = (glw::GLushort)((*ptr) >> 22);
1456 const glw::GLushort g = ((*ptr) >> 12) & 1023;
1457 const glw::GLushort b = ((*ptr) >> 2) & 1023;
1458 const glw::GLushort a = (*ptr) & 3;
1459
1460 ch_r = r;
1461 ch_g = g;
1462 ch_b = b;
1463 ch_a = a;
1464
1465 if (true == is_norm)
1466 {
1467 ch_r /= 1023.0;
1468 ch_g /= 1023.0;
1469 ch_b /= 1023.0;
1470 ch_a /= 3.0;
1471 }
1472 }
1473 else if (GL_UNSIGNED_INT_10F_11F_11F_REV == format.m_type)
1474 {
1475 ch_r = r11f.asDouble();
1476 ch_g = g11f.asDouble();
1477 ch_b = b10f.asDouble();
1478 }
1479 else if (GL_UNSIGNED_INT_5_9_9_9_REV == format.m_type)
1480 {
1481 TCU_FAIL("Not supported: GL_UNSIGNED_INT_5_9_9_9_REV");
1482 }
1483 else if (GL_UNSIGNED_INT_24_8 == format.m_type)
1484 {
1485 TCU_FAIL("Not supported: GL_UNSIGNED_INT_24_8");
1486 }
1487 else if (GL_FLOAT_32_UNSIGNED_INT_24_8_REV == format.m_type)
1488 {
1489 TCU_FAIL("Not supported: GL_FLOAT_32_UNSIGNED_INT_24_8_REV");
1490 }
1491 else if (GL_BYTE == format.m_type)
1492 {
1493 const glw::GLbyte *ptr = (const glw::GLbyte *)format.m_source_data;
1494
1495 for (size_t i = 0; i < n_channels; ++i)
1496 {
1497 const glw::GLbyte val = ptr[i];
1498 double &ch = ch_rgba[i];
1499
1500 ch = val;
1501 if (true == is_norm)
1502 ch /= 127.0;
1503 }
1504 }
1505 else if (GL_UNSIGNED_BYTE == format.m_type)
1506 {
1507 const glw::GLubyte *ptr = (const glw::GLubyte *)format.m_source_data;
1508
1509 for (size_t i = 0; i < n_channels; ++i)
1510 {
1511 const glw::GLubyte val = ptr[i];
1512 double &ch = ch_rgba[i];
1513
1514 ch = val;
1515 if (true == is_norm)
1516 ch /= 255.0;
1517 }
1518 }
1519 else if (GL_SHORT == format.m_type)
1520 {
1521 const glw::GLshort *ptr = (const glw::GLshort *)format.m_source_data;
1522
1523 for (size_t i = 0; i < n_channels; ++i)
1524 {
1525 const glw::GLshort val = ptr[i];
1526 double &ch = ch_rgba[i];
1527
1528 ch = val;
1529 if (true == is_norm)
1530 ch /= 32767.0;
1531 }
1532 }
1533 else if (GL_UNSIGNED_SHORT == format.m_type)
1534 {
1535 const glw::GLushort *ptr = (const glw::GLushort *)format.m_source_data;
1536
1537 for (size_t i = 0; i < n_channels; ++i)
1538 {
1539 const glw::GLushort val = ptr[i];
1540 double &ch = ch_rgba[i];
1541
1542 ch = val;
1543 if (true == is_norm)
1544 ch /= 65535.0;
1545 }
1546 }
1547 else if (GL_INT == format.m_type)
1548 {
1549 const glw::GLint *ptr = (const glw::GLint *)format.m_source_data;
1550
1551 for (size_t i = 0; i < n_channels; ++i)
1552 {
1553 const glw::GLint val = ptr[i];
1554 double &ch = ch_rgba[i];
1555
1556 ch = val;
1557 if (true == is_norm)
1558 ch /= 2147483647.0;
1559 }
1560 }
1561 else if (GL_UNSIGNED_INT == format.m_type)
1562 {
1563 const glw::GLuint *ptr = (const glw::GLuint *)format.m_source_data;
1564
1565 for (size_t i = 0; i < n_channels; ++i)
1566 {
1567 const glw::GLuint val = ptr[i];
1568 double &ch = ch_rgba[i];
1569
1570 ch = val;
1571 if (true == is_norm)
1572 ch /= 4294967295.0;
1573 }
1574 }
1575 else if (GL_FLOAT == format.m_type)
1576 {
1577 const glw::GLfloat *ptr = (const glw::GLfloat *)format.m_source_data;
1578
1579 for (size_t i = 0; i < n_channels; ++i)
1580 {
1581 const glw::GLfloat val = ptr[i];
1582 double &ch = ch_rgba[i];
1583
1584 ch = val;
1585 }
1586 }
1587 else if (GL_HALF_FLOAT == format.m_type)
1588 {
1589 const glw::GLhalf *ptr = (const glw::GLhalf *)format.m_source_data;
1590
1591 for (size_t i = 0; i < n_channels; ++i)
1592 {
1593 const glw::GLhalf val = ptr[i];
1594 double &ch = ch_rgba[i];
1595
1596 tcu::Float16 f16(val);
1597 ch = f16.asDouble();
1598 }
1599 }
1600 else
1601 {
1602 TCU_FAIL("Invalid enum");
1603 }
1604
1605 /* Store results */
1606 memcpy(out_ch_rgba, ch_rgba, 4 * sizeof(double));
1607 }
1608
1609 /** Calculate maximum uint value for given size of storage
1610 *
1611 * @param size Size of storage in bits
1612 *
1613 * @return Calculated max
1614 **/
calculate_max_for_size(size_t size)1615 double calculate_max_for_size(size_t size)
1616 {
1617 double power = pow(2.0, double(size));
1618
1619 return power - 1.0;
1620 }
1621
1622 /** Converts from double to given T
1623 *
1624 * @tparam Requested type of value
1625 *
1626 * @param out_expected_data Storage for converted value
1627 * @param value Value to be converted
1628 **/
1629 template <typename T>
convert(void * out_expected_data,double value)1630 void convert(void *out_expected_data, double value)
1631 {
1632 T *ptr = (T *)out_expected_data;
1633
1634 *ptr = T(value);
1635 }
1636
1637 /** Calcualte range of expected values
1638 *
1639 * @param source_format_idx Index of source format
1640 * @param output_format_idx Index of output format
1641 * @param index_of_swizzled_channel Index of swizzled channel
1642 * @param source_size Size of source storage in bits
1643 * @param output_size Size of output storage in bits
1644 * @param out_expected_data_low Lowest acceptable value
1645 * @param out_expected_data_top Highest acceptable value
1646 * @param out_expected_data_size Number of bytes used to store out values
1647 **/
calculate_expected_value(size_t source_format_idx,size_t output_format_idx,size_t index_of_swizzled_channel,glw::GLint source_size,glw::GLint output_size,void * out_expected_data_low,void * out_expected_data_top,size_t & out_expected_data_size)1648 void calculate_expected_value(size_t source_format_idx, size_t output_format_idx, size_t index_of_swizzled_channel,
1649 glw::GLint source_size, glw::GLint output_size, void *out_expected_data_low,
1650 void *out_expected_data_top, size_t &out_expected_data_size)
1651 {
1652 const _texture_format &output_format = texture_formats[output_format_idx];
1653 const _texture_format &source_format = texture_formats[source_format_idx];
1654 const _out_ch_desc &desc = get_descriptor_for_channel(source_format, index_of_swizzled_channel);
1655 const glw::GLvoid *expected_data = desc.m_expected_data;
1656 bool is_signed = false;
1657 double range_low = 0.0f;
1658 double range_top = 0.0f;
1659 size_t texel_size = 0;
1660
1661 /* Select range, texel size and is_signed */
1662 switch (output_format.m_type)
1663 {
1664 case GL_BYTE:
1665 is_signed = true;
1666
1667 range_low = -127.0;
1668 range_top = 127.0;
1669
1670 texel_size = 1;
1671
1672 break;
1673
1674 case GL_UNSIGNED_BYTE:
1675 range_low = 0.0;
1676 range_top = 255.0;
1677
1678 texel_size = 1;
1679
1680 break;
1681
1682 case GL_SHORT:
1683 is_signed = true;
1684
1685 range_low = -32767.0;
1686 range_top = 32767.0;
1687
1688 texel_size = 2;
1689
1690 break;
1691
1692 case GL_UNSIGNED_SHORT:
1693 range_low = 0.0;
1694 range_top = 65535.0;
1695
1696 texel_size = 2;
1697
1698 break;
1699
1700 case GL_HALF_FLOAT:
1701 texel_size = 2;
1702
1703 /* Halfs are not calculated, range will not be used */
1704
1705 break;
1706
1707 case GL_INT:
1708 is_signed = true;
1709
1710 range_low = -2147483647.0;
1711 range_top = 2147483647.0;
1712
1713 texel_size = 4;
1714
1715 break;
1716
1717 case GL_UNSIGNED_INT:
1718 range_low = 0.0;
1719 range_top = 4294967295.0;
1720
1721 texel_size = 4;
1722
1723 break;
1724
1725 case GL_FLOAT:
1726 texel_size = 4;
1727
1728 /* Float are not calculated, range will not be used */
1729
1730 break;
1731
1732 default:
1733 TCU_FAIL("Invalid enum");
1734 }
1735
1736 /* Signed formats use one bit less */
1737 if (true == is_signed)
1738 {
1739 source_size -= 1;
1740 output_size -= 1;
1741 }
1742
1743 /* If expected data is hardcoded just copy data to low and top */
1744 if (nullptr != expected_data)
1745 {
1746 memcpy(out_expected_data_top, expected_data, texel_size);
1747 memcpy(out_expected_data_low, expected_data, texel_size);
1748 out_expected_data_size = texel_size;
1749 }
1750 else
1751 {
1752 /* Get source values */
1753 double ch_rgba[4];
1754 calculate_values_from_source(source_format_idx, ch_rgba);
1755
1756 /* Calculate expected value */
1757 const float max_internal = float(calculate_max_for_size(source_size));
1758 const float max_output = float(calculate_max_for_size(output_size));
1759 const float temp_internal = float(ch_rgba[index_of_swizzled_channel]) * max_internal;
1760 const float stor_internal_low =
1761 deFloatFloor(temp_internal - 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1762 const float stor_internal_top =
1763 deFloatCeil(temp_internal + 1.0f); /* Offset by 1 to avoid rounding done by FPU */
1764 const float read_internal_low = stor_internal_low / max_internal;
1765 const float read_internal_top = stor_internal_top / max_internal;
1766 const float temp_output_low = read_internal_low * max_output;
1767 const float temp_output_top = read_internal_top * max_output;
1768 double stor_output_low = floor(temp_output_low);
1769 double stor_output_top = ceil(temp_output_top);
1770
1771 /* Clamp to limits of output format */
1772 stor_output_low = de::clamp(stor_output_low, range_low, range_top);
1773 stor_output_top = de::clamp(stor_output_top, range_low, range_top);
1774
1775 /* Store resuts */
1776 switch (output_format.m_type)
1777 {
1778 case GL_BYTE:
1779 convert<glw::GLbyte>(out_expected_data_low, stor_output_low);
1780 convert<glw::GLbyte>(out_expected_data_top, stor_output_top);
1781 break;
1782 case GL_UNSIGNED_BYTE:
1783 convert<glw::GLubyte>(out_expected_data_low, stor_output_low);
1784 convert<glw::GLubyte>(out_expected_data_top, stor_output_top);
1785 break;
1786 case GL_SHORT:
1787 convert<glw::GLshort>(out_expected_data_low, stor_output_low);
1788 convert<glw::GLshort>(out_expected_data_top, stor_output_top);
1789 break;
1790 case GL_UNSIGNED_SHORT:
1791 convert<glw::GLushort>(out_expected_data_low, stor_output_low);
1792 convert<glw::GLushort>(out_expected_data_top, stor_output_top);
1793 break;
1794 case GL_INT:
1795 convert<glw::GLint>(out_expected_data_low, stor_output_low);
1796 convert<glw::GLint>(out_expected_data_top, stor_output_top);
1797 break;
1798 case GL_UNSIGNED_INT:
1799 convert<glw::GLuint>(out_expected_data_low, stor_output_low);
1800 convert<glw::GLuint>(out_expected_data_top, stor_output_top);
1801 break;
1802 default:
1803 TCU_FAIL("Invalid enum");
1804 }
1805 out_expected_data_size = texel_size;
1806 }
1807 }
1808
1809 /** Gets index of internal format in texture_fomrats
1810 *
1811 * @param internal_format Internal format to be found
1812 *
1813 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1814 **/
get_index_of_format(glw::GLenum internal_format)1815 size_t get_index_of_format(glw::GLenum internal_format)
1816 {
1817 if (GL_ZERO == internal_format)
1818 {
1819 return 0;
1820 }
1821
1822 for (size_t i = 0; i < n_texture_formats; ++i)
1823 {
1824 if (texture_formats[i].m_internal_format == internal_format)
1825 {
1826 return i;
1827 }
1828 }
1829
1830 TCU_FAIL("Unknown internal format");
1831 return -1;
1832 }
1833
1834 /** Gets index of target in texture_targets
1835 *
1836 * @param target target to be found
1837 *
1838 * @return Found index. -1 when format is not available. 0 when GL_ZERO is requested.
1839 **/
get_index_of_target(glw::GLenum target)1840 size_t get_index_of_target(glw::GLenum target)
1841 {
1842 if (GL_ZERO == target)
1843 {
1844 return 0;
1845 }
1846
1847 for (size_t i = 0; i < n_texture_targets; ++i)
1848 {
1849 if (texture_targets[i].m_target == target)
1850 {
1851 return i;
1852 }
1853 }
1854
1855 TCU_FAIL("Unknown texture target");
1856 return -1;
1857 }
1858
1859 /* Constants used by get_swizzled_channel_idx */
1860 static const size_t CHANNEL_INDEX_ONE = 4;
1861 static const size_t CHANNEL_INDEX_ZERO = 5;
1862
1863 /** Get index of channel that will be accessed after "swizzle" is applied
1864 *
1865 * @param channel_idx Index of channel before "swizzle" is applied
1866 * @param swizzle_set Set of swizzle states
1867 *
1868 * @return Index of "swizzled" channel
1869 */
get_swizzled_channel_idx(const size_t channel_idx,const glw::GLint swizzle_set[4])1870 size_t get_swizzled_channel_idx(const size_t channel_idx, const glw::GLint swizzle_set[4])
1871 {
1872 const glw::GLint swizzle = swizzle_set[channel_idx];
1873
1874 size_t channel = 0;
1875
1876 switch (swizzle)
1877 {
1878 case GL_RED:
1879 channel = 0;
1880 break;
1881 case GL_GREEN:
1882 channel = 1;
1883 break;
1884 case GL_BLUE:
1885 channel = 2;
1886 break;
1887 case GL_ALPHA:
1888 channel = 3;
1889 break;
1890 case GL_ONE:
1891 channel = CHANNEL_INDEX_ONE;
1892 break;
1893 case GL_ZERO:
1894 channel = CHANNEL_INDEX_ZERO;
1895 break;
1896 default:
1897 TCU_FAIL("Invalid value");
1898 }
1899
1900 return channel;
1901 }
1902
1903 /** Gets descriptor of output channel from texture format descriptor
1904 *
1905 * @param format Format descriptor
1906 * @param channel Index of "swizzled" channel
1907 *
1908 * @return Descriptor of output channel
1909 **/
get_descriptor_for_channel(const _texture_format & format,const size_t channel)1910 const _out_ch_desc &get_descriptor_for_channel(const _texture_format &format, const size_t channel)
1911 {
1912 const _out_ch_desc *desc = 0;
1913
1914 switch (channel)
1915 {
1916 case CHANNEL_INDEX_ONE:
1917 desc = &format.m_one_ch;
1918 break;
1919 case CHANNEL_INDEX_ZERO:
1920 desc = &format.m_zero_ch;
1921 break;
1922 case 0:
1923 desc = &format.m_red_ch;
1924 break;
1925 case 1:
1926 desc = &format.m_green_ch;
1927 break;
1928 case 2:
1929 desc = &format.m_blue_ch;
1930 break;
1931 case 3:
1932 desc = &format.m_alpha_ch;
1933 break;
1934 default:
1935 TCU_FAIL("Invalid value");
1936 }
1937
1938 switch (desc->m_internal_format)
1939 {
1940 case GL_ONE:
1941 desc = &format.m_one_ch;
1942 break;
1943 case GL_ZERO:
1944 desc = &format.m_zero_ch;
1945 break;
1946 default:
1947 break;
1948 }
1949
1950 return *desc;
1951 }
1952
1953 /** Gets internal_format of output channel for given texture format
1954 *
1955 * @param format Format descriptor
1956 * @param channel Index of "swizzled" channel
1957 *
1958 * @return Internal format
1959 **/
get_internal_format_for_channel(const _texture_format & format,const size_t channel)1960 glw::GLenum get_internal_format_for_channel(const _texture_format &format, const size_t channel)
1961 {
1962 return get_descriptor_for_channel(format, channel).m_internal_format;
1963 }
1964
1965 /** Constructor
1966 *
1967 * @param context Test context
1968 **/
programInfo(deqp::Context & context)1969 Utils::programInfo::programInfo(deqp::Context &context)
1970 : m_context(context)
1971 , m_fragment_shader_id(0)
1972 , m_program_object_id(0)
1973 , m_vertex_shader_id(0)
1974 {
1975 /* Nothing to be done here */
1976 }
1977
1978 /** Destructor
1979 *
1980 **/
~programInfo()1981 Utils::programInfo::~programInfo()
1982 {
1983 /* GL entry points */
1984 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1985
1986 /* Make sure program object is no longer used by GL */
1987 gl.useProgram(0);
1988
1989 /* Clean program object */
1990 if (0 != m_program_object_id)
1991 {
1992 gl.deleteProgram(m_program_object_id);
1993 m_program_object_id = 0;
1994 }
1995
1996 /* Clean shaders */
1997 if (0 != m_fragment_shader_id)
1998 {
1999 gl.deleteShader(m_fragment_shader_id);
2000 m_fragment_shader_id = 0;
2001 }
2002
2003 if (0 != m_vertex_shader_id)
2004 {
2005 gl.deleteShader(m_vertex_shader_id);
2006 m_vertex_shader_id = 0;
2007 }
2008 }
2009
2010 /** Build program
2011 *
2012 * @param fragment_shader_code Fragment shader source code
2013 * @param vertex_shader_code Vertex shader source code
2014 **/
build(const glw::GLchar * fragment_shader_code,const glw::GLchar * vertex_shader_code)2015 void Utils::programInfo::build(const glw::GLchar *fragment_shader_code, const glw::GLchar *vertex_shader_code)
2016 {
2017 /* GL entry points */
2018 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2019
2020 /* Create shader objects and compile */
2021 if (0 != fragment_shader_code)
2022 {
2023 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
2024 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2025
2026 compile(m_fragment_shader_id, fragment_shader_code);
2027 }
2028
2029 if (0 != vertex_shader_code)
2030 {
2031 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
2032 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
2033
2034 compile(m_vertex_shader_id, vertex_shader_code);
2035 }
2036
2037 /* Create program object */
2038 m_program_object_id = gl.createProgram();
2039 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
2040
2041 /* Link program */
2042 link();
2043 }
2044
2045 /** Compile shader
2046 *
2047 * @param shader_id Shader object id
2048 * @param shader_code Shader source code
2049 **/
compile(glw::GLuint shader_id,const glw::GLchar * shader_code) const2050 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar *shader_code) const
2051 {
2052 /* GL entry points */
2053 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2054
2055 /* Compilation status */
2056 glw::GLint status = GL_FALSE;
2057
2058 /* Set source code */
2059 gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
2060 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
2061
2062 /* Compile */
2063 gl.compileShader(shader_id);
2064 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
2065
2066 /* Get compilation status */
2067 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
2068 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2069
2070 /* Log compilation error */
2071 if (GL_TRUE != status)
2072 {
2073 glw::GLint length = 0;
2074 std::vector<glw::GLchar> message;
2075
2076 /* Error log length */
2077 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
2078 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
2079
2080 /* Prepare storage */
2081 message.resize(length);
2082
2083 /* Get error log */
2084 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
2085 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
2086
2087 /* Log */
2088 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
2089 << &message[0] << "\nShader source\n"
2090 << shader_code << tcu::TestLog::EndMessage;
2091
2092 TCU_FAIL("Failed to compile shader");
2093 }
2094 }
2095
2096 /** Attach shaders and link program
2097 *
2098 **/
link() const2099 void Utils::programInfo::link() const
2100 {
2101 /* GL entry points */
2102 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2103
2104 /* Link status */
2105 glw::GLint status = GL_FALSE;
2106
2107 /* Attach shaders */
2108 if (0 != m_fragment_shader_id)
2109 {
2110 gl.attachShader(m_program_object_id, m_fragment_shader_id);
2111 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2112 }
2113
2114 if (0 != m_vertex_shader_id)
2115 {
2116 gl.attachShader(m_program_object_id, m_vertex_shader_id);
2117 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
2118 }
2119
2120 /* Link */
2121 gl.linkProgram(m_program_object_id);
2122 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
2123
2124 /* Get link status */
2125 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
2126 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2127
2128 /* Log link error */
2129 if (GL_TRUE != status)
2130 {
2131 glw::GLint length = 0;
2132 std::vector<glw::GLchar> message;
2133
2134 /* Get error log length */
2135 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
2136 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
2137
2138 message.resize(length);
2139
2140 /* Get error log */
2141 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
2142 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
2143
2144 /* Log */
2145 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
2146 << &message[0] << tcu::TestLog::EndMessage;
2147
2148 TCU_FAIL("Failed to link program");
2149 }
2150 }
2151
2152 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
2153 *
2154 * @param token Token string
2155 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
2156 * @param text String that will be used as replacement for <token>
2157 * @param string String to work on
2158 **/
replaceToken(const glw::GLchar * token,size_t & search_position,const glw::GLchar * text,std::string & string)2159 void Utils::replaceToken(const glw::GLchar *token, size_t &search_position, const glw::GLchar *text,
2160 std::string &string)
2161 {
2162 const size_t text_length = strlen(text);
2163 const size_t token_length = strlen(token);
2164 const size_t token_position = string.find(token, search_position);
2165
2166 string.replace(token_position, token_length, text, text_length);
2167
2168 search_position = token_position + text_length;
2169 }
2170
2171 /** Constructor.
2172 *
2173 * @param context Rendering context.
2174 **/
APIErrorsTest(deqp::Context & context)2175 APIErrorsTest::APIErrorsTest(deqp::Context &context)
2176 : TestCase(context, "api_errors", "Verifies that errors are generated as specified")
2177 , m_id(0)
2178 {
2179 /* Left blank intentionally */
2180 }
2181
2182 /** Deinitialization **/
deinit()2183 void APIErrorsTest::deinit()
2184 {
2185 if (0 != m_id)
2186 {
2187 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2188
2189 gl.deleteTextures(1, &m_id);
2190 m_id = 0;
2191 }
2192 }
2193
2194 /** Executes test iteration.
2195 *
2196 * @return Returns STOP.
2197 */
iterate()2198 tcu::TestNode::IterateResult APIErrorsTest::iterate()
2199 {
2200 static const glw::GLint invalid_values[] = {0x1902, 0x1907, -1, 2};
2201 static const size_t n_invalid_values = sizeof(invalid_values) / sizeof(invalid_values[0]);
2202
2203 /* */
2204 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2205
2206 gl.genTextures(1, &m_id);
2207 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2208
2209 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_id);
2210 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2211
2212 /*
2213 * - INVALID_ENUM is generated by TexParameter* routines when <pname> is
2214 * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B,
2215 * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO,
2216 * ONE];
2217 */
2218 for (size_t i = 0; i < n_states; ++i)
2219 {
2220 for (size_t j = 0; j < n_valid_values; ++j)
2221 {
2222 const glw::GLenum state = states[i];
2223 const glw::GLint value = valid_values[j];
2224
2225 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2226 verifyError(GL_NO_ERROR);
2227 }
2228
2229 for (size_t j = 0; j < n_invalid_values; ++j)
2230 {
2231 const glw::GLenum state = states[i];
2232 const glw::GLint value = invalid_values[j];
2233
2234 gl.texParameteri(GL_TEXTURE_CUBE_MAP, state, value);
2235 verifyError(GL_INVALID_ENUM);
2236 }
2237 }
2238
2239 /*
2240 * - INVALID_ENUM is generated by TexParameter*v routines when <pname> is
2241 * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of
2242 * [RED, GREEN, BLUE, ALPHA, ZERO, ONE].
2243 */
2244 for (size_t i = 0; i < 4 /* number of channels */; ++i)
2245 {
2246 for (size_t j = 0; j < n_valid_values; ++j)
2247 {
2248 const glw::GLint value = valid_values[j];
2249
2250 glw::GLint param[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
2251
2252 param[i] = value;
2253
2254 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2255 verifyError(GL_NO_ERROR);
2256 }
2257
2258 for (size_t j = 0; j < n_invalid_values; ++j)
2259 {
2260 const glw::GLint value = invalid_values[j];
2261
2262 glw::GLint param[4] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
2263
2264 param[i] = value;
2265
2266 gl.texParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_RGBA, param);
2267 verifyError(GL_INVALID_ENUM);
2268 }
2269 }
2270
2271 /* Set result - exceptions are thrown in case of any error */
2272 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2273
2274 /* Done */
2275 return STOP;
2276 }
2277
2278 /** Verifies that proper error was generated
2279 *
2280 * @param expected_error
2281 **/
verifyError(const glw::GLenum expected_error)2282 void APIErrorsTest::verifyError(const glw::GLenum expected_error)
2283 {
2284 /* */
2285 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2286
2287 const glw::GLenum error = gl.getError();
2288
2289 if (expected_error != error)
2290 {
2291 TCU_FAIL("Got invalid error");
2292 }
2293 }
2294
2295 /** Constructor.
2296 *
2297 * @param context Rendering context.
2298 **/
IntialStateTest(deqp::Context & context)2299 IntialStateTest::IntialStateTest(deqp::Context &context)
2300 : TestCase(context, "intial_state", "Verifies that initial states are as specified")
2301 , m_id(0)
2302 {
2303 /* Left blank intentionally */
2304 }
2305
2306 /** Deinitialization **/
deinit()2307 void IntialStateTest::deinit()
2308 {
2309 if (0 != m_id)
2310 {
2311 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2312
2313 gl.deleteTextures(1, &m_id);
2314 m_id = 0;
2315 }
2316 }
2317
2318 /** Executes test iteration.
2319 *
2320 * @return Returns STOP.
2321 */
iterate()2322 tcu::TestNode::IterateResult IntialStateTest::iterate()
2323 {
2324 /* */
2325 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2326
2327 gl.genTextures(1, &m_id);
2328 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
2329
2330 for (size_t tex_tgt_idx = 0; tex_tgt_idx < n_texture_targets; ++tex_tgt_idx)
2331 {
2332 const glw::GLenum target = texture_targets[tex_tgt_idx].m_target;
2333
2334 gl.bindTexture(target, m_id);
2335 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2336
2337 verifyValues(target);
2338
2339 deinit();
2340 }
2341
2342 /* Set result - exceptions are thrown in case of any error */
2343 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2344
2345 /* Done */
2346 return STOP;
2347 }
2348
2349 /** Verifies that proper error was generated
2350 *
2351 * @param expected_error
2352 **/
verifyValues(const glw::GLenum texture_target)2353 void IntialStateTest::verifyValues(const glw::GLenum texture_target)
2354 {
2355 /* */
2356 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2357
2358 glw::GLint red = 0;
2359 glw::GLint green = 0;
2360 glw::GLint blue = 0;
2361 glw::GLint alpha = 0;
2362 glw::GLint param[4] = {0};
2363
2364 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_R, &red);
2365 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2366 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_G, &green);
2367 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2368 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_B, &blue);
2369 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2370 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_A, &alpha);
2371 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2372 gl.getTexParameterIiv(texture_target, GL_TEXTURE_SWIZZLE_RGBA, param);
2373 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexParameterIiv");
2374
2375 if (GL_RED != red)
2376 {
2377 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_R");
2378 }
2379 if (GL_GREEN != green)
2380 {
2381 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_G");
2382 }
2383 if (GL_BLUE != blue)
2384 {
2385 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_B");
2386 }
2387 if (GL_ALPHA != alpha)
2388 {
2389 TCU_FAIL("Got invalid initial state for TEXTURE_SWIZZLE_A");
2390 }
2391
2392 if (GL_RED != param[0])
2393 {
2394 TCU_FAIL("Got invalid initial red state for TEXTURE_SWIZZLE_RGBA");
2395 }
2396 if (GL_GREEN != param[1])
2397 {
2398 TCU_FAIL("Got invalid initial green state for TEXTURE_SWIZZLE_RGBA");
2399 }
2400 if (GL_BLUE != param[2])
2401 {
2402 TCU_FAIL("Got invalid initial blue state for TEXTURE_SWIZZLE_RGBA");
2403 }
2404 if (GL_ALPHA != param[3])
2405 {
2406 TCU_FAIL("Got invalid initial alpha state for TEXTURE_SWIZZLE_RGBA");
2407 }
2408 }
2409
2410 /* Constants used by SmokeTest */
2411 const glw::GLsizei SmokeTest::m_depth = 1;
2412 const glw::GLsizei SmokeTest::m_height = 1;
2413 const glw::GLsizei SmokeTest::m_width = 1;
2414 const glw::GLsizei SmokeTest::m_output_height = 8;
2415 const glw::GLsizei SmokeTest::m_output_width = 8;
2416
2417 /** Constructor.
2418 *
2419 * @param context Rendering context.
2420 **/
SmokeTest(deqp::Context & context)2421 SmokeTest::SmokeTest(deqp::Context &context)
2422 : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines")
2423 , m_is_ms_supported(false)
2424 , m_prepare_fbo_id(0)
2425 , m_out_tex_id(0)
2426 , m_source_tex_id(0)
2427 , m_test_fbo_id(0)
2428 , m_vao_id(0)
2429 , m_access_idx(0)
2430 , m_channel_idx(0)
2431 {
2432 /* Left blank intentionally */
2433 }
2434
2435 /** Constructor.
2436 *
2437 * @param context Rendering context.
2438 **/
SmokeTest(deqp::Context & context,size_t access_idx,size_t channel_idx)2439 SmokeTest::SmokeTest(deqp::Context &context, size_t access_idx, size_t channel_idx)
2440 : TestCase(context, "smoke", "Verifies that all swizzle combinations work with all texture access routines")
2441 , m_is_ms_supported(false)
2442 , m_prepare_fbo_id(0)
2443 , m_out_tex_id(0)
2444 , m_source_tex_id(0)
2445 , m_test_fbo_id(0)
2446 , m_vao_id(0)
2447 , m_access_idx(access_idx)
2448 , m_channel_idx(channel_idx)
2449 {
2450 std::string name =
2451 "smoke_access_idx_" + std::to_string(m_access_idx) + "_channel_idx_" + std::to_string(m_channel_idx);
2452
2453 TestCase::m_name = name;
2454 }
2455
2456 /** Constructor.
2457 *
2458 * @param context Rendering context.
2459 **/
SmokeTest(deqp::Context & context,const glw::GLchar * name,const glw::GLchar * description)2460 SmokeTest::SmokeTest(deqp::Context &context, const glw::GLchar *name, const glw::GLchar *description)
2461 : TestCase(context, name, description)
2462 , m_is_ms_supported(false)
2463 , m_prepare_fbo_id(0)
2464 , m_out_tex_id(0)
2465 , m_source_tex_id(0)
2466 , m_test_fbo_id(0)
2467 , m_vao_id(0)
2468 , m_access_idx(0)
2469 , m_channel_idx(0)
2470 {
2471 /* Left blank intentionally */
2472 }
2473
2474 /** Deinitialization **/
deinit()2475 void SmokeTest::deinit()
2476 {
2477 deinitTextures();
2478
2479 if (m_prepare_fbo_id != 0)
2480 {
2481 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2482 gl.deleteFramebuffers(1, &m_prepare_fbo_id);
2483
2484 m_prepare_fbo_id = 0;
2485 }
2486
2487 if (m_test_fbo_id != 0)
2488 {
2489 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2490 gl.deleteFramebuffers(1, &m_test_fbo_id);
2491
2492 m_test_fbo_id = 0;
2493 }
2494
2495 if (m_vao_id != 0)
2496 {
2497 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2498 gl.deleteVertexArrays(1, &m_vao_id);
2499
2500 m_vao_id = 0;
2501 }
2502 }
2503
2504 /** Executes test iteration.
2505 *
2506 * @return Returns STOP.
2507 */
iterate()2508 tcu::TestNode::IterateResult SmokeTest::iterate()
2509 {
2510 static const glw::GLenum tested_format = GL_RGBA32UI;
2511 static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY;
2512
2513 const size_t format_idx = get_index_of_format(tested_format);
2514 const size_t tgt_idx = get_index_of_target(tested_target);
2515
2516 glw::GLint source_channel_sizes[4] = {0};
2517
2518 /* */
2519 testInit();
2520
2521 if (false == isTargetSupported(tgt_idx))
2522 {
2523 throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__);
2524 }
2525
2526 /* Prepare and fill source texture */
2527 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
2528 if (false == fillSourceTexture(format_idx, tgt_idx))
2529 {
2530 TCU_FAIL("Failed to prepare source texture");
2531 }
2532
2533 /* Skip invalid cases */
2534 if (false == isTargetSuppByAccess(m_access_idx, tgt_idx))
2535 {
2536 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
2537 return STOP;
2538 }
2539
2540 for (size_t r = 0; r < TextureSwizzle::n_valid_values; ++r)
2541 {
2542 for (size_t g = 0; g < TextureSwizzle::n_valid_values; ++g)
2543 {
2544 for (size_t b = 0; b < TextureSwizzle::n_valid_values; ++b)
2545 {
2546 for (size_t a = 0; a < TextureSwizzle::n_valid_values; ++a)
2547 {
2548 const testCase test_case = {m_channel_idx,
2549 format_idx,
2550 tgt_idx,
2551 m_access_idx,
2552 valid_values[r],
2553 valid_values[g],
2554 valid_values[b],
2555 valid_values[a],
2556 {source_channel_sizes[0], source_channel_sizes[1],
2557 source_channel_sizes[2], source_channel_sizes[3]}};
2558
2559 executeTestCase(test_case);
2560
2561 deinitOutputTexture();
2562 }
2563 }
2564 }
2565 }
2566
2567 /* Set result - exceptions are thrown in case of any error */
2568 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2569
2570 /* Done */
2571 return STOP;
2572 }
2573
2574 /** Deinitialization of output texture **/
deinitOutputTexture()2575 void SmokeTest::deinitOutputTexture()
2576 {
2577 if (m_out_tex_id != 0)
2578 {
2579 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2580 gl.deleteTextures(1, &m_out_tex_id);
2581
2582 m_out_tex_id = 0;
2583 }
2584 }
2585
2586 /** Deinitialization of textures **/
deinitTextures()2587 void SmokeTest::deinitTextures()
2588 {
2589 deinitOutputTexture();
2590
2591 if (m_source_tex_id != 0)
2592 {
2593 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2594 gl.deleteTextures(1, &m_source_tex_id);
2595
2596 m_source_tex_id = 0;
2597 }
2598 }
2599
2600 /** Captures and verifies contents of output texture
2601 *
2602 * @param test_case Test case instance
2603 * @param output_format_index Index of format used by output texture
2604 * @parma output_channel_size Size of storage used by output texture in bits
2605 * @param index_of_swizzled_channel Index of swizzled channel
2606 */
captureAndVerify(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel)2607 void SmokeTest::captureAndVerify(const testCase &test_case, size_t output_format_index, glw::GLint output_channel_size,
2608 size_t index_of_swizzled_channel)
2609 {
2610 const _texture_format &output_format = texture_formats[output_format_index];
2611
2612 /* */
2613 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2614
2615 /* Storage for image data */
2616 glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)];
2617
2618 /* Get image data */
2619 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2620 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2621
2622 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, output_format.m_format, output_format.m_type, result_image);
2623 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
2624
2625 /* Unbind output texture */
2626 gl.bindTexture(GL_TEXTURE_2D, 0);
2627 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2628
2629 /* Verification */
2630 verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image);
2631 }
2632
2633 /** Draws four points
2634 *
2635 * @param target Target of source texture
2636 * @param texture_swizzle Set of texture swizzle values
2637 * @param use_rgba_enum If texture swizzle states should be set with RGBA enum or separe calls
2638 **/
draw(glw::GLenum target,const glw::GLint * texture_swizzle,bool use_rgba_enum)2639 void SmokeTest::draw(glw::GLenum target, const glw::GLint *texture_swizzle, bool use_rgba_enum)
2640 {
2641 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2642
2643 /* Prepare source texture */
2644 gl.activeTexture(GL_TEXTURE0);
2645 GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
2646
2647 gl.bindTexture(target, m_source_tex_id);
2648 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2649
2650 /* Set texture swizzle */
2651 if (true == use_rgba_enum)
2652 {
2653 gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle);
2654 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv");
2655 }
2656 else
2657 {
2658 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, texture_swizzle[0]);
2659 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, texture_swizzle[1]);
2660 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, texture_swizzle[2]);
2661 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, texture_swizzle[3]);
2662 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2663 }
2664
2665 /* Clear */
2666 gl.clear(GL_COLOR_BUFFER_BIT);
2667 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2668
2669 /* Draw */
2670 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
2671 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2672
2673 /* Revert texture swizzle */
2674 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2675 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2676 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2677 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2678 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2679
2680 /* Unbind source texture */
2681 gl.bindTexture(target, 0);
2682 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2683 }
2684
2685 /** Executes test case
2686 *
2687 * @param test_case Test case instance
2688 **/
executeTestCase(const testCase & test_case)2689 void SmokeTest::executeTestCase(const testCase &test_case)
2690 {
2691 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2692 const glw::GLint red = test_case.m_texture_swizzle_red;
2693 const glw::GLint green = test_case.m_texture_swizzle_green;
2694 const glw::GLint blue = test_case.m_texture_swizzle_blue;
2695 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
2696 const glw::GLint param[4] = {red, green, blue, alpha};
2697 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
2698 glw::GLint out_channel_size = 0;
2699 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
2700 const size_t out_format_idx = get_index_of_format(out_internal_format);
2701
2702 /* */
2703 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2704
2705 /* Prepare output */
2706 prepareOutputTexture(out_format_idx);
2707
2708 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2709 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2710
2711 gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id);
2712 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2713
2714 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_out_tex_id, 0 /* level */);
2715 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
2716
2717 /* Set Viewport */
2718 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
2719 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2720
2721 /* Get internal storage size of output texture */
2722 gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_RED_SIZE, &out_channel_size);
2723 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
2724
2725 /* Unbind output texture */
2726 gl.bindTexture(GL_TEXTURE_2D, 0);
2727 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2728
2729 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true);
2730 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false);
2731
2732 /* Unbind FBO */
2733 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2734 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2735 }
2736
2737 /** Fills source texture
2738 *
2739 * @param format_idx Index of format
2740 * @param target_idx Index of target
2741 *
2742 * @return True if operation was successful, false other wise
2743 **/
fillSourceTexture(size_t format_idx,size_t target_idx)2744 bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx)
2745 {
2746 static const glw::GLuint rgba32ui[4] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff};
2747
2748 const glw::GLenum target = texture_targets[target_idx].m_target;
2749 const _texture_format &texture_format = texture_formats[format_idx];
2750
2751 /* */
2752 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2753 const glw::GLvoid *data = 0;
2754
2755 /* Bind texture and FBO */
2756 gl.bindTexture(target, m_source_tex_id);
2757 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2758
2759 /* Set color */
2760 switch (texture_format.m_internal_format)
2761 {
2762 case GL_RGBA32UI:
2763 data = (const glw::GLubyte *)rgba32ui;
2764 break;
2765
2766 default:
2767 TCU_FAIL("Invalid enum");
2768 }
2769
2770 /* Attach texture */
2771 switch (target)
2772 {
2773 case GL_TEXTURE_2D_ARRAY:
2774 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
2775 texture_format.m_format, texture_format.m_type, data);
2776 break;
2777
2778 default:
2779 TCU_FAIL("Invalid enum");
2780 }
2781
2782 /* Unbind */
2783 gl.bindTexture(target, 0);
2784 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2785
2786 /* Done */
2787 return true;
2788 }
2789
2790 /** Gets source of fragment shader
2791 *
2792 * @param test_case Test case instance
2793 * @param output_format_index Index of output format
2794 * @param is_tested_stage Selects if fragment or vertex shader makes texture access
2795 *
2796 * @return Source of shader
2797 **/
getFragmentShader(const testCase & test_case,size_t output_format_index,bool is_tested_stage)2798 std::string SmokeTest::getFragmentShader(const testCase &test_case, size_t output_format_index, bool is_tested_stage)
2799 {
2800 static const glw::GLchar *fs_blank_template = "#version 330 core\n"
2801 "\n"
2802 "flat in BASIC_TYPE result;\n"
2803 "\n"
2804 "out BASIC_TYPE out_color;\n"
2805 "\n"
2806 "void main()\n"
2807 "{\n"
2808 " out_color = result;\n"
2809 "}\n"
2810 "\n";
2811
2812 static const glw::GLchar *fs_test_template = "#version 330 core\n"
2813 "\n"
2814 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2815 "\n"
2816 "out BASIC_TYPE out_color;\n"
2817 "\n"
2818 "void main()\n"
2819 "{\n"
2820 " BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2821 "\n"
2822 " out_color = result;\n"
2823 "}\n"
2824 "\n";
2825
2826 /* */
2827 const std::string &arguments = prepareArguments(test_case);
2828 const _texture_access &access = texture_access[test_case.m_texture_access_index];
2829 const glw::GLchar *channel = channels[test_case.m_channel_index];
2830 const _texture_format &output_format = texture_formats[output_format_index];
2831 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2832 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
2833
2834 std::string fs;
2835 size_t position = 0;
2836
2837 if (is_tested_stage)
2838 {
2839 fs = fs_test_template;
2840
2841 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, fs);
2842 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, fs);
2843 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2844 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2845 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, fs);
2846 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), fs);
2847 Utils::replaceToken("CHANNEL", position, channel, fs);
2848 }
2849 else
2850 {
2851 fs = fs_blank_template;
2852
2853 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2854 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2855 }
2856
2857 return fs;
2858 }
2859
2860 /** Gets source of vertex shader
2861 *
2862 * @param test_case Test case instance
2863 * @param is_tested_stage Selects if vertex or fragment shader makes texture access
2864 *
2865 * @return Source of shader
2866 **/
getVertexShader(const testCase & test_case,bool is_tested_stage)2867 std::string SmokeTest::getVertexShader(const testCase &test_case, bool is_tested_stage)
2868 {
2869 static const glw::GLchar *vs_blank_template = "#version 330 core\n"
2870 "\n"
2871 "void main()\n"
2872 "{\n"
2873 " switch (gl_VertexID)\n"
2874 " {\n"
2875 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2876 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2877 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2878 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2879 " }\n"
2880 "}\n"
2881 "\n";
2882
2883 static const glw::GLchar *vs_test_template = "#version 330 core\n"
2884 "\n"
2885 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2886 "\n"
2887 "flat out BASIC_TYPE result;\n"
2888 "\n"
2889 "void main()\n"
2890 "{\n"
2891 " result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2892 "\n"
2893 " switch (gl_VertexID)\n"
2894 " {\n"
2895 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2896 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2897 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2898 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2899 " }\n"
2900 "}\n"
2901 "\n";
2902
2903 std::string vs;
2904
2905 if (is_tested_stage)
2906 {
2907 /* */
2908 const std::string &arguments = prepareArguments(test_case);
2909 const _texture_access &access = texture_access[test_case.m_texture_access_index];
2910 const glw::GLchar *channel = channels[test_case.m_channel_index];
2911 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2912 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
2913
2914 size_t position = 0;
2915
2916 vs = vs_test_template;
2917
2918 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, vs);
2919 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, vs);
2920 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, vs);
2921 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, vs);
2922 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), vs);
2923 Utils::replaceToken("CHANNEL", position, channel, vs);
2924 }
2925 else
2926 {
2927 vs = vs_blank_template;
2928 }
2929
2930 return vs;
2931 }
2932
2933 /** Check if target is supported
2934 *
2935 * @param target_idx Index of target
2936 *
2937 * @return true if target is supported, false otherwise
2938 **/
isTargetSupported(size_t target_idx)2939 bool SmokeTest::isTargetSupported(size_t target_idx)
2940 {
2941 const _texture_target &target = texture_targets[target_idx];
2942
2943 bool is_supported = true;
2944
2945 switch (target.m_target)
2946 {
2947 case GL_TEXTURE_2D_MULTISAMPLE:
2948 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2949 is_supported = m_is_ms_supported;
2950 break;
2951
2952 default:
2953 break;
2954 }
2955
2956 return is_supported;
2957 }
2958
2959 /** Check if target is supported by access routine
2960 *
2961 * @param access_idx Index of access routine
2962 * @param target_idx Index of target
2963 *
2964 * @return true if target is supported, false otherwise
2965 **/
isTargetSuppByAccess(size_t access_idx,size_t target_idx)2966 bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx)
2967 {
2968 const _texture_access &access = texture_access[access_idx];
2969 const _texture_target &source_target = texture_targets[target_idx];
2970
2971 if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates))
2972 {
2973 /* Cases are not valid, texelFetch* is not supported by the target */
2974 return false;
2975 }
2976
2977 if ((false == source_target.m_support_offset) && (true == access.m_use_offsets))
2978 {
2979 /* Cases are not valid, texture*Offset is not supported by the target */
2980 return false;
2981 }
2982
2983 if ((false == source_target.m_support_lod) && (true == access.m_use_lod))
2984 {
2985 /* Access is one of texture*Lod* or texelFetch* */
2986 /* Target is one of MS or rect */
2987
2988 if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling))
2989 {
2990 /* texelFetch */
2991 /* One of MS targets */
2992 return true;
2993 }
2994
2995 /* Cases are not valid, either lod or sample is required but target does not supported that */
2996 return false;
2997 }
2998
2999 if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates))
3000 {
3001 /* Cases are not valid, textureProj* is not supported by the target */
3002 return false;
3003 }
3004
3005 if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling))
3006 {
3007 /* Cases are not valid, texelFetch* is not supported by the target */
3008 return false;
3009 }
3010
3011 return true;
3012 }
3013
3014 /** Check if target is supported by format
3015 *
3016 * @param format_idx Index of format
3017 * @param target_idx Index of target
3018 *
3019 * @return true if target is supported, false otherwise
3020 **/
isTargetSuppByFormat(size_t format_idx,size_t target_idx)3021 bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx)
3022 {
3023 const _texture_format &format = texture_formats[format_idx];
3024 const _texture_target &source_target = texture_targets[target_idx];
3025
3026 bool is_supported = true;
3027
3028 switch (format.m_internal_format)
3029 {
3030 case GL_DEPTH_COMPONENT16:
3031 case GL_DEPTH_COMPONENT24:
3032 case GL_DEPTH_COMPONENT32:
3033 case GL_DEPTH_COMPONENT32F:
3034 case GL_DEPTH24_STENCIL8:
3035 case GL_DEPTH32F_STENCIL8:
3036 switch (source_target.m_target)
3037 {
3038 case GL_TEXTURE_3D:
3039 case GL_TEXTURE_2D_MULTISAMPLE:
3040 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3041 is_supported = false;
3042 break;
3043 default:
3044 break;
3045 }
3046 break;
3047
3048 case GL_RGB9_E5:
3049 switch (source_target.m_target)
3050 {
3051 case GL_TEXTURE_2D_MULTISAMPLE:
3052 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3053 is_supported = false;
3054 break;
3055 default:
3056 break;
3057 }
3058 break;
3059
3060 default:
3061 break;
3062 }
3063
3064 return is_supported;
3065 }
3066
3067 /** Logs details of test case
3068 *
3069 * @parma test_case Test case instance
3070 **/
logTestCaseDetials(const testCase & test_case)3071 void SmokeTest::logTestCaseDetials(const testCase &test_case)
3072 {
3073 const glw::GLenum target = texture_targets[test_case.m_source_texture_target_index].m_target;
3074 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
3075 const glw::GLint red = test_case.m_texture_swizzle_red;
3076 const glw::GLint green = test_case.m_texture_swizzle_green;
3077 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3078 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3079 const glw::GLint param[4] = {red, green, blue, alpha};
3080 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
3081 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
3082 const size_t out_format_idx = get_index_of_format(out_internal_format);
3083 const _texture_format &output_format = texture_formats[out_format_idx];
3084
3085 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case details. Source texture: Target: "
3086 << glu::getTextureTargetStr(target)
3087 << ". Format: " << glu::getTextureFormatName(source_format.m_internal_format)
3088 << ", " << glu::getTextureFormatName(source_format.m_format) << ", "
3089 << glu::getTypeStr(source_format.m_type)
3090 << ", DS: " << glu::getTextureDepthStencilModeName(source_format.m_ds_mode)
3091 << ". Swizzle: [" << glu::getTextureSwizzleStr(red) << ", "
3092 << glu::getTextureSwizzleStr(green) << ", " << glu::getTextureSwizzleStr(blue)
3093 << ", " << glu::getTextureSwizzleStr(alpha)
3094 << "]. Channel: " << channels[test_case.m_channel_index]
3095 << ". Access: " << texture_access[test_case.m_texture_access_index].m_name
3096 << ". Output texture: Format: "
3097 << glu::getTextureFormatName(output_format.m_internal_format) << ", "
3098 << glu::getTextureFormatName(output_format.m_format) << ", "
3099 << glu::getTypeStr(output_format.m_type) << "." << tcu::TestLog::EndMessage;
3100 }
3101
3102 /** Prepares program then draws and verifies resutls for both ways of setting texture swizzle
3103 *
3104 * @param test_case Test case instance
3105 * @param output_format_index Index of format used by output texture
3106 * @parma output_channel_size Size of storage used by output texture in bits
3107 * @param index_of_swizzled_channel Index of swizzled channel
3108 * @param test_vertex_stage Selects if vertex or fragment shader should execute texture access
3109 **/
prepareAndTestProgram(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel,bool test_vertex_stage)3110 void SmokeTest::prepareAndTestProgram(const testCase &test_case, size_t output_format_index,
3111 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
3112 bool test_vertex_stage)
3113 {
3114 const _texture_target &source_target = texture_targets[test_case.m_source_texture_target_index];
3115 const glw::GLint red = test_case.m_texture_swizzle_red;
3116 const glw::GLint green = test_case.m_texture_swizzle_green;
3117 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3118 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3119 const glw::GLint param[4] = {red, green, blue, alpha};
3120
3121 /* */
3122 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3123
3124 /* Prepare program */
3125 const std::string &fs = getFragmentShader(test_case, output_format_index, !test_vertex_stage);
3126 const std::string &vs = getVertexShader(test_case, test_vertex_stage);
3127
3128 Utils::programInfo program(m_context);
3129 program.build(fs.c_str(), vs.c_str());
3130
3131 gl.useProgram(program.m_program_object_id);
3132 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3133
3134 /* Prepare sampler */
3135 glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler");
3136 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3137
3138 if (-1 == location)
3139 {
3140 TCU_FAIL("Uniform is not available");
3141 }
3142
3143 gl.uniform1i(location, 0 /* texture unit */);
3144 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3145
3146 draw(source_target.m_target, param, false);
3147 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3148
3149 draw(source_target.m_target, param, true);
3150 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3151 }
3152
3153 /** Prepares arguments for texture access routine call
3154 *
3155 * @param test_case Test case instance
3156 *
3157 * @return Source code
3158 **/
prepareArguments(const testCase & test_case)3159 std::string SmokeTest::prepareArguments(const testCase &test_case)
3160 {
3161 const _texture_access &access = texture_access[test_case.m_texture_access_index];
3162 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3163
3164 std::string arguments = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE";
3165 const std::string &coordinates = prepareCoordinates(test_case);
3166
3167 size_t position = 0;
3168
3169 Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments);
3170
3171 if ((true == access.m_use_lod) && (true == target.m_support_lod))
3172 {
3173 Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments);
3174 }
3175 else if (true == access.m_use_derivaties)
3176 {
3177 const std::string &derivatives_0 = prepareDerivatives(test_case, 0);
3178 const std::string &derivatives_1 = prepareDerivatives(test_case, 1);
3179 const size_t start_pos = position;
3180
3181 Utils::replaceToken("LODDERIVATIVES", position, ", XXXXX, XXXXX", arguments);
3182 position = start_pos + 2;
3183 Utils::replaceToken("XXXXX", position, derivatives_0.c_str(), arguments);
3184 Utils::replaceToken("XXXXX", position, derivatives_1.c_str(), arguments);
3185 }
3186 else
3187 {
3188 Utils::replaceToken("LODDERIVATIVES", position, "", arguments);
3189 }
3190
3191 if (true == access.m_use_offsets)
3192 {
3193 const std::string &offsets = prepareOffsets(test_case);
3194 const size_t start_pos = position;
3195
3196 Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments);
3197 position = start_pos + 2;
3198 Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments);
3199 }
3200 else
3201 {
3202 Utils::replaceToken("OFFSETS", position, "", arguments);
3203 }
3204
3205 if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling))
3206 {
3207 const std::string &sample = prepareSample();
3208 const size_t start_pos = position;
3209
3210 Utils::replaceToken("SAMPLE", position, ", XX", arguments);
3211 position = start_pos + 2;
3212 Utils::replaceToken("XX", position, sample.c_str(), arguments);
3213 }
3214 else
3215 {
3216 Utils::replaceToken("SAMPLE", position, "", arguments);
3217 }
3218
3219 return arguments;
3220 }
3221
3222 /** Prepares coordinate for texture access routine call
3223 *
3224 * @param test_case Test case instance
3225 *
3226 * @return Source code
3227 **/
prepareCoordinates(const testCase & test_case)3228 std::string SmokeTest::prepareCoordinates(const testCase &test_case)
3229 {
3230 const _texture_access &access = texture_access[test_case.m_texture_access_index];
3231 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3232
3233 const glw::GLchar *type = 0;
3234
3235 std::string coordinates = "TYPE(VAL_LIST)";
3236
3237 if (false == access.m_use_integral_coordinates)
3238 {
3239 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3240 {
3241 case 1:
3242 type = "float";
3243 break;
3244 case 2:
3245 type = "vec2";
3246 break;
3247 case 3:
3248 type = "vec3";
3249 break;
3250 case 4:
3251 type = "vec4";
3252 break;
3253 default:
3254 TCU_FAIL("Invalid value");
3255 }
3256 }
3257 else
3258 {
3259 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3260 {
3261 case 1:
3262 type = "int";
3263 break;
3264 case 2:
3265 type = "ivec2";
3266 break;
3267 case 3:
3268 type = "ivec3";
3269 break;
3270 case 4:
3271 type = "ivec4";
3272 break;
3273 default:
3274 TCU_FAIL("Invalid value");
3275 }
3276 }
3277
3278 size_t position = 0;
3279
3280 Utils::replaceToken("TYPE", position, type, coordinates);
3281
3282 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3283 {
3284 size_t start_position = position;
3285
3286 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3287
3288 position = start_position + 1;
3289 }
3290
3291 for (size_t i = 0; i < target.m_n_array_coordinates; ++i)
3292 {
3293 size_t start_position = position;
3294
3295 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3296
3297 position = start_position + 1;
3298 }
3299
3300 for (size_t i = 0; i < access.m_n_coordinates; ++i)
3301 {
3302 size_t start_position = position;
3303
3304 Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates);
3305
3306 position = start_position + 1;
3307 }
3308
3309 Utils::replaceToken(", VAL_LIST", position, "", coordinates);
3310
3311 return coordinates;
3312 }
3313
3314 /** Prepares derivatives for texture access routine call
3315 *
3316 * @param test_case Test case instance
3317 *
3318 * @return Source code
3319 **/
prepareDerivatives(const testCase & test_case,size_t index)3320 std::string SmokeTest::prepareDerivatives(const testCase &test_case, size_t index)
3321 {
3322 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3323
3324 const glw::GLchar *type = 0;
3325
3326 std::string derivatives = "TYPE(VAL_LIST)";
3327
3328 switch (target.m_n_derivatives)
3329 {
3330 case 1:
3331 type = "float";
3332 break;
3333 case 2:
3334 type = "vec2";
3335 break;
3336 case 3:
3337 type = "vec3";
3338 break;
3339 case 4:
3340 type = "vec4";
3341 break;
3342 default:
3343 TCU_FAIL("Invalid value");
3344 }
3345
3346 size_t position = 0;
3347
3348 Utils::replaceToken("TYPE", position, type, derivatives);
3349
3350 for (size_t i = 0; i < target.m_n_derivatives; ++i)
3351 {
3352 size_t start_position = position;
3353
3354 if (index == i)
3355 {
3356 Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives);
3357 }
3358 else
3359 {
3360 Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives);
3361 }
3362
3363 position = start_position + 1;
3364 }
3365
3366 Utils::replaceToken(", VAL_LIST", position, "", derivatives);
3367
3368 return derivatives;
3369 }
3370
3371 /** Prepares offsets for texture access routine call
3372 *
3373 * @param test_case Test case instance
3374 *
3375 * @return Source code
3376 **/
prepareOffsets(const testCase & test_case)3377 std::string SmokeTest::prepareOffsets(const testCase &test_case)
3378 {
3379 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3380
3381 const glw::GLchar *type = nullptr;
3382
3383 std::string offsets = "TYPE(VAL_LIST)";
3384
3385 switch (target.m_n_derivatives)
3386 {
3387 case 1:
3388 type = "int";
3389 break;
3390 case 2:
3391 type = "ivec2";
3392 break;
3393 case 3:
3394 type = "ivec3";
3395 break;
3396 case 4:
3397 type = "ivec4";
3398 break;
3399 default:
3400 TCU_FAIL("Invalid value");
3401 }
3402
3403 size_t position = 0;
3404
3405 Utils::replaceToken("TYPE", position, type, offsets);
3406
3407 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3408 {
3409 size_t start_position = position;
3410
3411 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets);
3412
3413 position = start_position + 1;
3414 }
3415
3416 Utils::replaceToken(", VAL_LIST", position, "", offsets);
3417
3418 return offsets;
3419 }
3420
3421 /** Prepares output texture
3422 *
3423 * @param format_idx Index of texture format
3424 **/
prepareOutputTexture(size_t format_idx)3425 void SmokeTest::prepareOutputTexture(size_t format_idx)
3426 {
3427 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3428
3429 const _texture_format &format = texture_formats[format_idx];
3430
3431 gl.genTextures(1, &m_out_tex_id);
3432 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3433
3434 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
3435 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3436
3437 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, format.m_internal_format, m_output_width, m_output_height,
3438 0 /* border */, format.m_format, format.m_type, 0 /* pixels */);
3439 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
3440
3441 gl.bindTexture(GL_TEXTURE_2D, 0);
3442 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3443 }
3444
3445 /** Prepares sample for texture access routine call
3446 *
3447 * @return Source code
3448 **/
prepareSample()3449 std::string SmokeTest::prepareSample()
3450 {
3451 glw::GLsizei samples = 1;
3452 std::stringstream stream;
3453
3454 /* Get max number of samples */
3455 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3456
3457 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3458 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3459
3460 stream << samples - 1;
3461
3462 return stream.str();
3463 }
3464
3465 /** Prepares source texture
3466 *
3467 * @param format_idx Index of texture format
3468 * @param target_idx Index of texture target
3469 * @param out_sizes Sizes of storage used for texture channels
3470 **/
prepareSourceTexture(size_t format_idx,size_t target_idx,glw::GLint out_sizes[4])3471 void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4])
3472 {
3473 static const glw::GLint border = 0;
3474 static const glw::GLint level = 0;
3475
3476 /* */
3477 const glw::GLenum target = texture_targets[target_idx].m_target;
3478 const _texture_format &texture_format = texture_formats[format_idx];
3479
3480 /* */
3481 glw::GLenum error = 0;
3482 const glw::GLenum format = texture_format.m_format;
3483 const glw::GLchar *function_name = "unknown";
3484 const glw::GLenum internal_format = texture_format.m_internal_format;
3485 glw::GLsizei samples = 1;
3486 glw::GLenum target_get_prm = target;
3487 const glw::GLenum type = texture_format.m_type;
3488
3489 /* */
3490 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3491
3492 /* Get max number of samples */
3493 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3494 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3495
3496 /* Generate and bind */
3497 gl.genTextures(1, &m_source_tex_id);
3498 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3499
3500 gl.bindTexture(target, m_source_tex_id);
3501 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3502
3503 /* Allocate storage */
3504 switch (target)
3505 {
3506 case GL_TEXTURE_1D:
3507
3508 gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */);
3509 error = gl.getError();
3510 function_name = "TexImage1D";
3511
3512 break;
3513
3514 case GL_TEXTURE_1D_ARRAY:
3515 case GL_TEXTURE_2D:
3516 case GL_TEXTURE_RECTANGLE:
3517 gl.texImage2D(target, level, internal_format, m_width, m_height, border, format, type, 0 /* pixels */);
3518 error = gl.getError();
3519 function_name = "TexImage2D";
3520
3521 break;
3522
3523 case GL_TEXTURE_2D_ARRAY:
3524 case GL_TEXTURE_3D:
3525 gl.texImage3D(target, level, internal_format, m_width, m_height, m_depth, border, format, type, 0 /* pixels */);
3526 error = gl.getError();
3527 function_name = "TexImage3D";
3528
3529 break;
3530
3531 case GL_TEXTURE_CUBE_MAP:
3532 for (size_t i = 0; i < n_cube_map_faces; ++i)
3533 {
3534 gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type,
3535 0 /* pixels */);
3536 }
3537 error = gl.getError();
3538 function_name = "TexImage2D";
3539
3540 target_get_prm = cube_map_faces[0];
3541
3542 break;
3543
3544 case GL_TEXTURE_2D_MULTISAMPLE:
3545 gl.texImage2DMultisample(target, samples, internal_format, m_width, m_height,
3546 GL_FALSE /* fixedsamplelocation */);
3547 error = gl.getError();
3548 function_name = "TexImage2DMultisample";
3549
3550 break;
3551
3552 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3553 gl.texImage3DMultisample(target, samples, internal_format, m_width, m_height, m_depth,
3554 GL_FALSE /* fixedsamplelocation */);
3555 error = gl.getError();
3556 function_name = "TexImage3DMultisample";
3557
3558 break;
3559
3560 default:
3561 TCU_FAIL("Invalid enum");
3562 }
3563
3564 /* Log error */
3565 GLU_EXPECT_NO_ERROR(error, function_name);
3566
3567 /* Make texture complete and set ds texture mode */
3568 if ((GL_TEXTURE_2D_MULTISAMPLE != target) && (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) &&
3569 (GL_TEXTURE_RECTANGLE != target))
3570 {
3571 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
3572 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3573
3574 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
3575 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3576
3577 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3578 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3579
3580 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3581 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3582 }
3583
3584 if (texture_format.m_ds_mode == GL_STENCIL_INDEX)
3585 {
3586 gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode);
3587 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3588 }
3589
3590 /* Get internal storage sizes */
3591 switch (internal_format)
3592 {
3593 case GL_DEPTH24_STENCIL8:
3594 case GL_DEPTH32F_STENCIL8:
3595
3596 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1);
3597 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3598
3599 /* Fall through */
3600
3601 case GL_DEPTH_COMPONENT16:
3602 case GL_DEPTH_COMPONENT24:
3603 case GL_DEPTH_COMPONENT32:
3604 case GL_DEPTH_COMPONENT32F:
3605
3606 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0);
3607 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3608
3609 break;
3610
3611 default:
3612
3613 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0);
3614 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3615
3616 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1);
3617 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3618
3619 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2);
3620 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3621
3622 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3);
3623 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3624
3625 break;
3626 }
3627
3628 /* Unbind texture */
3629 gl.bindTexture(target, 0);
3630 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3631 }
3632
3633 /** Initializes frame buffer and vertex array
3634 *
3635 **/
testInit()3636 void SmokeTest::testInit()
3637 {
3638 /* */
3639 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3640
3641 glw::GLint major = 0;
3642 glw::GLint minor = 0;
3643
3644 gl.getIntegerv(GL_MAJOR_VERSION, &major);
3645 gl.getIntegerv(GL_MINOR_VERSION, &minor);
3646
3647 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3648
3649 if (4 < major)
3650 {
3651 m_is_ms_supported = true;
3652 }
3653 else if (4 == major)
3654 {
3655 if (3 <= minor)
3656 {
3657 m_is_ms_supported = true;
3658 }
3659 }
3660
3661 /* Context is below 4.3 */
3662 if (false == m_is_ms_supported)
3663 {
3664 m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
3665 }
3666
3667 #if ENABLE_DEBUG
3668
3669 gl.debugMessageCallback(debug_proc, &m_context);
3670 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
3671
3672 #endif /* ENABLE_DEBUG */
3673
3674 /* Prepare FBOs */
3675 gl.genFramebuffers(1, &m_prepare_fbo_id);
3676 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3677
3678 gl.genFramebuffers(1, &m_test_fbo_id);
3679 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3680
3681 /* Prepare blank VAO */
3682 gl.genVertexArrays(1, &m_vao_id);
3683 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
3684
3685 gl.bindVertexArray(m_vao_id);
3686 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3687 }
3688
3689 /** Verifies contents of output image
3690 *
3691 * @param test_case Test case instance
3692 * @param ignored
3693 * @param ignored
3694 * @param index_of_swizzled_channel Index of swizzled channel
3695 * @param data Image contents
3696 **/
verifyOutputImage(const testCase & test_case,size_t,glw::GLint,size_t index_of_swizzled_channel,const glw::GLubyte * data)3697 void SmokeTest::verifyOutputImage(const testCase &test_case, size_t /* output_format_index */,
3698 glw::GLint /* output_channel_size */, size_t index_of_swizzled_channel,
3699 const glw::GLubyte *data)
3700 {
3701 static const glw::GLuint rgba32ui[6] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0};
3702
3703 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
3704
3705 /* Set color */
3706 switch (source_format.m_internal_format)
3707 {
3708 case GL_RGBA32UI:
3709 {
3710 glw::GLuint expected_value = rgba32ui[index_of_swizzled_channel];
3711 const glw::GLuint *image = (glw::GLuint *)data;
3712
3713 for (size_t i = 0; i < m_output_width * m_output_height; ++i)
3714 {
3715 if (image[i] != expected_value)
3716 {
3717 TCU_FAIL("Found pixel with wrong value");
3718 }
3719 }
3720 }
3721 break;
3722
3723 default:
3724 TCU_FAIL("Invalid enum");
3725 }
3726 }
3727
3728 /** Constructor.
3729 *
3730 * @param context Rendering context.
3731 **/
FunctionalTest(deqp::Context & context,size_t format_idx,size_t tgt_idx)3732 FunctionalTest::FunctionalTest(deqp::Context &context, size_t format_idx, size_t tgt_idx)
3733 : SmokeTest(context, "functional",
3734 "Verifies that swizzle is respected for textures of different formats and targets")
3735 , m_format_idx(format_idx)
3736 , m_tgt_idx(tgt_idx)
3737 {
3738 std::string name = "functional_format_idx_" + std::to_string(format_idx) + "_target_idx_" + std::to_string(tgt_idx);
3739
3740 TestCase::m_name = name;
3741 }
3742
3743 /** Executes test iteration.
3744 *
3745 * @return Returns STOP.
3746 */
iterate()3747 tcu::TestNode::IterateResult FunctionalTest::iterate()
3748 {
3749 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0
3750
3751 static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */
3752
3753 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */
3754
3755 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0
3756
3757 static const size_t tested_swizzle_combinations[][4] = {
3758 {3, 2, 1, 0}, /* values are indices of entries in valid_values */
3759 {5, 4, 0, 3},
3760 {5, 5, 5, 5},
3761 {4, 4, 4, 4},
3762 {2, 2, 2, 2}};
3763 static const size_t n_tested_swizzle_combinations =
3764 sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]);
3765
3766 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */
3767
3768 /* */
3769 bool test_result = true;
3770 glw::GLint source_channel_sizes[4] = {0};
3771
3772 /* */
3773 testInit();
3774
3775 /* Iterate over all cases */
3776
3777 #if FUNCTIONAL_TEST_ALL_FORMATS
3778
3779 /* Check that format is supported by context. */
3780 if (!glu::contextSupports(m_context.getRenderContext().getType(),
3781 texture_formats[m_format_idx].m_minimum_gl_context))
3782 {
3783 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Format not supported");
3784 return STOP;
3785 }
3786
3787 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
3788
3789 /* Skip not supported targets */
3790 if (false == isTargetSupported(m_tgt_idx))
3791 {
3792 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3793 return STOP;
3794 }
3795
3796 /* Skip invalid cases */
3797 if (false == isTargetSuppByFormat(m_format_idx, m_tgt_idx))
3798 {
3799 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3800 return STOP;
3801 }
3802
3803 try
3804 {
3805 prepareSourceTexture(m_format_idx, m_tgt_idx, source_channel_sizes);
3806
3807 /* Skip formats not supported by FBO */
3808 if (false == fillSourceTexture(m_format_idx, m_tgt_idx))
3809 {
3810 deinitTextures();
3811 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Format not supported");
3812 return STOP;
3813 }
3814
3815 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3816
3817 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
3818 {
3819 /* Skip invalid cases */
3820 if (false == isTargetSuppByAccess(access_idx, m_tgt_idx))
3821 {
3822 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3823 return STOP;
3824 }
3825 #else /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3826 /* Skip invalid cases */
3827 if (false == isTargetSuppByAccess(access_idx, m_tgt_idx))
3828 {
3829 deinitTextures();
3830 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Target not supported");
3831 return STOP;
3832 }
3833 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3834
3835 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3836
3837 for (size_t r = 0; r < n_valid_values; ++r)
3838 {
3839 for (size_t g = 0; g < n_valid_values; ++g)
3840 {
3841 for (size_t b = 0; b < n_valid_values; ++b)
3842 {
3843 for (size_t a = 0; a < n_valid_values; ++a)
3844 {
3845
3846 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3847
3848 for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations; ++tested_swizzle_idx)
3849 {
3850 const size_t r = tested_swizzle_combinations[tested_swizzle_idx][0];
3851 const size_t g = tested_swizzle_combinations[tested_swizzle_idx][1];
3852 const size_t b = tested_swizzle_combinations[tested_swizzle_idx][2];
3853 const size_t a = tested_swizzle_combinations[tested_swizzle_idx][3];
3854
3855 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3856
3857 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
3858 {
3859 const testCase test_case = {channel_idx,
3860 m_format_idx,
3861 m_tgt_idx,
3862 access_idx,
3863 valid_values[r],
3864 valid_values[g],
3865 valid_values[b],
3866 valid_values[a],
3867 {source_channel_sizes[0], source_channel_sizes[1],
3868 source_channel_sizes[2], source_channel_sizes[3]}};
3869
3870 executeTestCase(test_case);
3871
3872 deinitOutputTexture();
3873 } /* iteration over channels */
3874
3875 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3876
3877 /* iteration over swizzle combinations */
3878 }
3879 }
3880 }
3881 }
3882
3883 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3884
3885 } /* iteration over swizzle combinations */
3886
3887 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3888
3889 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3890
3891 } /* iteration over access routines - only when enabled */
3892
3893 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3894 deinitTextures();
3895 } /* try */
3896 catch (wrongResults &exc)
3897 {
3898 logTestCaseDetials(exc.m_test_case);
3899 m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage;
3900
3901 test_result = false;
3902 deinitTextures();
3903 }
3904 catch (...)
3905 {
3906 deinitTextures();
3907 throw;
3908 }
3909
3910 /* Set result */
3911 if (true == test_result)
3912 {
3913 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3914 }
3915 else
3916 {
3917 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3918 }
3919
3920 /* Done */
3921 return STOP;
3922 }
3923
3924 /** Fills multisampled source texture
3925 *
3926 * @param format_idx Index of format
3927 * @param target_idx Index of target
3928 *
3929 * @return True if operation was successful, false other wise
3930 **/
fillMSTexture(size_t format_idx,size_t target_idx)3931 bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx)
3932 {
3933 const glw::GLenum target = texture_targets[target_idx].m_target;
3934
3935 /* */
3936 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3937
3938 /* Bind FBO */
3939 gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id);
3940 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3941
3942 /* Attach texture */
3943 switch (target)
3944 {
3945 case GL_TEXTURE_2D_MULTISAMPLE:
3946
3947 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */);
3948 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3949
3950 break;
3951
3952 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3953
3954 gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */);
3955 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3956
3957 break;
3958
3959 default:
3960 TCU_FAIL("Invalid enum");
3961 }
3962
3963 /* Verify status */
3964 const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
3965 GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
3966
3967 if (GL_FRAMEBUFFER_UNSUPPORTED == status)
3968 {
3969 /* Unbind */
3970 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3971 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3972
3973 return false;
3974 }
3975 else if (GL_FRAMEBUFFER_COMPLETE != status)
3976 {
3977 TCU_FAIL("Framebuffer is incomplete. Format is supported");
3978 }
3979
3980 /* Set Viewport */
3981 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
3982 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3983
3984 Utils::programInfo program(m_context);
3985 prepareProgram(format_idx, program);
3986
3987 gl.useProgram(program.m_program_object_id);
3988 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3989
3990 /* Clear */
3991 gl.clear(GL_COLOR_BUFFER_BIT);
3992 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
3993
3994 /* Draw */
3995 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
3996 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
3997
3998 /* Unbind FBO */
3999 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4000 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4001
4002 /* Done */
4003 return true;
4004 }
4005
4006 /** Fills source texture
4007 *
4008 * @param format_idx Index of format
4009 * @param target_idx Index of target
4010 *
4011 * @return True if operation was successful, false other wise
4012 **/
fillSourceTexture(size_t format_idx,size_t target_idx)4013 bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx)
4014 {
4015 const glw::GLenum target = texture_targets[target_idx].m_target;
4016 const _texture_format &format = texture_formats[format_idx];
4017
4018 /* */
4019 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4020
4021 /* Result */
4022 bool result = true;
4023
4024 /* Bind texture */
4025 gl.bindTexture(target, m_source_tex_id);
4026 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4027
4028 /* Attach texture */
4029 switch (target)
4030 {
4031 case GL_TEXTURE_1D:
4032 gl.texSubImage1D(target, 0 /* level */, 0 /* x */, m_width, format.m_format, format.m_type,
4033 format.m_source_data);
4034 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D");
4035
4036 break;
4037
4038 case GL_TEXTURE_1D_ARRAY:
4039 case GL_TEXTURE_2D:
4040 case GL_TEXTURE_RECTANGLE:
4041 gl.texSubImage2D(target, 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, format.m_type,
4042 format.m_source_data);
4043 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4044
4045 break;
4046
4047 case GL_TEXTURE_2D_ARRAY:
4048 case GL_TEXTURE_3D:
4049 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
4050 format.m_format, format.m_type, format.m_source_data);
4051 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
4052
4053 break;
4054
4055 case GL_TEXTURE_CUBE_MAP:
4056 for (size_t i = 0; i < n_cube_map_faces; ++i)
4057 {
4058 gl.texSubImage2D(cube_map_faces[i], 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format,
4059 format.m_type, format.m_source_data);
4060 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4061 }
4062
4063 break;
4064
4065 case GL_TEXTURE_2D_MULTISAMPLE:
4066 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4067 result = fillMSTexture(format_idx, target_idx);
4068
4069 break;
4070
4071 default:
4072 TCU_FAIL("Invalid enum");
4073 }
4074
4075 /* Unbind */
4076 gl.bindTexture(target, 0);
4077 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4078
4079 /* Done */
4080 return result;
4081 }
4082
4083 /** Prepares program used to fill multisampled texture
4084 *
4085 * @param format_idx Index of texture format
4086 * @param program Instance of program that will be prepared
4087 **/
prepareProgram(size_t format_idx,Utils::programInfo & program)4088 void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo &program)
4089 {
4090 static const glw::GLchar *fs_template = "#version 330 core\n"
4091 "\n"
4092 "out PREFIXvec4 out_color;\n"
4093 "\n"
4094 "void main()\n"
4095 "{\n"
4096 " out_color = PREFIXvec4(VALUES);\n"
4097 "}\n"
4098 "\n";
4099
4100 const _texture_format &format = texture_formats[format_idx];
4101 const std::string &values = prepareValues(format_idx);
4102 const std::string &vs = getVertexShader(testCase(), false); /* Get blank VS */
4103
4104 std::string fs = fs_template;
4105 size_t position = 0;
4106
4107 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4108 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4109 Utils::replaceToken("VALUES", position, values.c_str(), fs);
4110
4111 program.build(fs.c_str(), vs.c_str());
4112 }
4113
4114 /** Prepares hardcoded values used by program to fill multisampled textures
4115 *
4116 * @param format_idx Index of texture format
4117 *
4118 * @return Shader source
4119 **/
prepareValues(size_t format_idx)4120 std::string FunctionalTest::prepareValues(size_t format_idx)
4121 {
4122 double ch_rgba[4] = {0.0, 0.0, 0.0, 0.0};
4123
4124 calculate_values_from_source(format_idx, ch_rgba);
4125
4126 /* Prepare string */
4127 std::stringstream stream;
4128 stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3];
4129
4130 return stream.str();
4131 }
4132
4133 /** Verifies if value is in <low:top> range
4134 *
4135 * @tparam T Type oo values
4136 *
4137 * @param value Value to check
4138 * @param low Lowest acceptable value
4139 * @param top Highest acceptable value
4140 *
4141 * @return true if value is in range, false otherwise
4142 **/
4143 template <typename T>
isInRange(const void * value,const void * low,const void * top)4144 bool isInRange(const void *value, const void *low, const void *top)
4145 {
4146 const T *v_ptr = (const T *)value;
4147 const T *l_ptr = (const T *)low;
4148 const T *t_ptr = (const T *)top;
4149
4150 if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr))
4151 {
4152 return false;
4153 }
4154
4155 return true;
4156 }
4157
4158 /** Verifies contents of output image
4159 *
4160 * @param test_case Test case instance
4161 * @param output_format_index Index of format used by output texture
4162 * @parma output_channel_size Size of storage used by output texture in bits
4163 * @param index_of_swizzled_channel Index of swizzled channel
4164 * @param data Image contents
4165 **/
verifyOutputImage(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel,const glw::GLubyte * data)4166 void FunctionalTest::verifyOutputImage(const testCase &test_case, size_t output_format_index,
4167 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
4168 const glw::GLubyte *data)
4169 {
4170 const _texture_format &output_format = texture_formats[output_format_index];
4171
4172 glw::GLubyte expected_data_low[8] = {0};
4173 glw::GLubyte expected_data_top[8] = {0};
4174 size_t texel_size = 0;
4175
4176 calculate_expected_value(test_case.m_source_texture_format_index, output_format_index, index_of_swizzled_channel,
4177 test_case.m_texture_sizes[index_of_swizzled_channel], output_channel_size,
4178 expected_data_low, expected_data_top, texel_size);
4179
4180 for (size_t i = 0; i < m_output_height * m_output_width; ++i)
4181 {
4182 const size_t offset = i * texel_size;
4183 const glw::GLvoid *pointer = data + offset;
4184
4185 bool res = false;
4186
4187 switch (output_format.m_type)
4188 {
4189 case GL_BYTE:
4190 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4191 break;
4192 case GL_UNSIGNED_BYTE:
4193 res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top);
4194 break;
4195 case GL_SHORT:
4196 res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top);
4197 break;
4198 case GL_UNSIGNED_SHORT:
4199 res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top);
4200 break;
4201 case GL_HALF_FLOAT:
4202 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4203 break;
4204 case GL_INT:
4205 res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top);
4206 break;
4207 case GL_UNSIGNED_INT:
4208 res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top);
4209 break;
4210 case GL_FLOAT:
4211 res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top);
4212 break;
4213 default:
4214 TCU_FAIL("Invalid enum");
4215 }
4216
4217 if (false == res)
4218 {
4219 throw wrongResults(test_case);
4220 }
4221 }
4222 }
4223 } // namespace TextureSwizzle
4224
4225 /** Constructor.
4226 *
4227 * @param context Rendering context.
4228 **/
TextureSwizzleTests(deqp::Context & context)4229 TextureSwizzleTests::TextureSwizzleTests(deqp::Context &context)
4230 : TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality")
4231 {
4232 /* Left blank on purpose */
4233 }
4234
4235 /** Initializes a texture_storage_multisample test group.
4236 *
4237 **/
init(void)4238 void TextureSwizzleTests::init(void)
4239 {
4240 addChild(new TextureSwizzle::APIErrorsTest(m_context));
4241 addChild(new TextureSwizzle::IntialStateTest(m_context));
4242 addSmokeTest();
4243 addFunctionalTest();
4244 }
4245
addSmokeTest()4246 void TextureSwizzleTests::addSmokeTest()
4247 {
4248 /* Iterate over all cases */
4249 for (size_t access_idx = 0; access_idx < TextureSwizzle::n_texture_access; ++access_idx)
4250 {
4251 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
4252 {
4253 addChild(new TextureSwizzle::SmokeTest(m_context, access_idx, channel_idx));
4254 } /* iteration over channels */
4255 } /* iteration over access routines */
4256 }
4257
addFunctionalTest()4258 void TextureSwizzleTests::addFunctionalTest()
4259 {
4260 #if FUNCTIONAL_TEST_ALL_FORMATS == 0
4261
4262 static const glw::GLenum tested_formats[] = {GL_R8, GL_R3_G3_B2, GL_RGBA16, GL_R11F_G11F_B10F,
4263 GL_RGB9_E5, GL_DEPTH32F_STENCIL8};
4264 static const size_t n_tested_formats = sizeof(tested_formats) / sizeof(tested_formats[0]);
4265
4266 #endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */
4267
4268 #if FUNCTIONAL_TEST_ALL_TARGETS == 0
4269
4270 static const glw::GLenum tested_targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
4271 static const size_t n_tested_targets = sizeof(tested_targets) / sizeof(tested_targets[0]);
4272
4273 #endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */
4274
4275 #if FUNCTIONAL_TEST_ALL_FORMATS
4276 for (size_t format_idx = 0; format_idx < TextureSwizzle::n_texture_formats; ++format_idx)
4277 {
4278
4279 #else /* FUNCTIONAL_TEST_ALL_FORMATS */
4280
4281 for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx)
4282 {
4283 const size_t format_idx = TextureSwizzle::get_index_of_format(tested_formats[tested_format_idx]);
4284
4285 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
4286
4287 #if FUNCTIONAL_TEST_ALL_TARGETS
4288
4289 for (size_t tgt_idx = 0; tgt_idx < TextureSwizzle::n_texture_targets; ++tgt_idx)
4290 {
4291
4292 #else /* FUNCTIONAL_TEST_ALL_TARGETS */
4293
4294 for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx)
4295 {
4296 const size_t tgt_idx = TextureSwizzle::get_index_of_target(tested_targets[tested_tgt_idx]);
4297
4298 #endif /* FUNCTIONAL_TEST_ALL_TARGETS */
4299 addChild(new TextureSwizzle::FunctionalTest(m_context, format_idx, tgt_idx));
4300 } /* iteration over texture targets */
4301 } /* iteration over texture formats */
4302 }
4303 } // namespace gl3cts
4304