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, DE_NULL},
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, DE_NULL},
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, DE_NULL},
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, DE_NULL},
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, DE_NULL},
289 {GL_R8, DE_NULL},
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, DE_NULL},
302 {GL_R8_SNORM, DE_NULL},
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, DE_NULL},
315 {GL_R16, DE_NULL},
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, DE_NULL},
328 {GL_R16_SNORM, DE_NULL},
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, DE_NULL},
342 {GL_R8, DE_NULL},
343 {GL_R8, DE_NULL},
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, DE_NULL},
355 {GL_R8, DE_NULL},
356 {GL_R8, DE_NULL},
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, DE_NULL},
368 {GL_R8, DE_NULL},
369 {GL_R8, DE_NULL},
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, DE_NULL},
381 {GL_R8, DE_NULL},
382 {GL_R8, DE_NULL},
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, DE_NULL},
394 {GL_R8_SNORM, DE_NULL},
395 {GL_R8_SNORM, DE_NULL},
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, DE_NULL},
407 {GL_R16, DE_NULL},
408 {GL_R16, DE_NULL},
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, DE_NULL},
420 {GL_R16, DE_NULL},
421 {GL_R16, DE_NULL},
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, DE_NULL},
433 {GL_R16, DE_NULL},
434 {GL_R16, DE_NULL},
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, DE_NULL},
447 {GL_R16_SNORM, DE_NULL},
448 {GL_R16_SNORM, DE_NULL},
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, DE_NULL},
460 {GL_R8, DE_NULL},
461 {GL_R8, DE_NULL},
462 {GL_R8, DE_NULL},
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, DE_NULL},
473 {GL_R8, DE_NULL},
474 {GL_R8, DE_NULL},
475 {GL_R8, DE_NULL},
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, DE_NULL},
486 {GL_R8, DE_NULL},
487 {GL_R8, DE_NULL},
488 {GL_R8, DE_NULL},
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, DE_NULL},
499 {GL_R8, DE_NULL},
500 {GL_R8, DE_NULL},
501 {GL_R8, DE_NULL},
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, DE_NULL},
512 {GL_R8_SNORM, DE_NULL},
513 {GL_R8_SNORM, DE_NULL},
514 {GL_R8_SNORM, DE_NULL},
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, DE_NULL},
525 {GL_R16, DE_NULL},
526 {GL_R16, DE_NULL},
527 {GL_R16, DE_NULL},
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, DE_NULL},
552 {GL_R16, DE_NULL},
553 {GL_R16, DE_NULL},
554 {GL_R16, DE_NULL},
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, DE_NULL},
565 {GL_R16, DE_NULL},
566 {GL_R16, DE_NULL},
567 {GL_R16, DE_NULL},
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, DE_NULL},
578 {GL_R16_SNORM, DE_NULL},
579 {GL_R16_SNORM, DE_NULL},
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 (DE_NULL != 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 {
2430 /* Left blank intentionally */
2431 }
2432
2433 /** Constructor.
2434 *
2435 * @param context Rendering context.
2436 **/
SmokeTest(deqp::Context & context,const glw::GLchar * name,const glw::GLchar * description)2437 SmokeTest::SmokeTest(deqp::Context &context, const glw::GLchar *name, const glw::GLchar *description)
2438 : TestCase(context, name, description)
2439 , m_is_ms_supported(false)
2440 , m_prepare_fbo_id(0)
2441 , m_out_tex_id(0)
2442 , m_source_tex_id(0)
2443 , m_test_fbo_id(0)
2444 , m_vao_id(0)
2445 {
2446 /* Left blank intentionally */
2447 }
2448
2449 /** Deinitialization **/
deinit()2450 void SmokeTest::deinit()
2451 {
2452 deinitTextures();
2453
2454 if (m_prepare_fbo_id != 0)
2455 {
2456 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2457 gl.deleteFramebuffers(1, &m_prepare_fbo_id);
2458
2459 m_prepare_fbo_id = 0;
2460 }
2461
2462 if (m_test_fbo_id != 0)
2463 {
2464 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2465 gl.deleteFramebuffers(1, &m_test_fbo_id);
2466
2467 m_test_fbo_id = 0;
2468 }
2469
2470 if (m_vao_id != 0)
2471 {
2472 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2473 gl.deleteVertexArrays(1, &m_vao_id);
2474
2475 m_vao_id = 0;
2476 }
2477 }
2478
2479 /** Executes test iteration.
2480 *
2481 * @return Returns STOP.
2482 */
iterate()2483 tcu::TestNode::IterateResult SmokeTest::iterate()
2484 {
2485 static const glw::GLenum tested_format = GL_RGBA32UI;
2486 static const glw::GLenum tested_target = GL_TEXTURE_2D_ARRAY;
2487
2488 const size_t format_idx = get_index_of_format(tested_format);
2489 const size_t tgt_idx = get_index_of_target(tested_target);
2490
2491 glw::GLint source_channel_sizes[4] = {0};
2492
2493 /* */
2494 testInit();
2495
2496 if (false == isTargetSupported(tgt_idx))
2497 {
2498 throw tcu::NotSupportedError("Texture target is not support by implementation", "", __FILE__, __LINE__);
2499 }
2500
2501 /* Prepare and fill source texture */
2502 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
2503 if (false == fillSourceTexture(format_idx, tgt_idx))
2504 {
2505 TCU_FAIL("Failed to prepare source texture");
2506 }
2507
2508 /* Iterate over all cases */
2509 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
2510 {
2511 /* Skip invalid cases */
2512 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
2513 {
2514 continue;
2515 }
2516
2517 for (size_t r = 0; r < n_valid_values; ++r)
2518 {
2519 for (size_t g = 0; g < n_valid_values; ++g)
2520 {
2521 for (size_t b = 0; b < n_valid_values; ++b)
2522 {
2523 for (size_t a = 0; a < n_valid_values; ++a)
2524 {
2525 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
2526 {
2527 const testCase test_case = {channel_idx,
2528 format_idx,
2529 tgt_idx,
2530 access_idx,
2531 valid_values[r],
2532 valid_values[g],
2533 valid_values[b],
2534 valid_values[a],
2535 {source_channel_sizes[0], source_channel_sizes[1],
2536 source_channel_sizes[2], source_channel_sizes[3]}};
2537
2538 executeTestCase(test_case);
2539
2540 deinitOutputTexture();
2541 } /* iteration over channels */
2542 } /* iteration over swizzle combinations */
2543 }
2544 }
2545 }
2546 } /* iteration over access routines */
2547
2548 /* Set result - exceptions are thrown in case of any error */
2549 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2550
2551 /* Done */
2552 return STOP;
2553 }
2554
2555 /** Deinitialization of output texture **/
deinitOutputTexture()2556 void SmokeTest::deinitOutputTexture()
2557 {
2558 if (m_out_tex_id != 0)
2559 {
2560 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2561 gl.deleteTextures(1, &m_out_tex_id);
2562
2563 m_out_tex_id = 0;
2564 }
2565 }
2566
2567 /** Deinitialization of textures **/
deinitTextures()2568 void SmokeTest::deinitTextures()
2569 {
2570 deinitOutputTexture();
2571
2572 if (m_source_tex_id != 0)
2573 {
2574 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2575 gl.deleteTextures(1, &m_source_tex_id);
2576
2577 m_source_tex_id = 0;
2578 }
2579 }
2580
2581 /** Captures and verifies contents of output texture
2582 *
2583 * @param test_case Test case instance
2584 * @param output_format_index Index of format used by output texture
2585 * @parma output_channel_size Size of storage used by output texture in bits
2586 * @param index_of_swizzled_channel Index of swizzled channel
2587 */
captureAndVerify(const testCase & test_case,size_t output_format_index,glw::GLint output_channel_size,size_t index_of_swizzled_channel)2588 void SmokeTest::captureAndVerify(const testCase &test_case, size_t output_format_index, glw::GLint output_channel_size,
2589 size_t index_of_swizzled_channel)
2590 {
2591 const _texture_format &output_format = texture_formats[output_format_index];
2592
2593 /* */
2594 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2595
2596 /* Storage for image data */
2597 glw::GLubyte result_image[m_output_width * m_output_height * 4 /* channles */ * sizeof(glw::GLuint)];
2598
2599 /* Get image data */
2600 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2601 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2602
2603 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, output_format.m_format, output_format.m_type, result_image);
2604 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
2605
2606 /* Unbind output texture */
2607 gl.bindTexture(GL_TEXTURE_2D, 0);
2608 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2609
2610 /* Verification */
2611 verifyOutputImage(test_case, output_format_index, output_channel_size, index_of_swizzled_channel, result_image);
2612 }
2613
2614 /** Draws four points
2615 *
2616 * @param target Target of source texture
2617 * @param texture_swizzle Set of texture swizzle values
2618 * @param use_rgba_enum If texture swizzle states should be set with RGBA enum or separe calls
2619 **/
draw(glw::GLenum target,const glw::GLint * texture_swizzle,bool use_rgba_enum)2620 void SmokeTest::draw(glw::GLenum target, const glw::GLint *texture_swizzle, bool use_rgba_enum)
2621 {
2622 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2623
2624 /* Prepare source texture */
2625 gl.activeTexture(GL_TEXTURE0);
2626 GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveTexture");
2627
2628 gl.bindTexture(target, m_source_tex_id);
2629 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2630
2631 /* Set texture swizzle */
2632 if (true == use_rgba_enum)
2633 {
2634 gl.texParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, texture_swizzle);
2635 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteriv");
2636 }
2637 else
2638 {
2639 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, texture_swizzle[0]);
2640 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, texture_swizzle[1]);
2641 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, texture_swizzle[2]);
2642 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, texture_swizzle[3]);
2643 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2644 }
2645
2646 /* Clear */
2647 gl.clear(GL_COLOR_BUFFER_BIT);
2648 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2649
2650 /* Draw */
2651 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
2652 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2653
2654 /* Revert texture swizzle */
2655 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2656 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2657 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2658 gl.texParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2659 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
2660
2661 /* Unbind source texture */
2662 gl.bindTexture(target, 0);
2663 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2664 }
2665
2666 /** Executes test case
2667 *
2668 * @param test_case Test case instance
2669 **/
executeTestCase(const testCase & test_case)2670 void SmokeTest::executeTestCase(const testCase &test_case)
2671 {
2672 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2673 const glw::GLint red = test_case.m_texture_swizzle_red;
2674 const glw::GLint green = test_case.m_texture_swizzle_green;
2675 const glw::GLint blue = test_case.m_texture_swizzle_blue;
2676 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
2677 const glw::GLint param[4] = {red, green, blue, alpha};
2678 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
2679 glw::GLint out_channel_size = 0;
2680 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
2681 const size_t out_format_idx = get_index_of_format(out_internal_format);
2682
2683 /* */
2684 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2685
2686 /* Prepare output */
2687 prepareOutputTexture(out_format_idx);
2688
2689 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
2690 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2691
2692 gl.bindFramebuffer(GL_FRAMEBUFFER, m_test_fbo_id);
2693 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2694
2695 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_out_tex_id, 0 /* level */);
2696 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
2697
2698 /* Set Viewport */
2699 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
2700 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
2701
2702 /* Get internal storage size of output texture */
2703 gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_RED_SIZE, &out_channel_size);
2704 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
2705
2706 /* Unbind output texture */
2707 gl.bindTexture(GL_TEXTURE_2D, 0);
2708 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2709
2710 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, true);
2711 prepareAndTestProgram(test_case, out_format_idx, out_channel_size, channel, false);
2712
2713 /* Unbind FBO */
2714 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
2715 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
2716 }
2717
2718 /** Fills source texture
2719 *
2720 * @param format_idx Index of format
2721 * @param target_idx Index of target
2722 *
2723 * @return True if operation was successful, false other wise
2724 **/
fillSourceTexture(size_t format_idx,size_t target_idx)2725 bool SmokeTest::fillSourceTexture(size_t format_idx, size_t target_idx)
2726 {
2727 static const glw::GLuint rgba32ui[4] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff};
2728
2729 const glw::GLenum target = texture_targets[target_idx].m_target;
2730 const _texture_format &texture_format = texture_formats[format_idx];
2731
2732 /* */
2733 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
2734 const glw::GLvoid *data = 0;
2735
2736 /* Bind texture and FBO */
2737 gl.bindTexture(target, m_source_tex_id);
2738 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2739
2740 /* Set color */
2741 switch (texture_format.m_internal_format)
2742 {
2743 case GL_RGBA32UI:
2744 data = (const glw::GLubyte *)rgba32ui;
2745 break;
2746
2747 default:
2748 TCU_FAIL("Invalid enum");
2749 }
2750
2751 /* Attach texture */
2752 switch (target)
2753 {
2754 case GL_TEXTURE_2D_ARRAY:
2755 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
2756 texture_format.m_format, texture_format.m_type, data);
2757 break;
2758
2759 default:
2760 TCU_FAIL("Invalid enum");
2761 }
2762
2763 /* Unbind */
2764 gl.bindTexture(target, 0);
2765 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
2766
2767 /* Done */
2768 return true;
2769 }
2770
2771 /** Gets source of fragment shader
2772 *
2773 * @param test_case Test case instance
2774 * @param output_format_index Index of output format
2775 * @param is_tested_stage Selects if fragment or vertex shader makes texture access
2776 *
2777 * @return Source of shader
2778 **/
getFragmentShader(const testCase & test_case,size_t output_format_index,bool is_tested_stage)2779 std::string SmokeTest::getFragmentShader(const testCase &test_case, size_t output_format_index, bool is_tested_stage)
2780 {
2781 static const glw::GLchar *fs_blank_template = "#version 330 core\n"
2782 "\n"
2783 "flat in BASIC_TYPE result;\n"
2784 "\n"
2785 "out BASIC_TYPE out_color;\n"
2786 "\n"
2787 "void main()\n"
2788 "{\n"
2789 " out_color = result;\n"
2790 "}\n"
2791 "\n";
2792
2793 static const glw::GLchar *fs_test_template = "#version 330 core\n"
2794 "\n"
2795 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2796 "\n"
2797 "out BASIC_TYPE out_color;\n"
2798 "\n"
2799 "void main()\n"
2800 "{\n"
2801 " BASIC_TYPE result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2802 "\n"
2803 " out_color = result;\n"
2804 "}\n"
2805 "\n";
2806
2807 /* */
2808 const std::string &arguments = prepareArguments(test_case);
2809 const _texture_access &access = texture_access[test_case.m_texture_access_index];
2810 const glw::GLchar *channel = channels[test_case.m_channel_index];
2811 const _texture_format &output_format = texture_formats[output_format_index];
2812 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2813 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
2814
2815 std::string fs;
2816 size_t position = 0;
2817
2818 if (is_tested_stage)
2819 {
2820 fs = fs_test_template;
2821
2822 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, fs);
2823 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, fs);
2824 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2825 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2826 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, fs);
2827 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), fs);
2828 Utils::replaceToken("CHANNEL", position, channel, fs);
2829 }
2830 else
2831 {
2832 fs = fs_blank_template;
2833
2834 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, fs);
2835 Utils::replaceToken("BASIC_TYPE", position, output_format.m_sampler.m_basic_type, fs);
2836 }
2837
2838 return fs;
2839 }
2840
2841 /** Gets source of vertex shader
2842 *
2843 * @param test_case Test case instance
2844 * @param is_tested_stage Selects if vertex or fragment shader makes texture access
2845 *
2846 * @return Source of shader
2847 **/
getVertexShader(const testCase & test_case,bool is_tested_stage)2848 std::string SmokeTest::getVertexShader(const testCase &test_case, bool is_tested_stage)
2849 {
2850 static const glw::GLchar *vs_blank_template = "#version 330 core\n"
2851 "\n"
2852 "void main()\n"
2853 "{\n"
2854 " switch (gl_VertexID)\n"
2855 " {\n"
2856 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2857 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2858 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2859 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2860 " }\n"
2861 "}\n"
2862 "\n";
2863
2864 static const glw::GLchar *vs_test_template = "#version 330 core\n"
2865 "\n"
2866 "uniform PREFIXsamplerSAMPLER_TYPE sampler;\n"
2867 "\n"
2868 "flat out BASIC_TYPE result;\n"
2869 "\n"
2870 "void main()\n"
2871 "{\n"
2872 " result = TEXTURE_ACCESS(sampler, ARGUMENTS).CHANNEL;\n"
2873 "\n"
2874 " switch (gl_VertexID)\n"
2875 " {\n"
2876 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
2877 " case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
2878 " case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
2879 " case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
2880 " }\n"
2881 "}\n"
2882 "\n";
2883
2884 std::string vs;
2885
2886 if (is_tested_stage)
2887 {
2888 /* */
2889 const std::string &arguments = prepareArguments(test_case);
2890 const _texture_access &access = texture_access[test_case.m_texture_access_index];
2891 const glw::GLchar *channel = channels[test_case.m_channel_index];
2892 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
2893 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
2894
2895 size_t position = 0;
2896
2897 vs = vs_test_template;
2898
2899 Utils::replaceToken("PREFIX", position, source_format.m_sampler.m_sampler_prefix, vs);
2900 Utils::replaceToken("SAMPLER_TYPE", position, target.m_sampler_type, vs);
2901 Utils::replaceToken("BASIC_TYPE", position, source_format.m_sampler.m_basic_type, vs);
2902 Utils::replaceToken("TEXTURE_ACCESS", position, access.m_name, vs);
2903 Utils::replaceToken("ARGUMENTS", position, arguments.c_str(), vs);
2904 Utils::replaceToken("CHANNEL", position, channel, vs);
2905 }
2906 else
2907 {
2908 vs = vs_blank_template;
2909 }
2910
2911 return vs;
2912 }
2913
2914 /** Check if target is supported
2915 *
2916 * @param target_idx Index of target
2917 *
2918 * @return true if target is supported, false otherwise
2919 **/
isTargetSupported(size_t target_idx)2920 bool SmokeTest::isTargetSupported(size_t target_idx)
2921 {
2922 const _texture_target &target = texture_targets[target_idx];
2923
2924 bool is_supported = true;
2925
2926 switch (target.m_target)
2927 {
2928 case GL_TEXTURE_2D_MULTISAMPLE:
2929 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2930 is_supported = m_is_ms_supported;
2931 break;
2932
2933 default:
2934 break;
2935 }
2936
2937 return is_supported;
2938 }
2939
2940 /** Check if target is supported by access routine
2941 *
2942 * @param access_idx Index of access routine
2943 * @param target_idx Index of target
2944 *
2945 * @return true if target is supported, false otherwise
2946 **/
isTargetSuppByAccess(size_t access_idx,size_t target_idx)2947 bool SmokeTest::isTargetSuppByAccess(size_t access_idx, size_t target_idx)
2948 {
2949 const _texture_access &access = texture_access[access_idx];
2950 const _texture_target &source_target = texture_targets[target_idx];
2951
2952 if ((false == source_target.m_support_integral_coordinates) && (true == access.m_use_integral_coordinates))
2953 {
2954 /* Cases are not valid, texelFetch* is not supported by the target */
2955 return false;
2956 }
2957
2958 if ((false == source_target.m_support_offset) && (true == access.m_use_offsets))
2959 {
2960 /* Cases are not valid, texture*Offset is not supported by the target */
2961 return false;
2962 }
2963
2964 if ((false == source_target.m_support_lod) && (true == access.m_use_lod))
2965 {
2966 /* Access is one of texture*Lod* or texelFetch* */
2967 /* Target is one of MS or rect */
2968
2969 if ((true == source_target.m_require_multisampling) && (true == access.m_support_multisampling))
2970 {
2971 /* texelFetch */
2972 /* One of MS targets */
2973 return true;
2974 }
2975
2976 /* Cases are not valid, either lod or sample is required but target does not supported that */
2977 return false;
2978 }
2979
2980 if ((false == source_target.m_supports_proj) && (1 == access.m_n_coordinates))
2981 {
2982 /* Cases are not valid, textureProj* is not supported by the target */
2983 return false;
2984 }
2985
2986 if ((true == source_target.m_require_multisampling) && (false == access.m_support_multisampling))
2987 {
2988 /* Cases are not valid, texelFetch* is not supported by the target */
2989 return false;
2990 }
2991
2992 return true;
2993 }
2994
2995 /** Check if target is supported by format
2996 *
2997 * @param format_idx Index of format
2998 * @param target_idx Index of target
2999 *
3000 * @return true if target is supported, false otherwise
3001 **/
isTargetSuppByFormat(size_t format_idx,size_t target_idx)3002 bool SmokeTest::isTargetSuppByFormat(size_t format_idx, size_t target_idx)
3003 {
3004 const _texture_format &format = texture_formats[format_idx];
3005 const _texture_target &source_target = texture_targets[target_idx];
3006
3007 bool is_supported = true;
3008
3009 switch (format.m_internal_format)
3010 {
3011 case GL_DEPTH_COMPONENT16:
3012 case GL_DEPTH_COMPONENT24:
3013 case GL_DEPTH_COMPONENT32:
3014 case GL_DEPTH_COMPONENT32F:
3015 case GL_DEPTH24_STENCIL8:
3016 case GL_DEPTH32F_STENCIL8:
3017 switch (source_target.m_target)
3018 {
3019 case GL_TEXTURE_3D:
3020 case GL_TEXTURE_2D_MULTISAMPLE:
3021 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3022 is_supported = false;
3023 break;
3024 default:
3025 break;
3026 }
3027 break;
3028
3029 case GL_RGB9_E5:
3030 switch (source_target.m_target)
3031 {
3032 case GL_TEXTURE_2D_MULTISAMPLE:
3033 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3034 is_supported = false;
3035 break;
3036 default:
3037 break;
3038 }
3039 break;
3040
3041 default:
3042 break;
3043 }
3044
3045 return is_supported;
3046 }
3047
3048 /** Logs details of test case
3049 *
3050 * @parma test_case Test case instance
3051 **/
logTestCaseDetials(const testCase & test_case)3052 void SmokeTest::logTestCaseDetials(const testCase &test_case)
3053 {
3054 const glw::GLenum target = texture_targets[test_case.m_source_texture_target_index].m_target;
3055 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
3056 const glw::GLint red = test_case.m_texture_swizzle_red;
3057 const glw::GLint green = test_case.m_texture_swizzle_green;
3058 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3059 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3060 const glw::GLint param[4] = {red, green, blue, alpha};
3061 const size_t channel = get_swizzled_channel_idx(test_case.m_channel_index, param);
3062 const glw::GLenum out_internal_format = get_internal_format_for_channel(source_format, channel);
3063 const size_t out_format_idx = get_index_of_format(out_internal_format);
3064 const _texture_format &output_format = texture_formats[out_format_idx];
3065
3066 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case details. Source texture: Target: "
3067 << glu::getTextureTargetStr(target)
3068 << ". Format: " << glu::getTextureFormatName(source_format.m_internal_format)
3069 << ", " << glu::getTextureFormatName(source_format.m_format) << ", "
3070 << glu::getTypeStr(source_format.m_type)
3071 << ", DS: " << glu::getTextureDepthStencilModeName(source_format.m_ds_mode)
3072 << ". Swizzle: [" << glu::getTextureSwizzleStr(red) << ", "
3073 << glu::getTextureSwizzleStr(green) << ", " << glu::getTextureSwizzleStr(blue)
3074 << ", " << glu::getTextureSwizzleStr(alpha)
3075 << "]. Channel: " << channels[test_case.m_channel_index]
3076 << ". Access: " << texture_access[test_case.m_texture_access_index].m_name
3077 << ". Output texture: Format: "
3078 << glu::getTextureFormatName(output_format.m_internal_format) << ", "
3079 << glu::getTextureFormatName(output_format.m_format) << ", "
3080 << glu::getTypeStr(output_format.m_type) << "." << tcu::TestLog::EndMessage;
3081 }
3082
3083 /** Prepares program then draws and verifies resutls for both ways of setting texture swizzle
3084 *
3085 * @param test_case Test case instance
3086 * @param output_format_index Index of format used by output texture
3087 * @parma output_channel_size Size of storage used by output texture in bits
3088 * @param index_of_swizzled_channel Index of swizzled channel
3089 * @param test_vertex_stage Selects if vertex or fragment shader should execute texture access
3090 **/
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)3091 void SmokeTest::prepareAndTestProgram(const testCase &test_case, size_t output_format_index,
3092 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
3093 bool test_vertex_stage)
3094 {
3095 const _texture_target &source_target = texture_targets[test_case.m_source_texture_target_index];
3096 const glw::GLint red = test_case.m_texture_swizzle_red;
3097 const glw::GLint green = test_case.m_texture_swizzle_green;
3098 const glw::GLint blue = test_case.m_texture_swizzle_blue;
3099 const glw::GLint alpha = test_case.m_texture_swizzle_alpha;
3100 const glw::GLint param[4] = {red, green, blue, alpha};
3101
3102 /* */
3103 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3104
3105 /* Prepare program */
3106 const std::string &fs = getFragmentShader(test_case, output_format_index, !test_vertex_stage);
3107 const std::string &vs = getVertexShader(test_case, test_vertex_stage);
3108
3109 Utils::programInfo program(m_context);
3110 program.build(fs.c_str(), vs.c_str());
3111
3112 gl.useProgram(program.m_program_object_id);
3113 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
3114
3115 /* Prepare sampler */
3116 glw::GLint location = gl.getUniformLocation(program.m_program_object_id, "sampler");
3117 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
3118
3119 if (-1 == location)
3120 {
3121 TCU_FAIL("Uniform is not available");
3122 }
3123
3124 gl.uniform1i(location, 0 /* texture unit */);
3125 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3126
3127 draw(source_target.m_target, param, false);
3128 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3129
3130 draw(source_target.m_target, param, true);
3131 captureAndVerify(test_case, output_format_index, output_channel_size, index_of_swizzled_channel);
3132 }
3133
3134 /** Prepares arguments for texture access routine call
3135 *
3136 * @param test_case Test case instance
3137 *
3138 * @return Source code
3139 **/
prepareArguments(const testCase & test_case)3140 std::string SmokeTest::prepareArguments(const testCase &test_case)
3141 {
3142 const _texture_access &access = texture_access[test_case.m_texture_access_index];
3143 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3144
3145 std::string arguments = "COORDINATESLODDERIVATIVESOFFSETSSAMPLE";
3146 const std::string &coordinates = prepareCoordinates(test_case);
3147
3148 size_t position = 0;
3149
3150 Utils::replaceToken("COORDINATES", position, coordinates.c_str(), arguments);
3151
3152 if ((true == access.m_use_lod) && (true == target.m_support_lod))
3153 {
3154 Utils::replaceToken("LODDERIVATIVES", position, ", int(0)", arguments);
3155 }
3156 else if (true == access.m_use_derivaties)
3157 {
3158 const std::string &derivatives_0 = prepareDerivatives(test_case, 0);
3159 const std::string &derivatives_1 = prepareDerivatives(test_case, 1);
3160 const size_t start_pos = position;
3161
3162 Utils::replaceToken("LODDERIVATIVES", position, ", XXXXX, XXXXX", arguments);
3163 position = start_pos + 2;
3164 Utils::replaceToken("XXXXX", position, derivatives_0.c_str(), arguments);
3165 Utils::replaceToken("XXXXX", position, derivatives_1.c_str(), arguments);
3166 }
3167 else
3168 {
3169 Utils::replaceToken("LODDERIVATIVES", position, "", arguments);
3170 }
3171
3172 if (true == access.m_use_offsets)
3173 {
3174 const std::string &offsets = prepareOffsets(test_case);
3175 const size_t start_pos = position;
3176
3177 Utils::replaceToken("OFFSETS", position, ", XXXXX", arguments);
3178 position = start_pos + 2;
3179 Utils::replaceToken("XXXXX", position, offsets.c_str(), arguments);
3180 }
3181 else
3182 {
3183 Utils::replaceToken("OFFSETS", position, "", arguments);
3184 }
3185
3186 if ((true == target.m_require_multisampling) && (true == access.m_support_multisampling))
3187 {
3188 const std::string &sample = prepareSample();
3189 const size_t start_pos = position;
3190
3191 Utils::replaceToken("SAMPLE", position, ", XX", arguments);
3192 position = start_pos + 2;
3193 Utils::replaceToken("XX", position, sample.c_str(), arguments);
3194 }
3195 else
3196 {
3197 Utils::replaceToken("SAMPLE", position, "", arguments);
3198 }
3199
3200 return arguments;
3201 }
3202
3203 /** Prepares coordinate for texture access routine call
3204 *
3205 * @param test_case Test case instance
3206 *
3207 * @return Source code
3208 **/
prepareCoordinates(const testCase & test_case)3209 std::string SmokeTest::prepareCoordinates(const testCase &test_case)
3210 {
3211 const _texture_access &access = texture_access[test_case.m_texture_access_index];
3212 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3213
3214 const glw::GLchar *type = 0;
3215
3216 std::string coordinates = "TYPE(VAL_LIST)";
3217
3218 if (false == access.m_use_integral_coordinates)
3219 {
3220 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3221 {
3222 case 1:
3223 type = "float";
3224 break;
3225 case 2:
3226 type = "vec2";
3227 break;
3228 case 3:
3229 type = "vec3";
3230 break;
3231 case 4:
3232 type = "vec4";
3233 break;
3234 default:
3235 TCU_FAIL("Invalid value");
3236 }
3237 }
3238 else
3239 {
3240 switch (access.m_n_coordinates + target.m_n_array_coordinates + target.m_n_coordinates)
3241 {
3242 case 1:
3243 type = "int";
3244 break;
3245 case 2:
3246 type = "ivec2";
3247 break;
3248 case 3:
3249 type = "ivec3";
3250 break;
3251 case 4:
3252 type = "ivec4";
3253 break;
3254 default:
3255 TCU_FAIL("Invalid value");
3256 }
3257 }
3258
3259 size_t position = 0;
3260
3261 Utils::replaceToken("TYPE", position, type, coordinates);
3262
3263 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3264 {
3265 size_t start_position = position;
3266
3267 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3268
3269 position = start_position + 1;
3270 }
3271
3272 for (size_t i = 0; i < target.m_n_array_coordinates; ++i)
3273 {
3274 size_t start_position = position;
3275
3276 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", coordinates);
3277
3278 position = start_position + 1;
3279 }
3280
3281 for (size_t i = 0; i < access.m_n_coordinates; ++i)
3282 {
3283 size_t start_position = position;
3284
3285 Utils::replaceToken("VAL_LIST", position, "1, VAL_LIST", coordinates);
3286
3287 position = start_position + 1;
3288 }
3289
3290 Utils::replaceToken(", VAL_LIST", position, "", coordinates);
3291
3292 return coordinates;
3293 }
3294
3295 /** Prepares derivatives for texture access routine call
3296 *
3297 * @param test_case Test case instance
3298 *
3299 * @return Source code
3300 **/
prepareDerivatives(const testCase & test_case,size_t index)3301 std::string SmokeTest::prepareDerivatives(const testCase &test_case, size_t index)
3302 {
3303 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3304
3305 const glw::GLchar *type = 0;
3306
3307 std::string derivatives = "TYPE(VAL_LIST)";
3308
3309 switch (target.m_n_derivatives)
3310 {
3311 case 1:
3312 type = "float";
3313 break;
3314 case 2:
3315 type = "vec2";
3316 break;
3317 case 3:
3318 type = "vec3";
3319 break;
3320 case 4:
3321 type = "vec4";
3322 break;
3323 default:
3324 TCU_FAIL("Invalid value");
3325 }
3326
3327 size_t position = 0;
3328
3329 Utils::replaceToken("TYPE", position, type, derivatives);
3330
3331 for (size_t i = 0; i < target.m_n_derivatives; ++i)
3332 {
3333 size_t start_position = position;
3334
3335 if (index == i)
3336 {
3337 Utils::replaceToken("VAL_LIST", position, "1.0, VAL_LIST", derivatives);
3338 }
3339 else
3340 {
3341 Utils::replaceToken("VAL_LIST", position, "0.0, VAL_LIST", derivatives);
3342 }
3343
3344 position = start_position + 1;
3345 }
3346
3347 Utils::replaceToken(", VAL_LIST", position, "", derivatives);
3348
3349 return derivatives;
3350 }
3351
3352 /** Prepares offsets for texture access routine call
3353 *
3354 * @param test_case Test case instance
3355 *
3356 * @return Source code
3357 **/
prepareOffsets(const testCase & test_case)3358 std::string SmokeTest::prepareOffsets(const testCase &test_case)
3359 {
3360 const _texture_target &target = texture_targets[test_case.m_source_texture_target_index];
3361
3362 const glw::GLchar *type = DE_NULL;
3363
3364 std::string offsets = "TYPE(VAL_LIST)";
3365
3366 switch (target.m_n_derivatives)
3367 {
3368 case 1:
3369 type = "int";
3370 break;
3371 case 2:
3372 type = "ivec2";
3373 break;
3374 case 3:
3375 type = "ivec3";
3376 break;
3377 case 4:
3378 type = "ivec4";
3379 break;
3380 default:
3381 TCU_FAIL("Invalid value");
3382 }
3383
3384 size_t position = 0;
3385
3386 Utils::replaceToken("TYPE", position, type, offsets);
3387
3388 for (size_t i = 0; i < target.m_n_coordinates; ++i)
3389 {
3390 size_t start_position = position;
3391
3392 Utils::replaceToken("VAL_LIST", position, "0, VAL_LIST", offsets);
3393
3394 position = start_position + 1;
3395 }
3396
3397 Utils::replaceToken(", VAL_LIST", position, "", offsets);
3398
3399 return offsets;
3400 }
3401
3402 /** Prepares output texture
3403 *
3404 * @param format_idx Index of texture format
3405 **/
prepareOutputTexture(size_t format_idx)3406 void SmokeTest::prepareOutputTexture(size_t format_idx)
3407 {
3408 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3409
3410 const _texture_format &format = texture_formats[format_idx];
3411
3412 gl.genTextures(1, &m_out_tex_id);
3413 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3414
3415 gl.bindTexture(GL_TEXTURE_2D, m_out_tex_id);
3416 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3417
3418 gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, format.m_internal_format, m_output_width, m_output_height,
3419 0 /* border */, format.m_format, format.m_type, 0 /* pixels */);
3420 GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D");
3421
3422 gl.bindTexture(GL_TEXTURE_2D, 0);
3423 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3424 }
3425
3426 /** Prepares sample for texture access routine call
3427 *
3428 * @return Source code
3429 **/
prepareSample()3430 std::string SmokeTest::prepareSample()
3431 {
3432 glw::GLsizei samples = 1;
3433 std::stringstream stream;
3434
3435 /* Get max number of samples */
3436 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3437
3438 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3439 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3440
3441 stream << samples - 1;
3442
3443 return stream.str();
3444 }
3445
3446 /** Prepares source texture
3447 *
3448 * @param format_idx Index of texture format
3449 * @param target_idx Index of texture target
3450 * @param out_sizes Sizes of storage used for texture channels
3451 **/
prepareSourceTexture(size_t format_idx,size_t target_idx,glw::GLint out_sizes[4])3452 void SmokeTest::prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4])
3453 {
3454 static const glw::GLint border = 0;
3455 static const glw::GLint level = 0;
3456
3457 /* */
3458 const glw::GLenum target = texture_targets[target_idx].m_target;
3459 const _texture_format &texture_format = texture_formats[format_idx];
3460
3461 /* */
3462 glw::GLenum error = 0;
3463 const glw::GLenum format = texture_format.m_format;
3464 const glw::GLchar *function_name = "unknown";
3465 const glw::GLenum internal_format = texture_format.m_internal_format;
3466 glw::GLsizei samples = 1;
3467 glw::GLenum target_get_prm = target;
3468 const glw::GLenum type = texture_format.m_type;
3469
3470 /* */
3471 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3472
3473 /* Get max number of samples */
3474 gl.getIntegerv(GL_MAX_SAMPLES, &samples);
3475 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3476
3477 /* Generate and bind */
3478 gl.genTextures(1, &m_source_tex_id);
3479 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
3480
3481 gl.bindTexture(target, m_source_tex_id);
3482 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3483
3484 /* Allocate storage */
3485 switch (target)
3486 {
3487 case GL_TEXTURE_1D:
3488
3489 gl.texImage1D(target, level, internal_format, m_width, border, format, type, 0 /* pixels */);
3490 error = gl.getError();
3491 function_name = "TexImage1D";
3492
3493 break;
3494
3495 case GL_TEXTURE_1D_ARRAY:
3496 case GL_TEXTURE_2D:
3497 case GL_TEXTURE_RECTANGLE:
3498 gl.texImage2D(target, level, internal_format, m_width, m_height, border, format, type, 0 /* pixels */);
3499 error = gl.getError();
3500 function_name = "TexImage2D";
3501
3502 break;
3503
3504 case GL_TEXTURE_2D_ARRAY:
3505 case GL_TEXTURE_3D:
3506 gl.texImage3D(target, level, internal_format, m_width, m_height, m_depth, border, format, type, 0 /* pixels */);
3507 error = gl.getError();
3508 function_name = "TexImage3D";
3509
3510 break;
3511
3512 case GL_TEXTURE_CUBE_MAP:
3513 for (size_t i = 0; i < n_cube_map_faces; ++i)
3514 {
3515 gl.texImage2D(cube_map_faces[i], level, internal_format, m_width, m_height, border, format, type,
3516 0 /* pixels */);
3517 }
3518 error = gl.getError();
3519 function_name = "TexImage2D";
3520
3521 target_get_prm = cube_map_faces[0];
3522
3523 break;
3524
3525 case GL_TEXTURE_2D_MULTISAMPLE:
3526 gl.texImage2DMultisample(target, samples, internal_format, m_width, m_height,
3527 GL_FALSE /* fixedsamplelocation */);
3528 error = gl.getError();
3529 function_name = "TexImage2DMultisample";
3530
3531 break;
3532
3533 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3534 gl.texImage3DMultisample(target, samples, internal_format, m_width, m_height, m_depth,
3535 GL_FALSE /* fixedsamplelocation */);
3536 error = gl.getError();
3537 function_name = "TexImage3DMultisample";
3538
3539 break;
3540
3541 default:
3542 TCU_FAIL("Invalid enum");
3543 }
3544
3545 /* Log error */
3546 GLU_EXPECT_NO_ERROR(error, function_name);
3547
3548 /* Make texture complete and set ds texture mode */
3549 if ((GL_TEXTURE_2D_MULTISAMPLE != target) && (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != target) &&
3550 (GL_TEXTURE_RECTANGLE != target))
3551 {
3552 gl.texParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
3553 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3554
3555 gl.texParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
3556 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3557
3558 gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3559 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3560
3561 gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3562 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3563 }
3564
3565 if (texture_format.m_ds_mode == GL_STENCIL_INDEX)
3566 {
3567 gl.texParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE, texture_format.m_ds_mode);
3568 GLU_EXPECT_NO_ERROR(gl.getError(), "TexParameteri");
3569 }
3570
3571 /* Get internal storage sizes */
3572 switch (internal_format)
3573 {
3574 case GL_DEPTH24_STENCIL8:
3575 case GL_DEPTH32F_STENCIL8:
3576
3577 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_STENCIL_SIZE, out_sizes + 1);
3578 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3579
3580 /* Fall through */
3581
3582 case GL_DEPTH_COMPONENT16:
3583 case GL_DEPTH_COMPONENT24:
3584 case GL_DEPTH_COMPONENT32:
3585 case GL_DEPTH_COMPONENT32F:
3586
3587 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_DEPTH_SIZE, out_sizes + 0);
3588 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3589
3590 break;
3591
3592 default:
3593
3594 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_RED_SIZE, out_sizes + 0);
3595 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3596
3597 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_GREEN_SIZE, out_sizes + 1);
3598 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3599
3600 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_BLUE_SIZE, out_sizes + 2);
3601 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3602
3603 gl.getTexLevelParameteriv(target_get_prm, 0 /* level */, GL_TEXTURE_ALPHA_SIZE, out_sizes + 3);
3604 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv");
3605
3606 break;
3607 }
3608
3609 /* Unbind texture */
3610 gl.bindTexture(target, 0);
3611 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
3612 }
3613
3614 /** Initializes frame buffer and vertex array
3615 *
3616 **/
testInit()3617 void SmokeTest::testInit()
3618 {
3619 /* */
3620 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3621
3622 glw::GLint major = 0;
3623 glw::GLint minor = 0;
3624
3625 gl.getIntegerv(GL_MAJOR_VERSION, &major);
3626 gl.getIntegerv(GL_MINOR_VERSION, &minor);
3627
3628 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
3629
3630 if (4 < major)
3631 {
3632 m_is_ms_supported = true;
3633 }
3634 else if (4 == major)
3635 {
3636 if (3 <= minor)
3637 {
3638 m_is_ms_supported = true;
3639 }
3640 }
3641
3642 /* Context is below 4.3 */
3643 if (false == m_is_ms_supported)
3644 {
3645 m_is_ms_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_storage_multisample");
3646 }
3647
3648 #if ENABLE_DEBUG
3649
3650 gl.debugMessageCallback(debug_proc, &m_context);
3651 GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback");
3652
3653 #endif /* ENABLE_DEBUG */
3654
3655 /* Prepare FBOs */
3656 gl.genFramebuffers(1, &m_prepare_fbo_id);
3657 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3658
3659 gl.genFramebuffers(1, &m_test_fbo_id);
3660 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
3661
3662 /* Prepare blank VAO */
3663 gl.genVertexArrays(1, &m_vao_id);
3664 GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
3665
3666 gl.bindVertexArray(m_vao_id);
3667 GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
3668 }
3669
3670 /** Verifies contents of output image
3671 *
3672 * @param test_case Test case instance
3673 * @param ignored
3674 * @param ignored
3675 * @param index_of_swizzled_channel Index of swizzled channel
3676 * @param data Image contents
3677 **/
verifyOutputImage(const testCase & test_case,size_t,glw::GLint,size_t index_of_swizzled_channel,const glw::GLubyte * data)3678 void SmokeTest::verifyOutputImage(const testCase &test_case, size_t /* output_format_index */,
3679 glw::GLint /* output_channel_size */, size_t index_of_swizzled_channel,
3680 const glw::GLubyte *data)
3681 {
3682 static const glw::GLuint rgba32ui[6] = {0x3fffffff, 0x7fffffff, 0xbfffffff, 0xffffffff, 1, 0};
3683
3684 const _texture_format &source_format = texture_formats[test_case.m_source_texture_format_index];
3685
3686 /* Set color */
3687 switch (source_format.m_internal_format)
3688 {
3689 case GL_RGBA32UI:
3690 {
3691 glw::GLuint expected_value = rgba32ui[index_of_swizzled_channel];
3692 const glw::GLuint *image = (glw::GLuint *)data;
3693
3694 for (size_t i = 0; i < m_output_width * m_output_height; ++i)
3695 {
3696 if (image[i] != expected_value)
3697 {
3698 TCU_FAIL("Found pixel with wrong value");
3699 }
3700 }
3701 }
3702 break;
3703
3704 default:
3705 TCU_FAIL("Invalid enum");
3706 }
3707 }
3708
3709 /** Constructor.
3710 *
3711 * @param context Rendering context.
3712 **/
FunctionalTest(deqp::Context & context)3713 FunctionalTest::FunctionalTest(deqp::Context &context)
3714 : SmokeTest(context, "functional",
3715 "Verifies that swizzle is respected for textures of different formats and targets")
3716 {
3717 /* Left blank intentionally */
3718 }
3719
3720 /** Executes test iteration.
3721 *
3722 * @return Returns STOP.
3723 */
iterate()3724 tcu::TestNode::IterateResult FunctionalTest::iterate()
3725 {
3726
3727 #if FUNCTIONAL_TEST_ALL_FORMATS == 0
3728
3729 static const glw::GLenum tested_formats[] = {GL_R8, GL_R3_G3_B2, GL_RGBA16, GL_R11F_G11F_B10F,
3730 GL_RGB9_E5, GL_DEPTH32F_STENCIL8};
3731 static const size_t n_tested_formats = sizeof(tested_formats) / sizeof(tested_formats[0]);
3732
3733 #endif /* FUNCTIONAL_TEST_ALL_FORMATS == 0 */
3734
3735 #if FUNCTIONAL_TEST_ALL_TARGETS == 0
3736
3737 static const glw::GLenum tested_targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
3738 static const size_t n_tested_targets = sizeof(tested_targets) / sizeof(tested_targets[0]);
3739
3740 #endif /* FUNCTIONAL_TEST_ALL_TARGETS == 0 */
3741
3742 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0
3743
3744 static const size_t access_idx = 4; /* 4 - index of "texelFetch" entry in texture_access_routines */
3745
3746 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES == 0 */
3747
3748 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0
3749
3750 static const size_t tested_swizzle_combinations[][4] = {
3751 {3, 2, 1, 0}, /* values are indices of entries in valid_values */
3752 {5, 4, 0, 3},
3753 {5, 5, 5, 5},
3754 {4, 4, 4, 4},
3755 {2, 2, 2, 2}};
3756 static const size_t n_tested_swizzle_combinations =
3757 sizeof(tested_swizzle_combinations) / sizeof(tested_swizzle_combinations[0]);
3758
3759 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS == 0 */
3760
3761 /* */
3762 bool test_result = true;
3763 glw::GLint source_channel_sizes[4] = {0};
3764
3765 /* */
3766 testInit();
3767
3768 /* Iterate over all cases */
3769
3770 #if FUNCTIONAL_TEST_ALL_FORMATS
3771
3772 for (size_t format_idx = 0; format_idx < n_texture_formats; ++format_idx)
3773 {
3774
3775 /* Check that format is supported by context. */
3776 if (!glu::contextSupports(m_context.getRenderContext().getType(),
3777 texture_formats[format_idx].m_minimum_gl_context))
3778 {
3779 continue;
3780 }
3781
3782 #else /* FUNCTIONAL_TEST_ALL_FORMATS */
3783
3784 for (size_t tested_format_idx = 0; tested_format_idx < n_tested_formats; ++tested_format_idx)
3785 {
3786 const size_t format_idx = get_index_of_format(tested_formats[tested_format_idx]);
3787
3788 #endif /* FUNCTIONAL_TEST_ALL_FORMATS */
3789
3790 #if FUNCTIONAL_TEST_ALL_TARGETS
3791
3792 for (size_t tgt_idx = 0; tgt_idx < n_texture_targets; ++tgt_idx)
3793 {
3794
3795 #else /* FUNCTIONAL_TEST_ALL_TARGETS */
3796
3797 for (size_t tested_tgt_idx = 0; tested_tgt_idx < n_tested_targets; ++tested_tgt_idx)
3798 {
3799 const size_t tgt_idx = get_index_of_target(tested_targets[tested_tgt_idx]);
3800
3801 #endif /* FUNCTIONAL_TEST_ALL_TARGETS */
3802
3803 /* Skip not supported targets */
3804 if (false == isTargetSupported(tgt_idx))
3805 {
3806 continue;
3807 }
3808
3809 /* Skip invalid cases */
3810 if (false == isTargetSuppByFormat(format_idx, tgt_idx))
3811 {
3812 continue;
3813 }
3814
3815 try
3816 {
3817 prepareSourceTexture(format_idx, tgt_idx, source_channel_sizes);
3818
3819 /* Skip formats not supported by FBO */
3820 if (false == fillSourceTexture(format_idx, tgt_idx))
3821 {
3822 deinitTextures();
3823 continue;
3824 }
3825
3826 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3827
3828 for (size_t access_idx = 0; access_idx < n_texture_access; ++access_idx)
3829 {
3830 /* Skip invalid cases */
3831 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3832 {
3833 continue;
3834 }
3835 #else /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3836 /* Skip invalid cases */
3837 if (false == isTargetSuppByAccess(access_idx, tgt_idx))
3838 {
3839 deinitTextures();
3840 continue;
3841 }
3842 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3843
3844 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3845
3846 for (size_t r = 0; r < n_valid_values; ++r)
3847 {
3848 for (size_t g = 0; g < n_valid_values; ++g)
3849 {
3850 for (size_t b = 0; b < n_valid_values; ++b)
3851 {
3852 for (size_t a = 0; a < n_valid_values; ++a)
3853 {
3854
3855 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3856
3857 for (size_t tested_swizzle_idx = 0; tested_swizzle_idx < n_tested_swizzle_combinations;
3858 ++tested_swizzle_idx)
3859 {
3860 const size_t r = tested_swizzle_combinations[tested_swizzle_idx][0];
3861 const size_t g = tested_swizzle_combinations[tested_swizzle_idx][1];
3862 const size_t b = tested_swizzle_combinations[tested_swizzle_idx][2];
3863 const size_t a = tested_swizzle_combinations[tested_swizzle_idx][3];
3864
3865 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3866
3867 for (size_t channel_idx = 0; channel_idx < 4; ++channel_idx)
3868 {
3869 const testCase test_case = {channel_idx,
3870 format_idx,
3871 tgt_idx,
3872 access_idx,
3873 valid_values[r],
3874 valid_values[g],
3875 valid_values[b],
3876 valid_values[a],
3877 {source_channel_sizes[0], source_channel_sizes[1],
3878 source_channel_sizes[2], source_channel_sizes[3]}};
3879
3880 executeTestCase(test_case);
3881
3882 deinitOutputTexture();
3883 } /* iteration over channels */
3884
3885 #if FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS
3886
3887 /* iteration over swizzle combinations */
3888 }
3889 }
3890 }
3891 }
3892
3893 #else /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3894
3895 } /* iteration over swizzle combinations */
3896
3897 #endif /* FUNCTIONAL_TEST_ALL_SWIZZLE_COMBINATIONS */
3898
3899 #if FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES
3900
3901 } /* iteration over access routines - only when enabled */
3902
3903 #endif /* FUNCTIONAL_TEST_ALL_ACCESS_ROUTINES */
3904 deinitTextures();
3905 } /* try */
3906 catch (wrongResults &exc)
3907 {
3908 logTestCaseDetials(exc.m_test_case);
3909 m_context.getTestContext().getLog() << tcu::TestLog::Message << exc.what() << tcu::TestLog::EndMessage;
3910
3911 test_result = false;
3912 deinitTextures();
3913 }
3914 catch (...)
3915 {
3916 deinitTextures();
3917 throw;
3918 }
3919 } /* iteration over texture targets */
3920
3921 } /* iteration over texture formats */
3922
3923 /* Set result */
3924 if (true == test_result)
3925 {
3926 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
3927 }
3928 else
3929 {
3930 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3931 }
3932
3933 /* Done */
3934 return STOP;
3935 }
3936
3937 /** Fills multisampled source texture
3938 *
3939 * @param format_idx Index of format
3940 * @param target_idx Index of target
3941 *
3942 * @return True if operation was successful, false other wise
3943 **/
3944 bool FunctionalTest::fillMSTexture(size_t format_idx, size_t target_idx)
3945 {
3946 const glw::GLenum target = texture_targets[target_idx].m_target;
3947
3948 /* */
3949 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
3950
3951 /* Bind FBO */
3952 gl.bindFramebuffer(GL_FRAMEBUFFER, m_prepare_fbo_id);
3953 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3954
3955 /* Attach texture */
3956 switch (target)
3957 {
3958 case GL_TEXTURE_2D_MULTISAMPLE:
3959
3960 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, m_source_tex_id, 0 /* level */);
3961 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3962
3963 break;
3964
3965 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
3966
3967 gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_source_tex_id, 0 /* level */, 0 /* layer */);
3968 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
3969
3970 break;
3971
3972 default:
3973 TCU_FAIL("Invalid enum");
3974 }
3975
3976 /* Verify status */
3977 const glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
3978 GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
3979
3980 if (GL_FRAMEBUFFER_UNSUPPORTED == status)
3981 {
3982 /* Unbind */
3983 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3984 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
3985
3986 return false;
3987 }
3988 else if (GL_FRAMEBUFFER_COMPLETE != status)
3989 {
3990 TCU_FAIL("Framebuffer is incomplete. Format is supported");
3991 }
3992
3993 /* Set Viewport */
3994 gl.viewport(0 /* x */, 0 /* y */, m_output_width, m_output_height);
3995 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3996
3997 Utils::programInfo program(m_context);
3998 prepareProgram(format_idx, program);
3999
4000 gl.useProgram(program.m_program_object_id);
4001 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
4002
4003 /* Clear */
4004 gl.clear(GL_COLOR_BUFFER_BIT);
4005 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
4006
4007 /* Draw */
4008 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
4009 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
4010
4011 /* Unbind FBO */
4012 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4013 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
4014
4015 /* Done */
4016 return true;
4017 }
4018
4019 /** Fills source texture
4020 *
4021 * @param format_idx Index of format
4022 * @param target_idx Index of target
4023 *
4024 * @return True if operation was successful, false other wise
4025 **/
4026 bool FunctionalTest::fillSourceTexture(size_t format_idx, size_t target_idx)
4027 {
4028 const glw::GLenum target = texture_targets[target_idx].m_target;
4029 const _texture_format &format = texture_formats[format_idx];
4030
4031 /* */
4032 const glw::Functions &gl = m_context.getRenderContext().getFunctions();
4033
4034 /* Result */
4035 bool result = true;
4036
4037 /* Bind texture */
4038 gl.bindTexture(target, m_source_tex_id);
4039 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4040
4041 /* Attach texture */
4042 switch (target)
4043 {
4044 case GL_TEXTURE_1D:
4045 gl.texSubImage1D(target, 0 /* level */, 0 /* x */, m_width, format.m_format, format.m_type,
4046 format.m_source_data);
4047 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D");
4048
4049 break;
4050
4051 case GL_TEXTURE_1D_ARRAY:
4052 case GL_TEXTURE_2D:
4053 case GL_TEXTURE_RECTANGLE:
4054 gl.texSubImage2D(target, 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format, format.m_type,
4055 format.m_source_data);
4056 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4057
4058 break;
4059
4060 case GL_TEXTURE_2D_ARRAY:
4061 case GL_TEXTURE_3D:
4062 gl.texSubImage3D(target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, m_width, m_height, m_depth,
4063 format.m_format, format.m_type, format.m_source_data);
4064 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D");
4065
4066 break;
4067
4068 case GL_TEXTURE_CUBE_MAP:
4069 for (size_t i = 0; i < n_cube_map_faces; ++i)
4070 {
4071 gl.texSubImage2D(cube_map_faces[i], 0 /* level */, 0 /* x */, 0 /* y */, m_width, m_height, format.m_format,
4072 format.m_type, format.m_source_data);
4073 GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D");
4074 }
4075
4076 break;
4077
4078 case GL_TEXTURE_2D_MULTISAMPLE:
4079 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4080 result = fillMSTexture(format_idx, target_idx);
4081
4082 break;
4083
4084 default:
4085 TCU_FAIL("Invalid enum");
4086 }
4087
4088 /* Unbind */
4089 gl.bindTexture(target, 0);
4090 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
4091
4092 /* Done */
4093 return result;
4094 }
4095
4096 /** Prepares program used to fill multisampled texture
4097 *
4098 * @param format_idx Index of texture format
4099 * @param program Instance of program that will be prepared
4100 **/
4101 void FunctionalTest::prepareProgram(size_t format_idx, Utils::programInfo &program)
4102 {
4103 static const glw::GLchar *fs_template = "#version 330 core\n"
4104 "\n"
4105 "out PREFIXvec4 out_color;\n"
4106 "\n"
4107 "void main()\n"
4108 "{\n"
4109 " out_color = PREFIXvec4(VALUES);\n"
4110 "}\n"
4111 "\n";
4112
4113 const _texture_format &format = texture_formats[format_idx];
4114 const std::string &values = prepareValues(format_idx);
4115 const std::string &vs = getVertexShader(testCase(), false); /* Get blank VS */
4116
4117 std::string fs = fs_template;
4118 size_t position = 0;
4119
4120 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4121 Utils::replaceToken("PREFIX", position, format.m_sampler.m_sampler_prefix, fs);
4122 Utils::replaceToken("VALUES", position, values.c_str(), fs);
4123
4124 program.build(fs.c_str(), vs.c_str());
4125 }
4126
4127 /** Prepares hardcoded values used by program to fill multisampled textures
4128 *
4129 * @param format_idx Index of texture format
4130 *
4131 * @return Shader source
4132 **/
4133 std::string FunctionalTest::prepareValues(size_t format_idx)
4134 {
4135 double ch_rgba[4] = {0.0, 0.0, 0.0, 0.0};
4136
4137 calculate_values_from_source(format_idx, ch_rgba);
4138
4139 /* Prepare string */
4140 std::stringstream stream;
4141 stream << ch_rgba[0] << ", " << ch_rgba[1] << ", " << ch_rgba[2] << ", " << ch_rgba[3];
4142
4143 return stream.str();
4144 }
4145
4146 /** Verifies if value is in <low:top> range
4147 *
4148 * @tparam T Type oo values
4149 *
4150 * @param value Value to check
4151 * @param low Lowest acceptable value
4152 * @param top Highest acceptable value
4153 *
4154 * @return true if value is in range, false otherwise
4155 **/
4156 template <typename T>
4157 bool isInRange(const void *value, const void *low, const void *top)
4158 {
4159 const T *v_ptr = (const T *)value;
4160 const T *l_ptr = (const T *)low;
4161 const T *t_ptr = (const T *)top;
4162
4163 if ((*v_ptr > *t_ptr) || (*v_ptr < *l_ptr))
4164 {
4165 return false;
4166 }
4167
4168 return true;
4169 }
4170
4171 /** Verifies contents of output image
4172 *
4173 * @param test_case Test case instance
4174 * @param output_format_index Index of format used by output texture
4175 * @parma output_channel_size Size of storage used by output texture in bits
4176 * @param index_of_swizzled_channel Index of swizzled channel
4177 * @param data Image contents
4178 **/
4179 void FunctionalTest::verifyOutputImage(const testCase &test_case, size_t output_format_index,
4180 glw::GLint output_channel_size, size_t index_of_swizzled_channel,
4181 const glw::GLubyte *data)
4182 {
4183 const _texture_format &output_format = texture_formats[output_format_index];
4184
4185 glw::GLubyte expected_data_low[8] = {0};
4186 glw::GLubyte expected_data_top[8] = {0};
4187 size_t texel_size = 0;
4188
4189 calculate_expected_value(test_case.m_source_texture_format_index, output_format_index, index_of_swizzled_channel,
4190 test_case.m_texture_sizes[index_of_swizzled_channel], output_channel_size,
4191 expected_data_low, expected_data_top, texel_size);
4192
4193 for (size_t i = 0; i < m_output_height * m_output_width; ++i)
4194 {
4195 const size_t offset = i * texel_size;
4196 const glw::GLvoid *pointer = data + offset;
4197
4198 bool res = false;
4199
4200 switch (output_format.m_type)
4201 {
4202 case GL_BYTE:
4203 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4204 break;
4205 case GL_UNSIGNED_BYTE:
4206 res = isInRange<glw::GLubyte>(pointer, expected_data_low, expected_data_top);
4207 break;
4208 case GL_SHORT:
4209 res = isInRange<glw::GLshort>(pointer, expected_data_low, expected_data_top);
4210 break;
4211 case GL_UNSIGNED_SHORT:
4212 res = isInRange<glw::GLushort>(pointer, expected_data_low, expected_data_top);
4213 break;
4214 case GL_HALF_FLOAT:
4215 res = isInRange<glw::GLbyte>(pointer, expected_data_low, expected_data_top);
4216 break;
4217 case GL_INT:
4218 res = isInRange<glw::GLint>(pointer, expected_data_low, expected_data_top);
4219 break;
4220 case GL_UNSIGNED_INT:
4221 res = isInRange<glw::GLhalf>(pointer, expected_data_low, expected_data_top);
4222 break;
4223 case GL_FLOAT:
4224 res = isInRange<glw::GLfloat>(pointer, expected_data_low, expected_data_top);
4225 break;
4226 default:
4227 TCU_FAIL("Invalid enum");
4228 }
4229
4230 if (false == res)
4231 {
4232 throw wrongResults(test_case);
4233 }
4234 }
4235 }
4236 } // namespace TextureSwizzle
4237
4238 /** Constructor.
4239 *
4240 * @param context Rendering context.
4241 **/
4242 TextureSwizzleTests::TextureSwizzleTests(deqp::Context &context)
4243 : TestCaseGroup(context, "texture_swizzle", "Verifies \"texture_swizzle\" functionality")
4244 {
4245 /* Left blank on purpose */
4246 }
4247
4248 /** Initializes a texture_storage_multisample test group.
4249 *
4250 **/
4251 void TextureSwizzleTests::init(void)
4252 {
4253 addChild(new TextureSwizzle::APIErrorsTest(m_context));
4254 addChild(new TextureSwizzle::IntialStateTest(m_context));
4255 addChild(new TextureSwizzle::SmokeTest(m_context));
4256 addChild(new TextureSwizzle::FunctionalTest(m_context));
4257 }
4258 } // namespace gl3cts
4259