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