1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24 /*!
25 * \file esextcTextureCubeMapArraySampling.cpp
26 * \brief Texture Cube Map Array Sampling (Test 1)
27 */ /*-------------------------------------------------------------------*/
28
29 /* Control logging of positive results. 0 disabled, 1 enabled */
30 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG 0
31
32 /* Control logging of program source for positive results. 0 disabled, 1 enabled */
33 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG 1
34
35 /* Control logging of negative results. 0 disabled, 1 enabled */
36 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG 1
37
38 /* Control logging of program source for negative results. 0 disabled, 1 enabled */
39 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG 1
40
41 /* When enabled, textures will be stored as TGA files. Test will not be executed. 0 disabled, 1 enabled */
42 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION 0
43
44 /* Output path for TGA files */
45 #define TEXTURECUBEMAPARRAYSAMPLINGTEST_PATH_FOR_COMPRESSION "c:\\textures\\"
46
47 #include "esextcTextureCubeMapArraySampling.hpp"
48 #include "esextcTextureCubeMapArraySamplingResources.hpp"
49
50 #include "gluContextInfo.hpp"
51 #include "glwEnums.hpp"
52 #include "glwFunctions.hpp"
53 #include "tcuTestLog.hpp"
54
55 #include <cmath>
56 #include <sstream>
57 #include <vector>
58
59 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION
60 #include <fstream>
61 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */
62
63 namespace glcts
64 {
65 /** Structure used to write shaders' variables to stream
66 *
67 **/
68 struct var2str
69 {
70 public:
71 /** Constructor. Stores strings used to create variable name
72 * prefixName[index]
73 *
74 * @param prefix Prefix part. Can be null.
75 * @param name Name part. Must not be null.
76 * @param index Index part. Can be null.
77 **/
var2strglcts::var2str78 var2str(const glw::GLchar* prefix, const glw::GLchar* name, const glw::GLchar* index)
79 : m_prefix(prefix), m_name(name), m_index(index)
80 {
81 /* Nothing to be done here */
82 }
83
84 const glw::GLchar* m_prefix;
85 const glw::GLchar* m_name;
86 const glw::GLchar* m_index;
87 };
88
89 /* Attribute names */
90 const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_grad_x = "grad_x";
91 const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_grad_y = "grad_y";
92 const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_lod = "lod";
93 const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_refZ = "refZ";
94 const glw::GLchar* const TextureCubeMapArraySamplingTest::attribute_texture_coordinate = "texture_coordinates";
95
96 /* Compute shader parts */
97 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_body =
98 "void main()\n"
99 "{\n"
100 " const int face_width = 3;\n"
101 " const int face_height = 3;\n"
102 " const int vertices_per_face = face_width * face_height;\n"
103 " const int faces_per_layer = 6;\n"
104 " const int layer_width = faces_per_layer * face_width;\n"
105 " const int vertices_per_layer = vertices_per_face * faces_per_layer;\n"
106 "\n"
107 " ivec2 image_coord = ivec2(gl_WorkGroupID.xy);\n"
108 " ivec3 texture_size = textureSize(sampler, 0);\n"
109 "\n"
110 " int layer = image_coord.x / layer_width;\n"
111 " int layer_offset = layer * layer_width;\n"
112 " int layer_index = layer * vertices_per_layer;\n"
113 " int face = (image_coord.x - layer_offset) / face_width;\n"
114 " int face_offset = face * face_width;\n"
115 " int face_index = face * vertices_per_face;\n"
116 " int vertex = image_coord.x - layer_offset - face_offset;\n"
117 " int vertex_index = layer_index + face_index + vertex + (face_height - image_coord.y - 1) * "
118 "face_width;\n"
119 "\n";
120 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_layout_binding = "layout(std430, binding=";
121 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_buffer = ") buffer ";
122 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_color = "color";
123 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_image_store =
124 " imageStore(image, image_coord, ";
125 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_layout =
126 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n";
127 const glw::GLchar* const TextureCubeMapArraySamplingTest::compute_shader_param = "cs_";
128
129 /* Fragment shader parts */
130 const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_input = "fs_in_color";
131 const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_output = "fs_out_color";
132 const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_pass_through_body_code =
133 "void main()\n"
134 "{\n"
135 " fs_out_color = fs_in_color;\n"
136 "}\n";
137 const glw::GLchar* const TextureCubeMapArraySamplingTest::fragment_shader_sampling_body_code = "void main()\n"
138 "{\n";
139
140 /* Geometry shader parts */
141 const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_emit_vertex_code = " EmitVertex();\n"
142 "}\n";
143 const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_extension = "${GEOMETRY_SHADER_REQUIRE}\n";
144 const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_layout =
145 "layout(points) in;\n"
146 "layout(points, max_vertices=1) out;\n"
147 "\n";
148 const glw::GLchar* const TextureCubeMapArraySamplingTest::geometry_shader_sampling_body_code =
149 "void main()\n"
150 "{\n"
151 " gl_Position = gl_in[0].gl_Position;\n";
152
153 /* Image types and name */
154 const glw::GLchar* const TextureCubeMapArraySamplingTest::image_float = "image2D ";
155 const glw::GLchar* const TextureCubeMapArraySamplingTest::image_int = "iimage2D ";
156 const glw::GLchar* const TextureCubeMapArraySamplingTest::image_name = "image";
157 const glw::GLchar* const TextureCubeMapArraySamplingTest::image_uint = "uimage2D ";
158
159 /* Interpolation */
160 const glw::GLchar* const TextureCubeMapArraySamplingTest::interpolation_flat = "flat ";
161
162 /* Sampler types and name */
163 const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_depth = "samplerCubeArrayShadow ";
164 const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_float = "samplerCubeArray ";
165 const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_int = "isamplerCubeArray ";
166 const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_name = "sampler";
167 const glw::GLchar* const TextureCubeMapArraySamplingTest::sampler_uint = "usamplerCubeArray ";
168
169 /* Common shader parts for */
170 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_code_preamble = "${VERSION}\n"
171 "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n"
172 "\n";
173
174 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_precision = "precision highp float;\n";
175
176 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_input = "in ";
177 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_layout = "layout(location = 0) ";
178 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_output = "out ";
179 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_uniform = "uniform ";
180 const glw::GLchar* const TextureCubeMapArraySamplingTest::shader_writeonly = "writeonly ";
181
182 /* Tesselation control shader parts */
183 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_layout =
184 "layout(vertices = 1) out;\n"
185 "\n";
186 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_sampling_body_code =
187 "void main()\n"
188 "{\n"
189 " gl_TessLevelInner[0] = 1.0;\n"
190 " gl_TessLevelInner[1] = 1.0;\n"
191 " gl_TessLevelOuter[0] = 1.0;\n"
192 " gl_TessLevelOuter[1] = 1.0;\n"
193 " gl_TessLevelOuter[2] = 1.0;\n"
194 " gl_TessLevelOuter[3] = 1.0;\n"
195 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n";
196 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_control_shader_output = "tcs_out_";
197
198 /* Tesselation evaluation shader parts */
199 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_input = "tes_in_color";
200 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_layout =
201 "layout(isolines, point_mode) in;\n"
202 "\n";
203 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_pass_through_body_code =
204 "void main()\n"
205 "{\n"
206 " gl_Position = gl_in[0].gl_Position;\n"
207 " fs_in_color = tes_in_color[0];\n"
208 "}\n";
209 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_evaluation_shader_sampling_body_code =
210 "void main()\n"
211 "{\n"
212 " gl_Position = gl_in[0].gl_Position;\n";
213 const glw::GLchar* const TextureCubeMapArraySamplingTest::tesselation_shader_extension =
214 "${TESSELLATION_SHADER_REQUIRE}\n";
215
216 /* Texture sampling routines */
217 const glw::GLchar* const TextureCubeMapArraySamplingTest::texture_func = "texture";
218 const glw::GLchar* const TextureCubeMapArraySamplingTest::textureGather_func = "textureGather";
219 const glw::GLchar* const TextureCubeMapArraySamplingTest::textureGrad_func = "textureGrad";
220 const glw::GLchar* const TextureCubeMapArraySamplingTest::textureLod_func = "textureLod";
221
222 /* Data types */
223 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_float = "float ";
224 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_ivec4 = "ivec4 ";
225 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_uint = "uint ";
226 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_uvec4 = "uvec4 ";
227 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_vec3 = "vec3 ";
228 const glw::GLchar* const TextureCubeMapArraySamplingTest::type_vec4 = "vec4 ";
229
230 /* Vertex shader parts */
231 const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_body_code =
232 "void main()\n"
233 "{\n"
234 " gl_PointSize = 1.0f;\n"
235 " gl_Position = vs_in_position;\n";
236 const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_input = "vs_in_";
237 const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_output = "vs_out_";
238 const glw::GLchar* const TextureCubeMapArraySamplingTest::vertex_shader_position = "position";
239
240 /* Static constants */
241 const glw::GLuint TextureCubeMapArraySamplingTest::m_get_type_api_status_program_resource = 0x02;
242 const glw::GLuint TextureCubeMapArraySamplingTest::m_get_type_api_status_uniform = 0x01;
243 const glw::GLuint TextureCubeMapArraySamplingTest::bufferDefinition::m_invalid_buffer_object_id = -1;
244 const glw::GLuint TextureCubeMapArraySamplingTest::programDefinition::m_invalid_program_object_id = 0;
245 const glw::GLuint TextureCubeMapArraySamplingTest::shaderDefinition::m_invalid_shader_object_id = 0;
246 const glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::m_invalid_texture_object_id = -1;
247 const glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::m_invalid_uniform_location = -1;
248 const glw::GLuint TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::m_invalid_attribute_location = -1;
249 const glw::GLuint TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::m_invalid_vertex_array_object_id = -1;
250
251 /* Functions */
252
253 /** Fill image with specified color
254 * @tparam T Image component type
255 * @tparam N_Components Number of image components
256 *
257 * @param image_width Width of image
258 * @param image_height Height of image
259 * @param pixel_components Image will be filled with that color
260 * @param out_data Image data, storage must be allocated
261 **/
262 template <typename T, unsigned int N_Components>
fillImage(glw::GLsizei image_width,glw::GLsizei image_height,const T * pixel_components,T * out_data)263 void fillImage(glw::GLsizei image_width, glw::GLsizei image_height, const T* pixel_components, T* out_data)
264 {
265 const glw::GLuint n_components_per_pixel = N_Components;
266 const glw::GLuint n_components_per_line = n_components_per_pixel * image_width;
267
268 for (glw::GLsizei y = 0; y < image_height; ++y)
269 {
270 const glw::GLuint line_offset = y * n_components_per_line;
271
272 for (glw::GLsizei x = 0; x < image_width; ++x)
273 {
274 for (glw::GLuint component = 0; component < n_components_per_pixel; ++component)
275 {
276 out_data[line_offset + x * n_components_per_pixel + component] = pixel_components[component];
277 }
278 }
279 }
280 }
281
282 /* Out of alphabetical order due to use in other functions */
283 /** Normalize vector stored in array. Only first N_NormalizedComponents will be normalized.
284 *
285 * @tparam N_NormalizedComponents Number of coordinates to normalize
286 * @tparam N_Components Number of coordinates in vector
287 *
288 * @param data Pointer to first coordinate of first vector in array
289 * @param index Index of vector to be normalized
290 **/
291 template <unsigned int N_NormalizedComponents, unsigned int N_Components>
vectorNormalize(glw::GLfloat * data,glw::GLuint index)292 void vectorNormalize(glw::GLfloat* data, glw::GLuint index)
293 {
294 glw::GLfloat* components = data + index * N_Components;
295
296 glw::GLfloat sqr_length = 0.0f;
297
298 for (glw::GLuint i = 0; i < N_NormalizedComponents; ++i)
299 {
300 const glw::GLfloat component = components[i];
301
302 sqr_length += component * component;
303 }
304
305 const glw::GLfloat length = sqrtf(sqr_length);
306 const glw::GLfloat factor = 1.0f / length;
307
308 for (glw::GLuint i = 0; i < N_NormalizedComponents; ++i)
309 {
310 components[i] *= factor;
311 }
312 }
313
314 /* Out of alphabetical order due to use in other functions */
315 /** Set coordinates of 4 element vector stored in array
316 *
317 * @param data Pointer to first coordinate of first vector in array
318 * @param index Index of vector to be normalized
319 * @param x 1st coordinate value
320 * @param y 2nd coordinate value
321 * @param z 3rd coordinate value
322 * @param w 4th coordinate value
323 **/
vectorSet4(glw::GLfloat * data,glw::GLuint index,glw::GLfloat x,glw::GLfloat y,glw::GLfloat z,glw::GLfloat w)324 void vectorSet4(glw::GLfloat* data, glw::GLuint index, glw::GLfloat x, glw::GLfloat y, glw::GLfloat z, glw::GLfloat w)
325 {
326 const glw::GLuint n_components_per_vertex = 4;
327 const glw::GLuint vector_offset = n_components_per_vertex * index;
328
329 data[vector_offset + 0] = x;
330 data[vector_offset + 1] = y;
331 data[vector_offset + 2] = z;
332 data[vector_offset + 3] = w;
333 }
334
335 /* Out of alphabetical order due to use in other functions */
336 /** Subtract vectors: a = b - a
337 *
338 * @tparam N_Components Number of coordinates in vector
339 *
340 * @param a Pointer to vector a
341 * @param b Pointer to vector b
342 **/
343 template <unsigned int N_Components>
vectorSubtractInPlace(glw::GLfloat * a,const glw::GLfloat * b)344 void vectorSubtractInPlace(glw::GLfloat* a, const glw::GLfloat* b)
345 {
346 const glw::GLuint n_components = N_Components;
347
348 for (glw::GLuint i = 0; i < n_components; ++i)
349 {
350 a[i] -= b[i];
351 }
352 }
353
354 /** Prepare color for rgba float textures
355 *
356 * @param cube_face Index of cube's face
357 * @param element_index Index of element in array
358 * @param mipmap_level Mipmap level
359 * @param n_elements Number of elements in array
360 * @param n_mipmap_levels Number of mipmap levels
361 * @param out_data Pointer to components storage
362 **/
getColorFloatComponents(glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLfloat * out_data)363 void getColorFloatComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level,
364 glw::GLint n_elements, glw::GLint n_mipmap_levels, glw::GLfloat* out_data)
365 {
366 static const glw::GLfloat n_faces = 6.0f;
367
368 out_data[0] = ((glw::GLfloat)(mipmap_level + 1)) / ((glw::GLfloat)n_mipmap_levels);
369 out_data[1] = ((glw::GLfloat)(cube_face + 1)) / n_faces;
370 out_data[2] = ((glw::GLfloat)(element_index + 1)) / ((glw::GLfloat)n_elements);
371 out_data[3] = 1.0f / 4.0f;
372 }
373
374 /** Prepare color for rgba integer textures
375 *
376 * @tparam T Type of components
377 *
378 * @param cube_face Index of cube's face
379 * @param element_index Index of element in array
380 * @param mipmap_level Mipmap level
381 * @param n_elements Number of elements in array, ignored
382 * @param n_mipmap_levels Number of mipmap levels, ignored
383 * @param out_data Pointer to components storage
384 **/
385 template <typename T>
getColorIntComponents(glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint,glw::GLint,T * out_data)386 void getColorIntComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level,
387 glw::GLint /* n_elements */, glw::GLint /* n_mipmap_levels */, T* out_data)
388 {
389 out_data[0] = static_cast<T>(mipmap_level + 1);
390 out_data[1] = static_cast<T>(cube_face + 1);
391 out_data[2] = static_cast<T>(element_index + 1);
392 out_data[3] = 1;
393 }
394
395 /** Prepare color for rgba compressed textures
396 *
397 * @param cube_face Index of cube's face
398 * @param element_index Index of element in array
399 * @param mipmap_level Mipmap level
400 * @param n_elements Number of elements in array
401 * @param n_mipmap_levels Number of mipmap levels
402 * @param out_data Pointer to components storage
403 **/
getCompressedColorUByteComponents(glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLubyte * out_data)404 void getCompressedColorUByteComponents(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level,
405 glw::GLint n_elements, glw::GLint n_mipmap_levels, glw::GLubyte* out_data)
406 {
407 (void)n_mipmap_levels;
408
409 static const glw::GLuint n_faces = 6;
410
411 const glw::GLuint n_faces_per_level = n_elements * n_faces;
412 const glw::GLubyte value =
413 static_cast<glw::GLubyte>(mipmap_level * n_faces_per_level + element_index * n_faces + cube_face + 1);
414
415 out_data[0] = value;
416 out_data[1] = value;
417 out_data[2] = value;
418 out_data[3] = value;
419 }
420
421 /** Get compressed texture data and size from resources. Width, height, number of array elements and mipmap level are used to identify image.
422 * Width and height are dimmensions of base level image, same values are used to identify all mipmap levels.
423 *
424 * @param width Width of texture
425 * @param height Height of texture
426 * @param n_array_elements Number of elemnts in array
427 * @param mipmap_level Level
428 * @param out_image_data Image data
429 * @param out_image_size Image size
430 **/
getCompressedTexture(glw::GLuint width,glw::GLuint height,glw::GLuint n_array_elements,glw::GLuint mipmap_level,const glw::GLubyte * & out_image_data,glw::GLuint & out_image_size)431 void getCompressedTexture(glw::GLuint width, glw::GLuint height, glw::GLuint n_array_elements, glw::GLuint mipmap_level,
432 const glw::GLubyte*& out_image_data, glw::GLuint& out_image_size)
433 {
434 for (glw::GLuint i = 0; i < n_compressed_images; ++i)
435 {
436 const compressedImage& image = compressed_images[i];
437
438 if ((image.width == width) && (image.height == height) && (image.length == n_array_elements) &&
439 (image.level == mipmap_level))
440 {
441 out_image_data = image.image_data;
442 out_image_size = image.image_size;
443
444 return;
445 }
446 }
447
448 out_image_data = 0;
449 out_image_size = 0;
450 }
451
452 /** Prepare color for depth textures
453 *
454 * @param cube_face Index of cube's face
455 * @param element_index Index of element in array
456 * @param mipmap_level Mipmap level
457 * @param n_elements Number of elements in array
458 * @param n_mipmap_levels Number of mipmap levels
459 * @param out_depth Depth value
460 **/
getDepthComponent(glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLfloat & out_depth)461 void getDepthComponent(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level, glw::GLint n_elements,
462 glw::GLint n_mipmap_levels, glw::GLfloat& out_depth)
463 {
464 static const glw::GLuint n_faces = 6;
465
466 out_depth = ((glw::GLfloat)(mipmap_level + 1 + cube_face + 1 + element_index + 1)) /
467 ((glw::GLfloat)(n_mipmap_levels + n_faces + n_elements));
468 }
469
470 /** Get expected color sampled by texture or textureGather from rgba float textures
471 *
472 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
473 * @param cube_face Index of cube's face
474 * @param element_index Index of element in array
475 * @param n_layers Number of elements in array
476 * @param n_mipmap_levels Number of mipmap levels
477 * @param out_components Pointer to components storage
478 **/
getExpectedColorFloatComponentsForTexture(glw::GLuint,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLfloat * out_components)479 void getExpectedColorFloatComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
480 glw::GLint element_index, glw::GLint n_layers,
481 glw::GLint n_mipmap_levels, glw::GLfloat* out_components)
482 {
483 getColorFloatComponents(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, out_components);
484 }
485
486 /** Get expected color sampled by textureLod or textureGrad from rgba float textures
487 *
488 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
489 * @param cube_face Index of cube's face
490 * @param element_index Index of element in array
491 * @param n_layers Number of elements in array
492 * @param n_mipmap_levels Number of mipmap levels
493 * @param out_components Pointer to components storage
494 **/
getExpectedColorFloatComponentsForTextureLod(glw::GLuint pixel_index,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLfloat * out_components)495 void getExpectedColorFloatComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face,
496 glw::GLint element_index, glw::GLint n_layers,
497 glw::GLint n_mipmap_levels, glw::GLfloat* out_components)
498 {
499 glw::GLint mipmap_level = 0;
500
501 if (1 == pixel_index % 2)
502 {
503 mipmap_level = n_mipmap_levels - 1;
504 }
505
506 getColorFloatComponents(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, out_components);
507 }
508
509 /** Get expected color sampled by texture or textureGather from rgba integer textures
510 *
511 * @tparam T Type of image components
512 *
513 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
514 * @param cube_face Index of cube's face
515 * @param element_index Index of element in array
516 * @param n_layers Number of elements in array
517 * @param n_mipmap_levels Number of mipmap levels
518 * @param out_components Pointer to components storage
519 **/
520 template <typename T>
getExpectedColorIntComponentsForTexture(glw::GLuint,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,T * out_components)521 void getExpectedColorIntComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
522 glw::GLint element_index, glw::GLint n_layers, glw::GLint n_mipmap_levels,
523 T* out_components)
524 {
525 getColorIntComponents<T>(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, out_components);
526 }
527
528 /** Get expected color sampled by textureLod or textureGrad from rgba integer textures
529 *
530 * @tparam T Type of image components
531 *
532 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
533 * @param cube_face Index of cube's face
534 * @param element_index Index of element in array
535 * @param n_layers Number of elements in array
536 * @param n_mipmap_levels Number of mipmap levels
537 * @param out_components Pointer to components storage
538 **/
539 template <typename T>
getExpectedColorIntComponentsForTextureLod(glw::GLuint pixel_index,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,T * out_components)540 void getExpectedColorIntComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint element_index,
541 glw::GLint n_layers, glw::GLint n_mipmap_levels, T* out_components)
542 {
543 glw::GLint mipmap_level = 0;
544
545 if (1 == pixel_index % 2)
546 {
547 mipmap_level = n_mipmap_levels - 1;
548 }
549
550 getColorIntComponents<T>(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, out_components);
551 }
552
553 /** Get expected color sampled by texture or textureGather from rgba compressed textures
554 *
555 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
556 * @param cube_face Index of cube's face
557 * @param element_index Index of element in array
558 * @param n_layers Number of elements in array
559 * @param n_mipmap_levels Number of mipmap levels
560 * @param out_components Pointer to components storage
561 **/
getExpectedCompressedComponentsForTexture(glw::GLuint,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLubyte * out_components)562 void getExpectedCompressedComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
563 glw::GLint element_index, glw::GLint n_layers,
564 glw::GLint n_mipmap_levels, glw::GLubyte* out_components)
565 {
566 getCompressedColorUByteComponents(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels,
567 out_components);
568 }
569
570 /** Get expected color sampled by textureLod or textureGrad from rgba compressed textures
571 *
572 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
573 * @param cube_face Index of cube's face
574 * @param element_index Index of element in array
575 * @param n_layers Number of elements in array
576 * @param n_mipmap_levels Number of mipmap levels
577 * @param out_components Pointer to components storage
578 **/
getExpectedCompressedComponentsForTextureLod(glw::GLuint pixel_index,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLubyte * out_components)579 void getExpectedCompressedComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face,
580 glw::GLint element_index, glw::GLint n_layers,
581 glw::GLint n_mipmap_levels, glw::GLubyte* out_components)
582 {
583 glw::GLint mipmap_level = 0;
584
585 if (1 == pixel_index % 2)
586 {
587 mipmap_level = n_mipmap_levels - 1;
588 }
589
590 getCompressedColorUByteComponents(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels,
591 out_components);
592 }
593
594 /** Get expected color sampled by texture or textureGather from depth textures
595 *
596 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>
597 * @param cube_face Index of cube's face. Ignored.
598 * @param element_index Index of element in array. Ignored.
599 * @param n_layers Number of elements in array. Ignored.
600 * @param n_mipmap_levels Number of mipmap levels. Ignored.
601 * @param out_components Pointer to components storage
602 **/
getExpectedDepthComponentsForTexture(glw::GLuint pixel_index,glw::GLint,glw::GLint,glw::GLint,glw::GLint,glw::GLfloat * out_components)603 void getExpectedDepthComponentsForTexture(glw::GLuint pixel_index, glw::GLint /* cube_face */,
604 glw::GLint /* element_index */, glw::GLint /* n_layers */,
605 glw::GLint /* n_mipmap_levels */, glw::GLfloat* out_components)
606 {
607 const glw::GLfloat results[9] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
608
609 out_components[0] = results[pixel_index];
610 }
611
612 /** Get expected color sampled by textureLod or textureGrad from depth textures
613 *
614 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
615 * @param cube_face Index of cube's face. Ignored.
616 * @param element_index Index of element in array. Ignored.
617 * @param n_layers Number of elements in array. Ignored.
618 * @param n_mipmap_levels Number of mipmap levels. Ignored.
619 * @param out_components Pointer to components storage
620 **/
getExpectedDepthComponentsForTextureLod(glw::GLuint pixel_index,glw::GLint,glw::GLint,glw::GLint,glw::GLint,glw::GLfloat * out_components)621 void getExpectedDepthComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint /* cube_face */,
622 glw::GLint /* element_index */, glw::GLint /* n_layers */,
623 glw::GLint /* n_mipmap_levels */, glw::GLfloat* out_components)
624 {
625 if (0 == pixel_index % 2)
626 {
627 out_components[0] = 0.0f;
628 }
629 else
630 {
631 out_components[0] = 1.0f;
632 }
633 }
634
635 /* Out of alphabetical order due to use in other functions */
636 /** Prepare color for stencil textures
637 *
638 * @param cube_face Index of cube's face
639 * @param element_index Index of element in array
640 * @param mipmap_level Mipmap level
641 * @param n_elements Number of elements in array
642 * @param n_mipmap_levels Number of mipmap levels
643 * @param out_stencil Stencil value
644 **/
getStencilComponent(glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLubyte & out_stencil)645 void getStencilComponent(glw::GLint cube_face, glw::GLint element_index, glw::GLint mipmap_level, glw::GLint n_elements,
646 glw::GLint n_mipmap_levels, glw::GLubyte& out_stencil)
647 {
648 static const glw::GLint n_faces = 6;
649
650 out_stencil = (glw::GLubyte)((mipmap_level + 1 + cube_face + 1 + element_index + 1) * 255 /
651 (n_mipmap_levels + n_faces + n_elements));
652 }
653
654 /** Get expected color sampled by texture or textureGather from stencil textures
655 *
656 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>. Ignored.
657 * @param cube_face Index of cube's face
658 * @param element_index Index of element in array
659 * @param n_layers Number of elements in array
660 * @param n_mipmap_levels Number of mipmap levels
661 * @param out_components Pointer to components storage
662 **/
getExpectedStencilComponentsForTexture(glw::GLuint,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLuint * out_components)663 void getExpectedStencilComponentsForTexture(glw::GLuint /* pixel_index */, glw::GLint cube_face,
664 glw::GLint element_index, glw::GLint n_layers, glw::GLint n_mipmap_levels,
665 glw::GLuint* out_components)
666 {
667 glw::GLubyte value = 0;
668
669 getStencilComponent(cube_face, element_index, 0 /* mipmap_level */, n_layers, n_mipmap_levels, value);
670
671 out_components[0] = value;
672 }
673
674 /** Get expected color sampled by textureLod or textureGrad from stencil textures
675 *
676 * @param pixel_index Index of pixel, identifies pixel at face <0:8> <left-top:rigth-bottom>.
677 * @param cube_face Index of cube's face
678 * @param element_index Index of element in array
679 * @param n_layers Number of elements in array
680 * @param n_mipmap_levels Number of mipmap levels
681 * @param out_components Pointer to components storage
682 **/
getExpectedStencilComponentsForTextureLod(glw::GLuint pixel_index,glw::GLint cube_face,glw::GLint element_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,glw::GLuint * out_components)683 void getExpectedStencilComponentsForTextureLod(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint element_index,
684 glw::GLint n_layers, glw::GLint n_mipmap_levels,
685 glw::GLuint* out_components)
686 {
687 glw::GLubyte value = 0;
688 glw::GLint mipmap_level = 0;
689
690 if (1 == pixel_index % 2)
691 {
692 mipmap_level = n_mipmap_levels - 1;
693 }
694
695 getStencilComponent(cube_face, element_index, mipmap_level, n_layers, n_mipmap_levels, value);
696
697 out_components[0] = value;
698 }
699
700 /** Returns number of mipmaps for given image dimmensions
701 *
702 * @param texture_width Width of image
703 * @param texture_height Height of image
704 *
705 * @returns Number of mipmaps
706 **/
getMipmapLevelCount(glw::GLsizei texture_width,glw::GLsizei texture_height)707 glw::GLubyte getMipmapLevelCount(glw::GLsizei texture_width, glw::GLsizei texture_height)
708 {
709 glw::GLsizei size = de::max(texture_width, texture_height);
710 glw::GLuint count = 1;
711
712 while (1 < size)
713 {
714 size /= 2;
715 count += 1;
716 }
717
718 return (glw::GLubyte)count;
719 }
720
721 /** Calculate texture coordinates for "right neighbour" of given texture coordinates
722 *
723 * @param texture_coordinates Texture coordinates of original point
724 * @param face Cube map's face index
725 * @param offset Offset of "neighbour" in "right" direction
726 * @param width Image width
727 * @param out_neighbour Texture coordinates of "neighbour" point
728 **/
getRightNeighbour(const glw::GLfloat * texture_coordinates,glw::GLuint face,glw::GLuint offset,glw::GLuint width,glw::GLfloat * out_neighbour)729 void getRightNeighbour(const glw::GLfloat* texture_coordinates, glw::GLuint face, glw::GLuint offset, glw::GLuint width,
730 glw::GLfloat* out_neighbour)
731 {
732 const glw::GLfloat step = (float)offset / (float)width;
733
734 glw::GLfloat& x = out_neighbour[0];
735 glw::GLfloat& y = out_neighbour[1];
736 glw::GLfloat& z = out_neighbour[2];
737
738 const glw::GLfloat coord_x = texture_coordinates[0];
739 const glw::GLfloat coord_y = texture_coordinates[1];
740 const glw::GLfloat coord_z = texture_coordinates[2];
741
742 switch (face)
743 {
744 case 0: // +X
745 x = coord_x;
746 y = coord_y - step;
747 z = coord_z;
748 break;
749 case 1: // -X
750 x = coord_x;
751 y = coord_y + step;
752 z = coord_z;
753 break;
754 case 2: // +Y
755 x = coord_x + step;
756 y = coord_y;
757 z = coord_z;
758 break;
759 case 3: // -Y
760 x = coord_x - step;
761 y = coord_y;
762 z = coord_z;
763 break;
764 case 4: // +Z
765 x = coord_x + step;
766 y = coord_y;
767 z = coord_z;
768 break;
769 case 5: // -Z
770 x = coord_x - step;
771 y = coord_y;
772 z = coord_z;
773 break;
774 }
775 }
776
777 /** Calculate texture coordinates for "top neighbour" of given texture coordinates
778 *
779 * @param texture_coordinates Texture coordinates of original point
780 * @param face Cube map's face index
781 * @param offset Offset of "neighbour" in "top" direction
782 * @param width Image width
783 * @param out_neighbour Texture coordinates of "neighbour" point
784 **/
getTopNeighbour(const glw::GLfloat * texture_coordinates,glw::GLuint face,glw::GLuint offset,glw::GLuint width,glw::GLfloat * out_neighbour)785 void getTopNeighbour(const glw::GLfloat* texture_coordinates, glw::GLuint face, glw::GLuint offset, glw::GLuint width,
786 glw::GLfloat* out_neighbour)
787 {
788 glw::GLfloat step = (float)offset / (float)width;
789
790 glw::GLfloat& x = out_neighbour[0];
791 glw::GLfloat& y = out_neighbour[1];
792 glw::GLfloat& z = out_neighbour[2];
793
794 const glw::GLfloat coord_x = texture_coordinates[0];
795 const glw::GLfloat coord_y = texture_coordinates[1];
796 const glw::GLfloat coord_z = texture_coordinates[2];
797
798 switch (face)
799 {
800 case 0: // +X
801 x = coord_x;
802 y = coord_y;
803 z = coord_z + step;
804 break;
805 case 1: // -X
806 x = coord_x;
807 y = coord_y;
808 z = coord_z + step;
809 break;
810 case 2: // +Y
811 x = coord_x;
812 y = coord_y;
813 z = coord_z + step;
814 break;
815 case 3: // -Y
816 x = coord_x;
817 y = coord_y;
818 z = coord_z + step;
819 break;
820 case 4: // +Z
821 x = coord_x;
822 y = coord_y - step;
823 z = coord_z;
824 break;
825 case 5: // -Z
826 x = coord_x;
827 y = coord_y + step;
828 z = coord_z;
829 break;
830 }
831 }
832
833 /** Write var2str instance to output stream
834 *
835 * @param stream Stream instance
836 * @param var var2str instance
837 *
838 * @returns Stream instance
839 **/
operator <<(std::ostream & stream,const var2str & var)840 std::ostream& operator<<(std::ostream& stream, const var2str& var)
841 {
842 if (0 != var.m_prefix)
843 {
844 stream << var.m_prefix;
845 }
846
847 stream << var.m_name;
848
849 if (0 != var.m_index)
850 {
851 stream << "[" << var.m_index << "]";
852 }
853
854 return stream;
855 }
856
857 /* Out of alphabetical order due to use in other functions */
858 /** Fill texture's face at given index and level with given color
859 *
860 * @tparam T Type of image component
861 * @tparam N_Components Number of components
862 *
863 * @param gl GL functions
864 * @param cube_face Index of cube map's face
865 * @param element_index Index of element in array
866 * @param mipmap_level Mipmap level
867 * @param texture_format Texture format
868 * @param texture_width Texture width
869 * @param texture_height Texture height
870 * @param components Color used to fill texture
871 **/
872 template <typename T, unsigned int N_Components>
prepareDataForTexture(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height,const T * components)873 void prepareDataForTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
874 glw::GLint mipmap_level, glw::GLenum texture_format, glw::GLenum texture_type,
875 glw::GLsizei texture_width, glw::GLsizei texture_height, const T* components)
876 {
877 static const glw::GLuint n_components_per_pixel = N_Components;
878
879 const glw::GLuint n_pixels = texture_width * texture_height;
880 const glw::GLuint n_total_componenets = n_components_per_pixel * n_pixels;
881 const glw::GLuint z_offset = element_index * 6 + cube_face;
882
883 std::vector<T> texture_data;
884 texture_data.resize(n_total_componenets);
885
886 fillImage<T, N_Components>(texture_width, texture_height, components, &texture_data[0]);
887
888 gl.texSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, 0 /* x */, 0 /* y */, z_offset, texture_width,
889 texture_height, 1 /* depth */, texture_format, texture_type, &texture_data[0]);
890
891 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update texture data");
892 }
893
894 /** Prepare texture's face at given index and level, for rgba float textures.
895 *
896 * @param gl GL functions
897 * @param cube_face Index of cube map's face
898 * @param element_index Index of element in array
899 * @param mipmap_level Mipmap level
900 * @param n_elements Number of elements in array
901 * @param n_mipmap_levels Number of mipmap levels
902 * @param texture_format Texture format
903 * @param texture_width Texture width
904 * @param texture_height Texture height
905 **/
prepareDataForColorFloatTexture(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)906 void prepareDataForColorFloatTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
907 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
908 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
909 glw::GLsizei texture_height)
910 {
911 glw::GLfloat components[4];
912
913 getColorFloatComponents(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, components);
914
915 prepareDataForTexture<glw::GLfloat, 4>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
916 texture_width, texture_height, components);
917 }
918
919 /** Prepare texture's face at given index and level, for rgba integer textures.
920 *
921 * @tparam T Type of image component
922 *
923 * @param gl GL functions
924 * @param cube_face Index of cube map's face
925 * @param element_index Index of element in array
926 * @param mipmap_level Mipmap level
927 * @param n_elements Number of elements in array
928 * @param n_mipmap_levels Number of mipmap levels
929 * @param texture_format Texture format
930 * @param texture_width Texture width
931 * @param texture_height Texture height
932 **/
933 template <typename T>
prepareDataForColorIntTexture(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)934 void prepareDataForColorIntTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
935 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
936 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
937 glw::GLsizei texture_height)
938 {
939 T components[4];
940
941 getColorIntComponents<T>(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, components);
942
943 prepareDataForTexture<T, 4>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type, texture_width,
944 texture_height, components);
945 }
946
947 /** Prepare texture's face at given index and level, for depth textures.
948 *
949 * @param gl GL functions
950 * @param cube_face Index of cube map's face
951 * @param element_index Index of element in array
952 * @param mipmap_level Mipmap level
953 * @param n_elements Number of elements in array
954 * @param n_mipmap_levels Number of mipmap levels
955 * @param texture_format Texture format
956 * @param texture_width Texture width
957 * @param texture_height Texture height
958 **/
prepareDataForDepthFloatTexture(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)959 void prepareDataForDepthFloatTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
960 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
961 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
962 glw::GLsizei texture_height)
963 {
964 glw::GLfloat component = 0;
965
966 getDepthComponent(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, component);
967
968 prepareDataForTexture<glw::GLfloat, 1>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
969 texture_width, texture_height, &component);
970 }
971
972 /** Prepare texture's face at given index and level, for stencil textures.
973 *
974 * @param gl GL functions
975 * @param cube_face Index of cube map's face
976 * @param element_index Index of element in array
977 * @param mipmap_level Mipmap level
978 * @param n_elements Number of elements in array
979 * @param n_mipmap_levels Number of mipmap levels
980 * @param texture_format Texture format
981 * @param texture_width Texture width
982 * @param texture_height Texture height
983 **/
prepareDataForStencilUIntTexture(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)984 void prepareDataForStencilUIntTexture(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
985 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
986 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
987 glw::GLsizei texture_height)
988 {
989 glw::GLubyte component = 0;
990
991 getStencilComponent(cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, component);
992
993 prepareDataForTexture<glw::GLubyte, 1>(gl, cube_face, element_index, mipmap_level, texture_format, texture_type,
994 texture_width, texture_height, &component);
995 }
996
997 /** Prepare texture's face at given index and level, for depth textures.
998 *
999 * @param gl GL functions
1000 * @param cube_face Index of cube map's face
1001 * @param element_index Index of element in array
1002 * @param mipmap_level Mipmap level
1003 * @param n_elements Number of elements in array
1004 * @param n_mipmap_levels Number of mipmap levels
1005 * @param texture_format Texture format
1006 * @param texture_width Texture width
1007 * @param texture_height Texture height
1008 **/
prepareDepthTextureFace(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)1009 void prepareDepthTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
1010 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
1011 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
1012 glw::GLsizei texture_height)
1013 {
1014 switch (texture_type)
1015 {
1016 case GL_FLOAT:
1017 prepareDataForDepthFloatTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
1018 texture_format, texture_type, texture_width, texture_height);
1019 break;
1020
1021 default:
1022 TCU_FAIL("Not implemented case !");
1023 break;
1024 }
1025 }
1026
1027 /** Prepare grad_x vector for given texture_coordinates
1028 *
1029 * @param grad_x Storage for grad_x
1030 * @param face Cube map's face index
1031 * @param texture_coordinates Texture coordinate
1032 * @param width Image width
1033 **/
prepareGradXForFace(glw::GLfloat * grad_x,glw::GLuint face,glw::GLfloat * texture_coordinates,glw::GLuint width)1034 void prepareGradXForFace(glw::GLfloat* grad_x, glw::GLuint face, glw::GLfloat* texture_coordinates, glw::GLuint width)
1035 {
1036 static const glw::GLuint n_points_per_face = 9;
1037 static const glw::GLuint n_texture_coordinates_components = 4;
1038 static const glw::GLuint n_grad_components = 4;
1039
1040 for (glw::GLuint i = 0; i < n_points_per_face; i += 2)
1041 {
1042 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1043 const glw::GLuint grad_offset = i * n_grad_components;
1044
1045 getRightNeighbour(texture_coordinates + texture_coordinates_offset, face, 1, width, grad_x + grad_offset);
1046 }
1047
1048 for (glw::GLuint i = 1; i < n_points_per_face; i += 2)
1049 {
1050 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1051 const glw::GLuint grad_offset = i * n_grad_components;
1052
1053 getRightNeighbour(texture_coordinates + texture_coordinates_offset, face, 4 * width, width,
1054 grad_x + grad_offset);
1055 }
1056
1057 for (glw::GLuint i = 0; i < n_points_per_face; ++i)
1058 {
1059 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1060 const glw::GLuint grad_offset = i * n_grad_components;
1061
1062 vectorSubtractInPlace<3>(grad_x + grad_offset, texture_coordinates + texture_coordinates_offset);
1063 }
1064 }
1065
1066 /** Prepare grad_y vector for given texture_coordinates
1067 *
1068 * @param grad_y Storage for grad_x
1069 * @param face Cube map's face index
1070 * @param texture_coordinates Texture coordinate
1071 * @param width Image width
1072 **/
prepareGradYForFace(glw::GLfloat * grad_y,glw::GLuint face,glw::GLfloat * texture_coordinates,glw::GLuint width)1073 void prepareGradYForFace(glw::GLfloat* grad_y, glw::GLuint face, glw::GLfloat* texture_coordinates, glw::GLuint width)
1074 {
1075 static const glw::GLuint n_points_per_face = 9;
1076 static const glw::GLuint n_texture_coordinates_components = 4;
1077 static const glw::GLuint n_grad_components = 4;
1078
1079 for (glw::GLuint i = 0; i < n_points_per_face; i += 2)
1080 {
1081 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1082 const glw::GLuint grad_offset = i * n_grad_components;
1083
1084 getTopNeighbour(texture_coordinates + texture_coordinates_offset, face, 1, width, grad_y + grad_offset);
1085 }
1086
1087 for (glw::GLuint i = 1; i < n_points_per_face; i += 2)
1088 {
1089 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1090 const glw::GLuint grad_offset = i * n_grad_components;
1091
1092 getTopNeighbour(texture_coordinates + texture_coordinates_offset, face, 4 * width, width, grad_y + grad_offset);
1093 }
1094
1095 for (glw::GLuint i = 0; i < n_points_per_face; ++i)
1096 {
1097 const glw::GLuint texture_coordinates_offset = i * n_texture_coordinates_components;
1098 const glw::GLuint grad_offset = i * n_grad_components;
1099
1100 vectorSubtractInPlace<3>(grad_y + grad_offset, texture_coordinates + texture_coordinates_offset);
1101 }
1102 }
1103
1104 /** Prepare "lods" for face.
1105 * Pattern is: B T B
1106 * T B T
1107 * B T B
1108 * B - base, T - top
1109 *
1110 * @param lods Storage for lods
1111 * @param n_mipmap_levels Number of mipmap levels
1112 **/
prepareLodForFace(glw::GLfloat * lods,glw::GLuint n_mipmap_levels)1113 void prepareLodForFace(glw::GLfloat* lods, glw::GLuint n_mipmap_levels)
1114 {
1115 const glw::GLfloat base_level = 0.0f;
1116 const glw::GLfloat top_level = (glw::GLfloat)(n_mipmap_levels - 1);
1117
1118 lods[0] = base_level;
1119 lods[1] = top_level;
1120 lods[2] = base_level;
1121 lods[3] = top_level;
1122 lods[4] = base_level;
1123 lods[5] = top_level;
1124 lods[6] = base_level;
1125 lods[7] = top_level;
1126 lods[8] = base_level;
1127 }
1128
1129 /** Prepare position for vertices. Each vertex is placed on a unique pixel of output image.
1130 *
1131 * @param positions Storage for positions
1132 * @param cube_face Texture coordinate
1133 * @param element_index Index of element in array
1134 * @param n_layers Image width
1135 **/
preparePositionForFace(glw::GLfloat * positions,glw::GLuint cube_face,glw::GLuint element_index,glw::GLuint n_layers)1136 void preparePositionForFace(glw::GLfloat* positions, glw::GLuint cube_face, glw::GLuint element_index,
1137 glw::GLuint n_layers)
1138 {
1139 static const glw::GLuint x_offset_per_face = 3;
1140 static const glw::GLuint n_faces = 6;
1141
1142 const glw::GLuint x_offset_for_face = (element_index * n_faces + cube_face) * x_offset_per_face;
1143
1144 const glw::GLfloat x_step = 2.0f / ((glw::GLfloat)(n_layers * 3));
1145 const glw::GLfloat x_mid_step = x_step / 2.0f;
1146 const glw::GLfloat y_step = 2.0f / 3.0f;
1147 const glw::GLfloat y_mid_step = y_step / 2.0f;
1148
1149 const glw::GLfloat x_left = -1.0f + x_mid_step + ((glw::GLfloat)x_offset_for_face) * x_step;
1150 const glw::GLfloat x_middle = x_left + x_step;
1151 const glw::GLfloat x_right = x_middle + x_step;
1152
1153 const glw::GLfloat y_top = 1.0f - y_mid_step;
1154 const glw::GLfloat y_middle = y_top - y_step;
1155 const glw::GLfloat y_bottom = y_middle - y_step;
1156
1157 vectorSet4(positions, 0, x_left, y_top, 0.0f, 1.0f);
1158 vectorSet4(positions, 1, x_middle, y_top, 0.0f, 1.0f);
1159 vectorSet4(positions, 2, x_right, y_top, 0.0f, 1.0f);
1160 vectorSet4(positions, 3, x_left, y_middle, 0.0f, 1.0f);
1161 vectorSet4(positions, 4, x_middle, y_middle, 0.0f, 1.0f);
1162 vectorSet4(positions, 5, x_right, y_middle, 0.0f, 1.0f);
1163 vectorSet4(positions, 6, x_left, y_bottom, 0.0f, 1.0f);
1164 vectorSet4(positions, 7, x_middle, y_bottom, 0.0f, 1.0f);
1165 vectorSet4(positions, 8, x_right, y_bottom, 0.0f, 1.0f);
1166 }
1167
1168 /** Prepare "refZ" for face.
1169 * Pattern is: - = +
1170 * - = +
1171 * - = +
1172 * '-' - lower than depth
1173 * = - eqaul to depth
1174 * + - higher thatn depth
1175 *
1176 * @param refZs Storage for refZs
1177 * @param n_mipmaps Number of mipmap levels
1178 * @param face Cube map's face index
1179 * @param layer Index of element in array
1180 * @param n_layers Number of elements in array
1181 **/
prepareRefZForFace(glw::GLfloat * refZs,glw::GLuint n_mipmaps,glw::GLuint face,glw::GLuint layer,glw::GLuint n_layers)1182 void prepareRefZForFace(glw::GLfloat* refZs, glw::GLuint n_mipmaps, glw::GLuint face, glw::GLuint layer,
1183 glw::GLuint n_layers)
1184 {
1185 glw::GLfloat expected_base_depth_value = 0;
1186 glw::GLfloat expected_top_depth_value = 0;
1187
1188 /* Get depth for top and base levles */
1189 getDepthComponent(face, layer, 0, n_layers, n_mipmaps, expected_base_depth_value);
1190 getDepthComponent(face, layer, n_mipmaps - 1, n_layers, n_mipmaps, expected_top_depth_value);
1191
1192 /* Use step of 10% */
1193 const glw::GLfloat base_depth_step = expected_base_depth_value * 0.1f;
1194 const glw::GLfloat top_depth_step = expected_top_depth_value * 0.1f;
1195
1196 /* Top row */
1197 refZs[0] = expected_base_depth_value - base_depth_step;
1198 refZs[1] = expected_top_depth_value;
1199 refZs[2] = expected_base_depth_value + base_depth_step;
1200
1201 /* Center row */
1202 refZs[3] = expected_top_depth_value - top_depth_step;
1203 refZs[4] = expected_base_depth_value;
1204 refZs[5] = expected_top_depth_value + top_depth_step;
1205
1206 /* Bottom row */
1207 refZs[6] = expected_base_depth_value - base_depth_step;
1208 refZs[7] = expected_top_depth_value;
1209 refZs[8] = expected_base_depth_value + base_depth_step;
1210 }
1211
1212 /** Prepare texture's face at given index and level, for rgba integer textures.
1213 *
1214 * @param gl GL functions
1215 * @param cube_face Index of cube map's face
1216 * @param element_index Index of element in array
1217 * @param mipmap_level Mipmap level
1218 * @param n_elements Number of elements in array
1219 * @param n_mipmap_levels Number of mipmap levels
1220 * @param texture_format Texture format
1221 * @param texture_width Texture width
1222 * @param texture_height Texture height
1223 **/
prepareRGBAIntegerTextureFace(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)1224 void prepareRGBAIntegerTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
1225 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
1226 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
1227 glw::GLsizei texture_height)
1228 {
1229 switch (texture_type)
1230 {
1231 case GL_UNSIGNED_INT:
1232 prepareDataForColorIntTexture<glw::GLuint>(gl, cube_face, element_index, mipmap_level, n_elements,
1233 n_mipmap_levels, texture_format, texture_type, texture_width,
1234 texture_height);
1235 break;
1236
1237 case GL_INT:
1238 prepareDataForColorIntTexture<glw::GLint>(gl, cube_face, element_index, mipmap_level, n_elements,
1239 n_mipmap_levels, texture_format, texture_type, texture_width,
1240 texture_height);
1241 break;
1242
1243 default:
1244 TCU_FAIL("Not implemented case !");
1245 break;
1246 }
1247 }
1248
1249 /** Prepare texture's face at given index and level, for rgba textures.
1250 *
1251 * @param gl GL functions
1252 * @param cube_face Index of cube map's face
1253 * @param element_index Index of element in array
1254 * @param mipmap_level Mipmap level
1255 * @param n_elements Number of elements in array
1256 * @param n_mipmap_levels Number of mipmap levels
1257 * @param texture_format Texture format
1258 * @param texture_width Texture width
1259 * @param texture_height Texture height
1260 **/
prepareRGBATextureFace(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)1261 void prepareRGBATextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
1262 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
1263 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
1264 glw::GLsizei texture_height)
1265 {
1266 switch (texture_type)
1267 {
1268 case GL_UNSIGNED_BYTE:
1269 prepareDataForColorIntTexture<glw::GLubyte>(gl, cube_face, element_index, mipmap_level, n_elements,
1270 n_mipmap_levels, texture_format, texture_type, texture_width,
1271 texture_height);
1272 break;
1273
1274 case GL_FLOAT:
1275 prepareDataForColorFloatTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
1276 texture_format, texture_type, texture_width, texture_height);
1277 break;
1278
1279 default:
1280 TCU_FAIL("Not implemented case !");
1281 break;
1282 }
1283 }
1284
1285 /** Prepare texture's face at given index and level, for stencil textures.
1286 *
1287 * @param gl GL functions
1288 * @param cube_face Index of cube map's face
1289 * @param element_index Index of element in array
1290 * @param mipmap_level Mipmap level
1291 * @param n_elements Number of elements in array
1292 * @param n_mipmap_levels Number of mipmap levels
1293 * @param texture_format Texture format
1294 * @param texture_width Texture width
1295 * @param texture_height Texture height
1296 **/
prepareStencilTextureFace(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)1297 void prepareStencilTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
1298 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
1299 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
1300 glw::GLsizei texture_height)
1301 {
1302 switch (texture_type)
1303 {
1304 case GL_UNSIGNED_BYTE:
1305 prepareDataForStencilUIntTexture(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
1306 texture_format, texture_type, texture_width, texture_height);
1307 break;
1308
1309 default:
1310 TCU_FAIL("Not implemented case !");
1311 break;
1312 }
1313 }
1314
1315 /** Prepare texture coordinates for vertices.
1316 * Each vertex has unique value. 4 corners, centers of 4 edges and central points are selected.
1317 *
1318 * @param positions Storage for positions
1319 * @param cube_face Texture coordinate
1320 * @param element_index Index of element in array
1321 * @param n_layers Image width
1322 **/
prepareTextureCoordinatesForFace(glw::GLfloat * data,glw::GLuint width,glw::GLuint height,glw::GLfloat layer,glw::GLuint face)1323 void prepareTextureCoordinatesForFace(glw::GLfloat* data, glw::GLuint width, glw::GLuint height, glw::GLfloat layer,
1324 glw::GLuint face)
1325 {
1326 const glw::GLfloat x_range = (glw::GLfloat)width;
1327 const glw::GLfloat y_range = (glw::GLfloat)height;
1328
1329 const glw::GLfloat x_step = 2.0f / x_range;
1330 const glw::GLfloat y_step = 2.0f / y_range;
1331
1332 const glw::GLfloat x_mid_step = x_step / 2.0f;
1333 const glw::GLfloat y_mid_step = y_step / 2.0f;
1334
1335 const glw::GLfloat left = -1.0f + x_mid_step;
1336 const glw::GLfloat right = 1.0f - x_mid_step;
1337 const glw::GLfloat top = 1.0f - y_mid_step;
1338 const glw::GLfloat bottom = -1.0f + y_mid_step;
1339 const glw::GLfloat middle = 0.0f;
1340 const glw::GLfloat negative = -1.0f;
1341 const glw::GLfloat positive = 1.0f;
1342
1343 switch (face)
1344 {
1345 case 0:
1346 vectorSet4(data, 0, positive, left, top, layer);
1347 vectorSet4(data, 1, positive, middle, top, layer);
1348 vectorSet4(data, 2, positive, right, top, layer);
1349 vectorSet4(data, 3, positive, left, middle, layer);
1350 vectorSet4(data, 4, positive, middle, middle, layer);
1351 vectorSet4(data, 5, positive, right, middle, layer);
1352 vectorSet4(data, 6, positive, left, bottom, layer);
1353 vectorSet4(data, 7, positive, middle, bottom, layer);
1354 vectorSet4(data, 8, positive, right, bottom, layer);
1355 break;
1356 case 1:
1357 vectorSet4(data, 0, negative, left, top, layer);
1358 vectorSet4(data, 1, negative, middle, top, layer);
1359 vectorSet4(data, 2, negative, right, top, layer);
1360 vectorSet4(data, 3, negative, left, middle, layer);
1361 vectorSet4(data, 4, negative, middle, middle, layer);
1362 vectorSet4(data, 5, negative, right, middle, layer);
1363 vectorSet4(data, 6, negative, left, bottom, layer);
1364 vectorSet4(data, 7, negative, middle, bottom, layer);
1365 vectorSet4(data, 8, negative, right, bottom, layer);
1366 break;
1367 case 2:
1368 vectorSet4(data, 0, left, positive, top, layer);
1369 vectorSet4(data, 1, middle, positive, top, layer);
1370 vectorSet4(data, 2, right, positive, top, layer);
1371 vectorSet4(data, 3, left, positive, middle, layer);
1372 vectorSet4(data, 4, middle, positive, middle, layer);
1373 vectorSet4(data, 5, right, positive, middle, layer);
1374 vectorSet4(data, 6, left, positive, bottom, layer);
1375 vectorSet4(data, 7, middle, positive, bottom, layer);
1376 vectorSet4(data, 8, right, positive, bottom, layer);
1377 break;
1378 case 3:
1379 vectorSet4(data, 0, left, negative, top, layer);
1380 vectorSet4(data, 1, middle, negative, top, layer);
1381 vectorSet4(data, 2, right, negative, top, layer);
1382 vectorSet4(data, 3, left, negative, middle, layer);
1383 vectorSet4(data, 4, middle, negative, middle, layer);
1384 vectorSet4(data, 5, right, negative, middle, layer);
1385 vectorSet4(data, 6, left, negative, bottom, layer);
1386 vectorSet4(data, 7, middle, negative, bottom, layer);
1387 vectorSet4(data, 8, right, negative, bottom, layer);
1388 break;
1389 case 4:
1390 vectorSet4(data, 0, left, top, positive, layer);
1391 vectorSet4(data, 1, middle, top, positive, layer);
1392 vectorSet4(data, 2, right, top, positive, layer);
1393 vectorSet4(data, 3, left, middle, positive, layer);
1394 vectorSet4(data, 4, middle, middle, positive, layer);
1395 vectorSet4(data, 5, right, middle, positive, layer);
1396 vectorSet4(data, 6, left, bottom, positive, layer);
1397 vectorSet4(data, 7, middle, bottom, positive, layer);
1398 vectorSet4(data, 8, right, bottom, positive, layer);
1399 break;
1400 case 5:
1401 vectorSet4(data, 0, left, top, negative, layer);
1402 vectorSet4(data, 1, middle, top, negative, layer);
1403 vectorSet4(data, 2, right, top, negative, layer);
1404 vectorSet4(data, 3, left, middle, negative, layer);
1405 vectorSet4(data, 4, middle, middle, negative, layer);
1406 vectorSet4(data, 5, right, middle, negative, layer);
1407 vectorSet4(data, 6, left, bottom, negative, layer);
1408 vectorSet4(data, 7, middle, bottom, negative, layer);
1409 vectorSet4(data, 8, right, bottom, negative, layer);
1410 break;
1411 };
1412
1413 vectorNormalize<3, 4>(data, 0);
1414 vectorNormalize<3, 4>(data, 1);
1415 vectorNormalize<3, 4>(data, 2);
1416 vectorNormalize<3, 4>(data, 3);
1417 vectorNormalize<3, 4>(data, 4);
1418 vectorNormalize<3, 4>(data, 5);
1419 vectorNormalize<3, 4>(data, 6);
1420 vectorNormalize<3, 4>(data, 7);
1421 vectorNormalize<3, 4>(data, 8);
1422 }
1423
1424 /** Prepare texture coordinates for vertices. For sampling with textureGather routine.
1425 * Each vertex has unique value. 4 corners, centers of 4 edges and central points are selected.
1426 *
1427 * @param positions Storage for positions
1428 * @param cube_face Texture coordinate
1429 * @param element_index Index of element in array
1430 * @param n_layers Image width
1431 **/
prepareTextureCoordinatesForGatherForFace(glw::GLfloat * data,glw::GLuint width,glw::GLuint height,glw::GLfloat layer,glw::GLuint face)1432 void prepareTextureCoordinatesForGatherForFace(glw::GLfloat* data, glw::GLuint width, glw::GLuint height,
1433 glw::GLfloat layer, glw::GLuint face)
1434 {
1435 const glw::GLfloat x_range = (glw::GLfloat)width;
1436 const glw::GLfloat y_range = (glw::GLfloat)height;
1437
1438 const glw::GLfloat x_step = 2.0f / x_range;
1439 const glw::GLfloat y_step = 2.0f / y_range;
1440
1441 const glw::GLfloat x_mid_step = x_step / 2.0f;
1442 const glw::GLfloat y_mid_step = y_step / 2.0f;
1443
1444 const glw::GLfloat left = -1.0f + x_mid_step + x_step;
1445 const glw::GLfloat right = 1.0f - x_mid_step - x_step;
1446 const glw::GLfloat top = 1.0f - y_mid_step - y_step;
1447 const glw::GLfloat bottom = -1.0f + y_mid_step + y_step;
1448 const glw::GLfloat middle = 0.0f;
1449 const glw::GLfloat negative = -1.0f;
1450 const glw::GLfloat positive = 1.0f;
1451
1452 switch (face)
1453 {
1454 case 0:
1455 vectorSet4(data, 0, positive, left, top, layer);
1456 vectorSet4(data, 1, positive, middle, top, layer);
1457 vectorSet4(data, 2, positive, right, top, layer);
1458 vectorSet4(data, 3, positive, left, middle, layer);
1459 vectorSet4(data, 4, positive, middle, middle, layer);
1460 vectorSet4(data, 5, positive, right, middle, layer);
1461 vectorSet4(data, 6, positive, left, bottom, layer);
1462 vectorSet4(data, 7, positive, middle, bottom, layer);
1463 vectorSet4(data, 8, positive, right, bottom, layer);
1464 break;
1465 case 1:
1466 vectorSet4(data, 0, negative, left, top, layer);
1467 vectorSet4(data, 1, negative, middle, top, layer);
1468 vectorSet4(data, 2, negative, right, top, layer);
1469 vectorSet4(data, 3, negative, left, middle, layer);
1470 vectorSet4(data, 4, negative, middle, middle, layer);
1471 vectorSet4(data, 5, negative, right, middle, layer);
1472 vectorSet4(data, 6, negative, left, bottom, layer);
1473 vectorSet4(data, 7, negative, middle, bottom, layer);
1474 vectorSet4(data, 8, negative, right, bottom, layer);
1475 break;
1476 case 2:
1477 vectorSet4(data, 0, left, positive, top, layer);
1478 vectorSet4(data, 1, middle, positive, top, layer);
1479 vectorSet4(data, 2, right, positive, top, layer);
1480 vectorSet4(data, 3, left, positive, middle, layer);
1481 vectorSet4(data, 4, middle, positive, middle, layer);
1482 vectorSet4(data, 5, right, positive, middle, layer);
1483 vectorSet4(data, 6, left, positive, bottom, layer);
1484 vectorSet4(data, 7, middle, positive, bottom, layer);
1485 vectorSet4(data, 8, right, positive, bottom, layer);
1486 break;
1487 case 3:
1488 vectorSet4(data, 0, left, negative, top, layer);
1489 vectorSet4(data, 1, middle, negative, top, layer);
1490 vectorSet4(data, 2, right, negative, top, layer);
1491 vectorSet4(data, 3, left, negative, middle, layer);
1492 vectorSet4(data, 4, middle, negative, middle, layer);
1493 vectorSet4(data, 5, right, negative, middle, layer);
1494 vectorSet4(data, 6, left, negative, bottom, layer);
1495 vectorSet4(data, 7, middle, negative, bottom, layer);
1496 vectorSet4(data, 8, right, negative, bottom, layer);
1497 break;
1498 case 4:
1499 vectorSet4(data, 0, left, top, positive, layer);
1500 vectorSet4(data, 1, middle, top, positive, layer);
1501 vectorSet4(data, 2, right, top, positive, layer);
1502 vectorSet4(data, 3, left, middle, positive, layer);
1503 vectorSet4(data, 4, middle, middle, positive, layer);
1504 vectorSet4(data, 5, right, middle, positive, layer);
1505 vectorSet4(data, 6, left, bottom, positive, layer);
1506 vectorSet4(data, 7, middle, bottom, positive, layer);
1507 vectorSet4(data, 8, right, bottom, positive, layer);
1508 break;
1509 case 5:
1510 vectorSet4(data, 0, left, top, negative, layer);
1511 vectorSet4(data, 1, middle, top, negative, layer);
1512 vectorSet4(data, 2, right, top, negative, layer);
1513 vectorSet4(data, 3, left, middle, negative, layer);
1514 vectorSet4(data, 4, middle, middle, negative, layer);
1515 vectorSet4(data, 5, right, middle, negative, layer);
1516 vectorSet4(data, 6, left, bottom, negative, layer);
1517 vectorSet4(data, 7, middle, bottom, negative, layer);
1518 vectorSet4(data, 8, right, bottom, negative, layer);
1519 break;
1520 };
1521
1522 vectorNormalize<3, 4>(data, 0);
1523 vectorNormalize<3, 4>(data, 1);
1524 vectorNormalize<3, 4>(data, 2);
1525 vectorNormalize<3, 4>(data, 3);
1526 vectorNormalize<3, 4>(data, 4);
1527 vectorNormalize<3, 4>(data, 5);
1528 vectorNormalize<3, 4>(data, 6);
1529 vectorNormalize<3, 4>(data, 7);
1530 vectorNormalize<3, 4>(data, 8);
1531 }
1532
1533 /** Prepare texture's face at given index and level.
1534 *
1535 * @param gl GL functions
1536 * @param cube_face Index of cube map's face
1537 * @param element_index Index of element in array
1538 * @param mipmap_level Mipmap level
1539 * @param n_elements Number of elements in array
1540 * @param n_mipmap_levels Number of mipmap levels
1541 * @param texture_format Texture format
1542 * @param texture_width Texture width
1543 * @param texture_height Texture height
1544 **/
prepareTextureFace(const glw::Functions & gl,glw::GLint cube_face,glw::GLint element_index,glw::GLint mipmap_level,glw::GLint n_elements,glw::GLint n_mipmap_levels,glw::GLenum texture_format,glw::GLenum texture_type,glw::GLsizei texture_width,glw::GLsizei texture_height)1545 void prepareTextureFace(const glw::Functions& gl, glw::GLint cube_face, glw::GLint element_index,
1546 glw::GLint mipmap_level, glw::GLint n_elements, glw::GLint n_mipmap_levels,
1547 glw::GLenum texture_format, glw::GLenum texture_type, glw::GLsizei texture_width,
1548 glw::GLsizei texture_height)
1549 {
1550 switch (texture_format)
1551 {
1552 case GL_RGBA:
1553 prepareRGBATextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, texture_format,
1554 texture_type, texture_width, texture_height);
1555 break;
1556
1557 case GL_RGBA_INTEGER:
1558 prepareRGBAIntegerTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
1559 texture_format, texture_type, texture_width, texture_height);
1560 break;
1561
1562 case GL_DEPTH_COMPONENT:
1563 prepareDepthTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels, texture_format,
1564 texture_type, texture_width, texture_height);
1565 break;
1566
1567 case GL_STENCIL_INDEX:
1568 prepareStencilTextureFace(gl, cube_face, element_index, mipmap_level, n_elements, n_mipmap_levels,
1569 texture_format, texture_type, texture_width, texture_height);
1570 break;
1571
1572 default:
1573 TCU_FAIL("Not implemented case !");
1574 break;
1575 }
1576 }
1577
1578 /** Verifies that all pixels rendered for specific face match expectations
1579 *
1580 * @tparam T Type of image component
1581 * @tparam N_Components Number of image components
1582 * @tparam Width Width of single face
1583 * @tparam Height Height of single face
1584 *
1585 * @param data Rendered data
1586 * @param cube_face Index of face in array
1587 * @param expected_values Expected values
1588 * @param image_width Widht of whole image
1589 **/
1590 template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
verifyFace(const T * data,const glw::GLuint cube_face,const T * expected_values,const glw::GLuint image_width)1591 bool verifyFace(const T* data, const glw::GLuint cube_face, const T* expected_values, const glw::GLuint image_width)
1592 {
1593 static const glw::GLuint size_of_pixel = N_Components;
1594
1595 const glw::GLuint data_face_offset = N_Components * Width * cube_face;
1596 const glw::GLuint exp_face_offset = N_Components * Width * Height * cube_face;
1597 const glw::GLuint data_size_of_line = image_width * size_of_pixel;
1598 const glw::GLuint exp_size_of_line = Width * size_of_pixel;
1599
1600 for (glw::GLuint y = 0; y < Height; ++y)
1601 {
1602 const glw::GLuint data_line_offset = y * data_size_of_line;
1603 const glw::GLuint exp_line_offset = y * exp_size_of_line;
1604
1605 for (glw::GLuint x = 0; x < Width; ++x)
1606 {
1607 const glw::GLuint data_pixel_offset = data_line_offset + data_face_offset + x * size_of_pixel;
1608 const glw::GLuint exp_pixel_offset = exp_line_offset + exp_face_offset + x * size_of_pixel;
1609
1610 for (glw::GLuint component = 0; component < N_Components; ++component)
1611 {
1612 if (data[data_pixel_offset + component] != expected_values[exp_pixel_offset + component])
1613 {
1614 return false;
1615 }
1616 }
1617 }
1618 }
1619
1620 return true;
1621 }
1622
1623 /** Verifies that all rendered pixels match expectation
1624 *
1625 * @tparam T Type of image component
1626 * @tparam N_Components Number of image components
1627 * @tparam Width Width of single face
1628 * @tparam Height Height of single face
1629 *
1630 * @param data Rendered data
1631 * @param expected_values Expected values
1632 * @param n_layers Number of elements in array
1633 **/
1634 template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
verifyImage(const T * data,const T * expected_values,const glw::GLuint n_layers)1635 bool verifyImage(const T* data, const T* expected_values, const glw::GLuint n_layers)
1636 {
1637 static const glw::GLuint n_faces = 6;
1638
1639 const glw::GLuint n_total_faces = n_layers * n_faces;
1640
1641 for (glw::GLuint face = 0; face < n_total_faces; ++face)
1642 {
1643 if (false == verifyFace<T, N_Components, Width, Height>(data, face, expected_values, n_total_faces * Width))
1644 {
1645 return false;
1646 }
1647 }
1648
1649 return true;
1650 }
1651
1652 /** Verifies that all rendered pixels match expectation
1653 *
1654 * @tparam T Type of image component
1655 * @tparam N_Components Number of image components
1656 * @tparam Width Width of single face
1657 * @tparam Height Height of single face
1658 *
1659 * @param n_mipmap_levels Number of mipmap levels
1660 * @param n_layers Number of elements in array
1661 * @param getComponents Routine which is used to obtain components
1662 * @param data Rendered data
1663 **/
1664 template <typename T, unsigned int N_Components, unsigned int Width, unsigned int Height>
verifyResultImage(glw::GLuint n_mipmap_levels,glw::GLuint n_layers,void (* getComponents)(glw::GLuint pixel_index,glw::GLint cube_face,glw::GLint layer_index,glw::GLint n_layers,glw::GLint n_mipmap_levels,T * out_components),const glw::GLubyte * data)1665 bool verifyResultImage(glw::GLuint n_mipmap_levels, glw::GLuint n_layers,
1666 void (*getComponents)(glw::GLuint pixel_index, glw::GLint cube_face, glw::GLint layer_index,
1667 glw::GLint n_layers, glw::GLint n_mipmap_levels, T* out_components),
1668 const glw::GLubyte* data)
1669 {
1670 const glw::GLuint n_components = N_Components;
1671 const glw::GLuint face_width = Width;
1672 const glw::GLuint face_height = Height;
1673 const glw::GLuint n_pixels_per_face = face_width * face_height;
1674 const glw::GLuint n_components_per_face = n_pixels_per_face * n_components;
1675 const glw::GLuint n_faces = 6;
1676 const glw::GLuint n_total_faces = n_layers * n_faces;
1677 const glw::GLuint n_total_components = n_total_faces * n_components_per_face;
1678 const T* result_image = (const T*)data;
1679
1680 std::vector<T> expected_values;
1681 expected_values.resize(n_total_components);
1682
1683 for (glw::GLuint layer = 0; layer < n_layers; ++layer)
1684 {
1685 const glw::GLuint layer_offset = layer * n_faces * n_components_per_face;
1686
1687 for (glw::GLuint face = 0; face < n_faces; ++face)
1688 {
1689 const glw::GLuint face_offset = face * n_components_per_face + layer_offset;
1690
1691 for (glw::GLuint pixel = 0; pixel < n_pixels_per_face; ++pixel)
1692 {
1693 const glw::GLuint pixel_offset = pixel * n_components + face_offset;
1694
1695 T components[n_components];
1696
1697 getComponents(pixel, face, layer, n_layers, n_mipmap_levels, components);
1698
1699 for (glw::GLuint component = 0; component < n_components; ++component)
1700 {
1701 const glw::GLuint component_offset = pixel_offset + component;
1702
1703 expected_values[component_offset] = components[component];
1704 }
1705 }
1706 }
1707 }
1708
1709 return verifyImage<T, N_Components, Width, Height>(result_image, &expected_values[0], n_layers);
1710 }
1711
1712 /** Constructor
1713 *
1714 * @param context Test context
1715 * @param name Test case's name
1716 * @param description Test case's desricption
1717 **/
TextureCubeMapArraySamplingTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)1718 TextureCubeMapArraySamplingTest::TextureCubeMapArraySamplingTest(Context& context, const ExtParameters& extParams,
1719 const char* name, const char* description)
1720 : TestCaseBase(context, extParams, name, description)
1721 , m_framebuffer_object_id(0)
1722 , compiled_shaders(0)
1723 , invalid_shaders(0)
1724 , linked_programs(0)
1725 , invalid_programs(0)
1726 , tested_cases(0)
1727 , failed_cases(0)
1728 , invalid_type_cases(0)
1729 {
1730 /* Prepare formats set */
1731 m_formats.push_back(formatDefinition(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false, Float, "GL_RGBA8"));
1732 m_formats.push_back(formatDefinition(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, false, Int, "GL_RGBA32I"));
1733 m_formats.push_back(formatDefinition(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, false, UInt, "GL_RGBA32UI"));
1734
1735 m_formats.push_back(formatDefinition(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, false, GL_RGBA8, GL_RGBA,
1736 GL_UNSIGNED_BYTE, Depth, "GL_DEPTH_COMPONENT32F"));
1737 m_formats.push_back(formatDefinition(GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, false, GL_R32UI,
1738 GL_RGBA_INTEGER, GL_UNSIGNED_INT, Stencil, "GL_STENCIL_INDEX8"));
1739
1740 /* Prepare sampling functions set */
1741 m_functions.push_back(samplingFunctionDefinition(Texture, "Texture"));
1742 m_functions.push_back(samplingFunctionDefinition(TextureLod, "TextureLod"));
1743 m_functions.push_back(samplingFunctionDefinition(TextureGrad, "TextureGrad"));
1744 m_functions.push_back(samplingFunctionDefinition(TextureGather, "TextureGather"));
1745
1746 /* Prepare mutabilities set */
1747 m_mutabilities.push_back(true);
1748 m_mutabilities.push_back(false);
1749
1750 /* Prepare resolutions set */
1751 m_resolutions.push_back(resolutionDefinition(64, 64, 18));
1752 m_resolutions.push_back(resolutionDefinition(117, 117, 6));
1753 m_resolutions.push_back(resolutionDefinition(256, 256, 6));
1754 m_resolutions.push_back(resolutionDefinition(173, 173, 12));
1755
1756 /* Prepare resolutions set for compressed formats */
1757 m_compressed_resolutions.push_back(resolutionDefinition(8, 8, 12));
1758 m_compressed_resolutions.push_back(resolutionDefinition(13, 13, 12));
1759 }
1760
1761 /** Check if getActiveUniform and glGetProgramResourceiv returns correct type for cube array samplers.
1762 *
1763 * @param program_id Program id
1764 * @param sampler_name_p Name of sampler
1765 * @param sampler_type Expected type of sampler
1766 *
1767 * @return Status. 1st LSB - glGetActiveUniform, second LSB glGetProgramResourceiv, 0 valid, 1 invalid.
1768 **/
checkUniformAndResourceApi(glw::GLuint program_id,const glw::GLchar * sampler_name_p,samplerType sampler_type)1769 glw::GLuint TextureCubeMapArraySamplingTest::checkUniformAndResourceApi(glw::GLuint program_id,
1770 const glw::GLchar* sampler_name_p,
1771 samplerType sampler_type)
1772 {
1773 /* GL functions */
1774 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1775
1776 glw::GLenum expected_type = 0;
1777 glw::GLuint index_getActiveUniform = GL_INVALID_INDEX;
1778 glw::GLuint index_getProgramResourceiv = GL_INVALID_INDEX;
1779 glw::GLenum props = GL_TYPE;
1780 glw::GLuint result = 0;
1781 glw::GLchar* name = 0;
1782 glw::GLint size = 0;
1783 glw::GLenum type_getActiveUniform = 0;
1784 glw::GLint type_getProgramResourceiv = 0;
1785
1786 // Get type by getActiveUniform
1787 gl.getUniformIndices(program_id, 1, &sampler_name_p, &index_getActiveUniform);
1788
1789 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformIndices");
1790
1791 if (GL_INVALID_INDEX == index_getActiveUniform)
1792 {
1793 throw tcu::InternalError("glGetUniformIndices: GL_INVALID_INDEX", "", __FILE__, __LINE__);
1794 }
1795
1796 gl.getActiveUniform(program_id, index_getActiveUniform, 0, 0, &size, &type_getActiveUniform, name);
1797 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetActiveUniform");
1798
1799 // Get type by gl.getProgramResourceiv
1800 index_getProgramResourceiv = gl.getProgramResourceIndex(program_id, GL_UNIFORM, sampler_name_p);
1801
1802 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex");
1803
1804 if (GL_INVALID_INDEX == index_getProgramResourceiv)
1805 {
1806 throw tcu::InternalError("glGetProgramResourceIndex: GL_INVALID_INDEX", "", __FILE__, __LINE__);
1807 }
1808
1809 gl.getProgramResourceiv(program_id, GL_UNIFORM, index_getProgramResourceiv, 1, &props, 1, 0,
1810 &type_getProgramResourceiv);
1811 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv");
1812
1813 // Verification
1814 switch (sampler_type)
1815 {
1816 case Float:
1817 expected_type = GL_SAMPLER_CUBE_MAP_ARRAY;
1818 break;
1819 case Int:
1820 expected_type = GL_INT_SAMPLER_CUBE_MAP_ARRAY;
1821 break;
1822 case UInt:
1823 expected_type = GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
1824 break;
1825 case Depth:
1826 expected_type = GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
1827 break;
1828 case Stencil:
1829 expected_type = GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
1830 break;
1831 }
1832
1833 if (expected_type != type_getActiveUniform)
1834 {
1835 result |= m_get_type_api_status_uniform;
1836 }
1837 if (expected_type != (glw::GLuint)type_getProgramResourceiv)
1838 {
1839 result |= m_get_type_api_status_program_resource;
1840 }
1841
1842 return result;
1843 }
1844
1845 /** Compile shader
1846 *
1847 * @param info Shader info
1848 **/
compile(shaderDefinition & info)1849 void TextureCubeMapArraySamplingTest::compile(shaderDefinition& info)
1850 {
1851 compiled_shaders += 1;
1852
1853 if (false == info.compile())
1854 {
1855 invalid_shaders += 1;
1856
1857 logCompilationLog(info);
1858 }
1859 }
1860
1861 /** Execute compute shader
1862 *
1863 * @param program_id Program id
1864 * @param width Width of result image
1865 * @param height Height of result image
1866 **/
dispatch(glw::GLuint program_id,glw::GLuint width,glw::GLuint height)1867 void TextureCubeMapArraySamplingTest::dispatch(glw::GLuint program_id, glw::GLuint width, glw::GLuint height)
1868 {
1869 (void)program_id;
1870
1871 /* GL functions */
1872 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1873
1874 gl.dispatchCompute(width, height, 1);
1875 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glDispatchCompute call.");
1876 }
1877
1878 /** Execute render call
1879 *
1880 * @param program_id Program id
1881 * @param primitive_type Type of primitive
1882 * @param n_vertices Number of vertices
1883 **/
draw(glw::GLuint program_id,glw::GLenum primitive_type,glw::GLuint n_vertices,glw::GLenum format)1884 void TextureCubeMapArraySamplingTest::draw(glw::GLuint program_id, glw::GLenum primitive_type, glw::GLuint n_vertices,
1885 glw::GLenum format)
1886 {
1887 (void)program_id;
1888
1889 /* GL functions */
1890 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1891
1892 const glw::GLenum framebuffer_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1893 if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status)
1894 {
1895 throw tcu::InternalError("Framebuffer is incomplete", "", __FILE__, __LINE__);
1896 }
1897
1898 switch (format)
1899 {
1900 case GL_RGBA32I:
1901 {
1902 const glw::GLint clearValue[4] = { 255, 255, 255, 255 };
1903 gl.clearBufferiv(GL_COLOR, 0, clearValue);
1904 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearBufferiv call.");
1905 }
1906 break;
1907 case GL_RGBA32UI:
1908 case GL_R32UI:
1909 {
1910 const glw::GLuint clearValue[4] = { 255, 255, 255, 255 };
1911 gl.clearBufferuiv(GL_COLOR, 0, clearValue);
1912 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearBufferuiv call.");
1913 }
1914 break;
1915 case GL_DEPTH_COMPONENT32F:
1916 gl.clearDepthf(1.0f);
1917 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearDepthf call.");
1918 break;
1919 case GL_STENCIL_INDEX8:
1920 gl.clearStencil(1);
1921 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearStencil call.");
1922 break;
1923
1924 default:
1925 gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f);
1926 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClearColor call.");
1927
1928 gl.clear(GL_COLOR_BUFFER_BIT);
1929 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glClear call.");
1930 }
1931
1932 gl.drawArrays(primitive_type, 0, n_vertices);
1933 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glDrawArrays call.");
1934 }
1935
1936 /** Get attributes specific for type of sampler
1937 *
1938 * @param sampler_type Type of sampler
1939 * @param out_attribute_definitions Array of attributes
1940 * @param out_n_attributes Number of attributes
1941 **/
getAttributes(samplerType sampler_type,const attributeDefinition * & out_attribute_definitions,glw::GLuint & out_n_attributes)1942 void TextureCubeMapArraySamplingTest::getAttributes(samplerType sampler_type,
1943 const attributeDefinition*& out_attribute_definitions,
1944 glw::GLuint& out_n_attributes)
1945 {
1946 static attributeDefinition depth_attributes[] = { { attribute_refZ, type_float, RefZ, 1 } };
1947
1948 static const glw::GLuint n_depth_attributes = sizeof(depth_attributes) / sizeof(depth_attributes[0]);
1949
1950 switch (sampler_type)
1951 {
1952 case Depth:
1953 out_attribute_definitions = depth_attributes;
1954 out_n_attributes = n_depth_attributes;
1955 break;
1956 default:
1957 out_attribute_definitions = 0;
1958 out_n_attributes = 0;
1959 break;
1960 };
1961 }
1962
1963 /** Get attributes specific for sampling function
1964 *
1965 * @param sampling_function Sampling function
1966 * @param out_attribute_definitions Array of attributes
1967 * @param out_n_attributes Number of attributes
1968 **/
getAttributes(samplingFunction sampling_function,const attributeDefinition * & out_attribute_definitions,glw::GLuint & out_n_attributes)1969 void TextureCubeMapArraySamplingTest::getAttributes(samplingFunction sampling_function,
1970 const attributeDefinition*& out_attribute_definitions,
1971 glw::GLuint& out_n_attributes)
1972 {
1973 static attributeDefinition texture_attributes[] = { { attribute_texture_coordinate, type_vec4, TextureCoordinates,
1974 0 } };
1975
1976 static attributeDefinition textureLod_attributes[] = {
1977 { attribute_texture_coordinate, type_vec4, TextureCoordinates, 0 }, { attribute_lod, type_float, Lod, 1 }
1978 };
1979
1980 static attributeDefinition textureGrad_attributes[] = { { attribute_texture_coordinate, type_vec4,
1981 TextureCoordinates, 0 },
1982 { attribute_grad_x, type_vec3, GradX, 1 },
1983 { attribute_grad_y, type_vec3, GradY, 2 } };
1984
1985 static attributeDefinition textureGather_attributes[] = { { attribute_texture_coordinate, type_vec4,
1986 TextureCoordinatesForGather, 0 } };
1987
1988 static const glw::GLuint n_texture_attributes = sizeof(texture_attributes) / sizeof(texture_attributes[0]);
1989 static const glw::GLuint n_textureLod_attributes = sizeof(textureLod_attributes) / sizeof(textureLod_attributes[0]);
1990 static const glw::GLuint n_textureGrad_attributes =
1991 sizeof(textureGrad_attributes) / sizeof(textureGrad_attributes[0]);
1992 static const glw::GLuint n_textureGather_attributes =
1993 sizeof(textureGather_attributes) / sizeof(textureGather_attributes[0]);
1994
1995 switch (sampling_function)
1996 {
1997 case Texture:
1998 out_attribute_definitions = texture_attributes;
1999 out_n_attributes = n_texture_attributes;
2000 break;
2001 case TextureLod:
2002 out_attribute_definitions = textureLod_attributes;
2003 out_n_attributes = n_textureLod_attributes;
2004 break;
2005 case TextureGrad:
2006 out_attribute_definitions = textureGrad_attributes;
2007 out_n_attributes = n_textureGrad_attributes;
2008 break;
2009 case TextureGather:
2010 out_attribute_definitions = textureGather_attributes;
2011 out_n_attributes = n_textureGather_attributes;
2012 break;
2013 };
2014 }
2015
2016 /** Get information about color type for type of sampler
2017 *
2018 * @param sampler_type Type of sampler
2019 * @param out_color_type Type used for color storage
2020 * @param out_interpolation_type Type of interpolation
2021 * @param out_sampler_type Type of sampler
2022 * @param out_n_components Number of components in color
2023 * @param out_is_shadow If shadow sampler
2024 **/
getColorType(samplerType sampler_type,const glw::GLchar * & out_color_type,const glw::GLchar * & out_interpolation_type,const glw::GLchar * & out_sampler_type,glw::GLuint & out_n_components,bool & out_is_shadow)2025 void TextureCubeMapArraySamplingTest::getColorType(samplerType sampler_type, const glw::GLchar*& out_color_type,
2026 const glw::GLchar*& out_interpolation_type,
2027 const glw::GLchar*& out_sampler_type, glw::GLuint& out_n_components,
2028 bool& out_is_shadow)
2029 {
2030 switch (sampler_type)
2031 {
2032 case Float:
2033 out_color_type = type_vec4;
2034 out_interpolation_type = "";
2035 out_sampler_type = sampler_float;
2036 out_n_components = 4;
2037 out_is_shadow = false;
2038 break;
2039 case Int:
2040 out_color_type = type_ivec4;
2041 out_interpolation_type = interpolation_flat;
2042 out_sampler_type = sampler_int;
2043 out_n_components = 4;
2044 out_is_shadow = false;
2045 break;
2046 case UInt:
2047 out_color_type = type_uvec4;
2048 out_interpolation_type = interpolation_flat;
2049 out_sampler_type = sampler_uint;
2050 out_n_components = 4;
2051 out_is_shadow = false;
2052 break;
2053 case Depth:
2054 out_color_type = type_float;
2055 out_interpolation_type = "";
2056 out_sampler_type = sampler_depth;
2057 out_n_components = 1;
2058 out_is_shadow = true;
2059 break;
2060 case Stencil:
2061 out_color_type = type_uint;
2062 out_interpolation_type = interpolation_flat;
2063 out_sampler_type = sampler_uint;
2064 out_n_components = 1;
2065 out_is_shadow = false;
2066 break;
2067 };
2068 }
2069
2070 /** Get information about color type for type of sampler
2071 *
2072 * @param sampler_type Type of sampler
2073 * @param out_color_type Type used for color storage
2074 * @param out_interpolation_type Type of interpolation
2075 * @param out_sampler_type Type of sampler
2076 * @param out_image_type Type of image
2077 * @param out_n_components Number of components in color
2078 * @param out_is_shadow If shadow sampler
2079 **/
getColorType(samplerType sampler_type,const glw::GLchar * & out_color_type,const glw::GLchar * & out_interpolation_type,const glw::GLchar * & out_sampler_type,const glw::GLchar * & out_image_type,const glw::GLchar * & out_image_layout,glw::GLuint & out_n_components,bool & out_is_shadow)2080 void TextureCubeMapArraySamplingTest::getColorType(samplerType sampler_type, const glw::GLchar*& out_color_type,
2081 const glw::GLchar*& out_interpolation_type,
2082 const glw::GLchar*& out_sampler_type,
2083 const glw::GLchar*& out_image_type,
2084 const glw::GLchar*& out_image_layout, glw::GLuint& out_n_components,
2085 bool& out_is_shadow)
2086 {
2087 getColorType(sampler_type, out_color_type, out_interpolation_type, out_sampler_type, out_n_components,
2088 out_is_shadow);
2089
2090 switch (sampler_type)
2091 {
2092 case Float:
2093 out_image_type = image_float;
2094 out_image_layout = "rgba8";
2095 break;
2096 case Depth:
2097 out_image_type = image_float;
2098 out_image_layout = "rgba8";
2099 break;
2100 case Int:
2101 out_image_type = image_int;
2102 out_image_layout = "rgba32i";
2103 break;
2104 case UInt:
2105 out_image_type = image_uint;
2106 out_image_layout = "rgba32ui";
2107 break;
2108 case Stencil:
2109 out_image_type = image_uint;
2110 out_image_layout = "r32ui";
2111 break;
2112 };
2113 }
2114
2115 /** Prepare code for passthrough fragment shader
2116 *
2117 * @param sampler_type Type of sampler
2118 * @param out_fragment_shader_code Storage for code
2119 **/
getPassThroughFragmentShaderCode(samplerType sampler_type,std::string & out_fragment_shader_code)2120 void TextureCubeMapArraySamplingTest::getPassThroughFragmentShaderCode(samplerType sampler_type,
2121 std::string& out_fragment_shader_code)
2122 {
2123 std::stringstream stream;
2124 const glw::GLchar* color_type;
2125 const glw::GLchar* interpolation_type;
2126 const glw::GLchar* ignored_sampler_type;
2127 glw::GLuint ignored_n_components;
2128 bool ignored_is_shadow;
2129
2130 /* Get type for color variables */
2131 getColorType(sampler_type, color_type, interpolation_type, ignored_sampler_type, ignored_n_components,
2132 ignored_is_shadow);
2133
2134 /* Preamble */
2135 stream << shader_code_preamble << shader_precision << "/* Pass through fragment shader */" << std::endl;
2136
2137 /* in vec4 fs_in_color */
2138 stream << interpolation_type << shader_input << color_type << fragment_shader_input << ";" << std::endl;
2139
2140 stream << std::endl;
2141
2142 /* layout(location = 0) out vec4 fs_out_color */
2143 stream << shader_layout << shader_output << color_type << fragment_shader_output << ";" << std::endl;
2144
2145 stream << std::endl;
2146
2147 /* Body */
2148 stream << fragment_shader_pass_through_body_code << std::endl;
2149
2150 /* Store result */
2151 out_fragment_shader_code = stream.str();
2152 }
2153
2154 /** Prepare code for passthrough tesselation control shader
2155 *
2156 * @param sampler_type Type of sampler
2157 * @param out_tesselation_control_shader_code Storage for code
2158 **/
getPassThroughTesselationControlShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_tesselation_control_shader_code)2159 void TextureCubeMapArraySamplingTest::getPassThroughTesselationControlShaderCode(
2160 const samplerType& sampler_type, const samplingFunction& sampling_function,
2161 std::string& out_tesselation_control_shader_code)
2162 {
2163 std::stringstream stream;
2164 glw::GLuint n_routine_attributes = 0;
2165 glw::GLuint n_type_attributes = 0;
2166 const attributeDefinition* routine_attribute_definitions = 0;
2167 const attributeDefinition* type_attribute_definitions = 0;
2168
2169 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2170 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2171
2172 /* Preamble, extension : require */
2173 stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
2174 << "/* Passthrough tesselation control shader */" << std::endl;
2175
2176 /* layout(vertices = 1) out */
2177 stream << tesselation_control_shader_layout;
2178
2179 /* in type attribute*/
2180 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2181 {
2182 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
2183 << routine_attribute_definitions[i].name << "[];" << std::endl;
2184 stream << shader_output << routine_attribute_definitions[i].type << tesselation_control_shader_output
2185 << routine_attribute_definitions[i].name << "[];" << std::endl;
2186 }
2187 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2188 {
2189 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
2190 << type_attribute_definitions[i].name << "[];" << std::endl;
2191 stream << shader_output << type_attribute_definitions[i].type << tesselation_control_shader_output
2192 << type_attribute_definitions[i].name << "[];" << std::endl;
2193 }
2194
2195 /* Body */
2196 stream << tesselation_control_shader_sampling_body_code;
2197
2198 /* tcs_out[gl_InvocationID] = vs_out[gl_InvocationID] */
2199 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2200 {
2201 stream << " " << tesselation_control_shader_output << routine_attribute_definitions[i].name
2202 << "[gl_InvocationID] = " << vertex_shader_output << routine_attribute_definitions[i].name
2203 << "[gl_InvocationID];" << std::endl;
2204 }
2205
2206 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2207 {
2208 stream << " " << tesselation_control_shader_output << type_attribute_definitions[i].name
2209 << "[gl_InvocationID] = " << vertex_shader_output << type_attribute_definitions[i].name
2210 << "[gl_InvocationID];" << std::endl;
2211 }
2212
2213 stream << "}" << std::endl << std::endl;
2214
2215 /* Store result */
2216 out_tesselation_control_shader_code = stream.str();
2217 }
2218
2219 /** Prepare code for passthrough tesselation evaluation shader
2220 *
2221 * @param sampler_type Type of sampler
2222 * @param out_tesselation_evaluation_shader_code Storage for code
2223 **/
getPassThroughTesselationEvaluationShaderCode(samplerType sampler_type,std::string & out_tesselation_evaluation_shader_code)2224 void TextureCubeMapArraySamplingTest::getPassThroughTesselationEvaluationShaderCode(
2225 samplerType sampler_type, std::string& out_tesselation_evaluation_shader_code)
2226 {
2227 const glw::GLchar* color_type = 0;
2228 bool ignored_is_shadow = false;
2229 glw::GLuint ignored_n_components = 0;
2230 const glw::GLchar* ignored_sampler_type = 0;
2231 const glw::GLchar* interpolation_type = 0;
2232 std::stringstream stream;
2233
2234 /* Get type for color variables */
2235 getColorType(sampler_type, color_type, interpolation_type, ignored_sampler_type, ignored_n_components,
2236 ignored_is_shadow);
2237
2238 /* Preamble, extension : require */
2239 stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
2240 << "/* Pass through tesselation evaluation shader */" << std::endl;
2241
2242 /* layout(point_mode) in; */
2243 stream << tesselation_evaluation_shader_layout;
2244
2245 /* in vec4 tes_in_color[] */
2246 stream << interpolation_type << shader_input << color_type << tesselation_evaluation_shader_input << "[];"
2247 << std::endl;
2248
2249 stream << std::endl;
2250
2251 /* out vec4 fs_in_color[] */
2252 stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;
2253
2254 stream << std::endl;
2255
2256 /* Body */
2257 stream << tesselation_evaluation_shader_pass_through_body_code << std::endl;
2258
2259 /* Store result */
2260 out_tesselation_evaluation_shader_code = stream.str();
2261 }
2262
2263 /** Prepare code for passthrough vertex shader
2264 *
2265 * @param sampler_type Type of sampler
2266 * @param sampling_function Type of sampling function
2267 * @param out_vertex_shader_code Storage for code
2268 **/
getPassThroughVertexShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_vertex_shader_code)2269 void TextureCubeMapArraySamplingTest::getPassThroughVertexShaderCode(const samplerType& sampler_type,
2270 const samplingFunction& sampling_function,
2271 std::string& out_vertex_shader_code)
2272 {
2273 glw::GLuint n_routine_attributes = 0;
2274 glw::GLuint n_type_attributes = 0;
2275 const attributeDefinition* routine_attribute_definitions = 0;
2276 std::stringstream stream;
2277 const attributeDefinition* type_attribute_definitions = 0;
2278
2279 /* Get attributes for sampling function */
2280 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2281 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2282
2283 /* Preamble */
2284 stream << shader_code_preamble << "/* Pass through vertex shader */" << std::endl << shader_precision;
2285
2286 /* in vec4 vs_in_position */
2287 stream << shader_input << type_vec4 << vertex_shader_input << vertex_shader_position << ";" << std::endl;
2288
2289 /* in type vs_in_attribute */
2290 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2291 {
2292 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_input
2293 << routine_attribute_definitions[i].name << ";" << std::endl;
2294 }
2295
2296 /* in float vs_in_refZ */
2297 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2298 {
2299 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_input
2300 << type_attribute_definitions[i].name << ";" << std::endl;
2301 }
2302
2303 stream << std::endl;
2304
2305 /* out type vs_out_attribute */
2306 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2307 {
2308 stream << shader_output << routine_attribute_definitions[i].type << vertex_shader_output
2309 << routine_attribute_definitions[i].name << ";" << std::endl;
2310 }
2311
2312 /* out float vs_out_refZ */
2313 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2314 {
2315 stream << shader_output << type_attribute_definitions[i].type << vertex_shader_output
2316 << type_attribute_definitions[i].name << ";" << std::endl;
2317 }
2318
2319 stream << std::endl;
2320
2321 /* Body */
2322 stream << vertex_shader_body_code;
2323
2324 /* vs_out = vs_in */
2325 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2326 {
2327 stream << " " << vertex_shader_output << routine_attribute_definitions[i].name << " = "
2328 << vertex_shader_input << routine_attribute_definitions[i].name << ";" << std::endl;
2329 }
2330
2331 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2332 {
2333 stream << " " << vertex_shader_output << type_attribute_definitions[i].name << " = " << vertex_shader_input
2334 << type_attribute_definitions[i].name << ";" << std::endl;
2335 }
2336
2337 stream << "}" << std::endl << std::endl;
2338
2339 /* Store result */
2340 out_vertex_shader_code = stream.str();
2341 }
2342
2343 /** Prepare code for sampling compute shader
2344 *
2345 * @param sampler_type Type of sampler
2346 * @param sampling_function Type of sampling function
2347 * @param out_compute_shader_code Storage for code
2348 **/
getSamplingComputeShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_compute_shader_code)2349 void TextureCubeMapArraySamplingTest::getSamplingComputeShaderCode(const samplerType& sampler_type,
2350 const samplingFunction& sampling_function,
2351 std::string& out_compute_shader_code)
2352 {
2353 const glw::GLchar* color_type = 0;
2354 const glw::GLchar* image_type_str = 0;
2355 const glw::GLchar* image_layout_str = 0;
2356 const glw::GLchar* interpolation_type = 0;
2357 bool is_shadow_sampler = false;
2358 glw::GLuint n_components = 0;
2359 glw::GLuint n_routine_attributes = 0;
2360 glw::GLuint n_type_attributes = 0;
2361 const attributeDefinition* routine_attribute_definitions = 0;
2362 const attributeDefinition* type_attribute_definitions = 0;
2363 const glw::GLchar* sampler_type_str = 0;
2364 std::string sampling_code;
2365 std::stringstream stream;
2366
2367 /* Get attributes for sampling function */
2368 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2369 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2370
2371 /* Get type for color variables */
2372 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, image_type_str, image_layout_str,
2373 n_components, is_shadow_sampler);
2374
2375 /* Get sampling code */
2376 if (false == is_shadow_sampler)
2377 {
2378 getSamplingFunctionCall(sampling_function, color_type, n_components, compute_shader_param, 0,
2379 compute_shader_color, 0, sampler_name, sampling_code);
2380 }
2381 else
2382 {
2383 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, compute_shader_param, 0,
2384 compute_shader_color, 0, sampler_name, sampling_code);
2385 }
2386
2387 /* Preamble */
2388 stream << shader_code_preamble << shader_precision << "/* Sampling compute shader */" << std::endl;
2389
2390 /* uniform samplerType sampler */
2391 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2392
2393 /* uniform writeonly image2D image*/
2394 stream << "layout(" << image_layout_str << ") " << shader_uniform << shader_writeonly << "highp " << image_type_str
2395 << image_name << ";" << std::endl;
2396
2397 /* layout(shared) buffer attribute { type attribute_data[]; }; */
2398 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2399 {
2400 stream << compute_shader_layout_binding << routine_attribute_definitions[i].binding << compute_shader_buffer
2401 << routine_attribute_definitions[i].name << std::endl;
2402
2403 stream << "{\n";
2404 stream << " " << routine_attribute_definitions[i].type << " " << routine_attribute_definitions[i].name
2405 << "_data[];\n";
2406 stream << "};\n";
2407 }
2408 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2409 {
2410 stream << compute_shader_layout_binding << type_attribute_definitions[i].binding << compute_shader_buffer
2411 << type_attribute_definitions[i].name << std::endl;
2412
2413 stream << "{\n";
2414 stream << " " << type_attribute_definitions[i].type << " " << type_attribute_definitions[i].name
2415 << "_data[];\n";
2416 stream << "};\n";
2417 }
2418
2419 /* layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; */
2420 stream << compute_shader_layout << std::endl;
2421
2422 /* main + body */
2423 stream << compute_shader_body;
2424
2425 /* type cs_attribute = attribute_data[vertex_index] */
2426 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2427 {
2428 stream << " " << routine_attribute_definitions[i].type << compute_shader_param
2429 << routine_attribute_definitions[i].name << " = " << routine_attribute_definitions[i].name
2430 << "_data[vertex_index];" << std::endl;
2431 }
2432 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2433 {
2434 stream << " " << type_attribute_definitions[i].type << compute_shader_param
2435 << type_attribute_definitions[i].name << " = " << type_attribute_definitions[i].name
2436 << "_data[vertex_index];" << std::endl;
2437 }
2438
2439 /* type color */
2440 stream << std::endl << " " << color_type << compute_shader_color << ";" << std::endl;
2441
2442 /* color = texture*/
2443 stream << std::endl << sampling_code << std::endl;
2444 //stream << std::endl << compute_shader_color << " = vec4(cs_grad_x, 255.0);" << std::endl;
2445
2446 /* imageStore */
2447 stream << compute_shader_image_store;
2448 switch (n_components)
2449 {
2450 case 1:
2451 /* imageStore(image, image_coord, color.r);*/
2452 if (sampler_type == Depth)
2453 {
2454 stream << "vec4(" << compute_shader_color << ")";
2455 }
2456 else if (sampler_type == Stencil)
2457 {
2458 stream << "uvec4(" << compute_shader_color << ")";
2459 }
2460 else
2461 {
2462 // unexpected case
2463 DE_ASSERT(false);
2464 }
2465 break;
2466 case 4:
2467 /* imageStore(image, image_coord, color);*/
2468 stream << compute_shader_color;
2469 break;
2470 };
2471
2472 stream << ");\n";
2473
2474 stream << "}\n" << std::endl;
2475
2476 out_compute_shader_code = stream.str();
2477 }
2478
2479 /** Prepare code for sampling fragment shader
2480 *
2481 * @param sampler_type Type of sampler
2482 * @param sampling_function Type of sampling function
2483 * @param out_fragment_shader_code Storage for code
2484 **/
getSamplingFragmentShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_fragment_shader_code)2485 void TextureCubeMapArraySamplingTest::getSamplingFragmentShaderCode(const samplerType& sampler_type,
2486 const samplingFunction& sampling_function,
2487 std::string& out_fragment_shader_code)
2488 {
2489 const glw::GLchar* color_type = 0;
2490 const glw::GLchar* interpolation_type = 0;
2491 bool is_shadow_sampler = false;
2492 glw::GLuint n_components = 0;
2493 glw::GLuint n_routine_attributes = 0;
2494 glw::GLuint n_type_attributes = 0;
2495 const attributeDefinition* routine_attribute_definitions = 0;
2496 const attributeDefinition* type_attribute_definitions = 0;
2497 const glw::GLchar* sampler_type_str = 0;
2498 std::string sampling_code;
2499 std::stringstream stream;
2500
2501 /* Get attributes for sampling function */
2502 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2503 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2504
2505 /* Get type for color variables */
2506 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);
2507
2508 /* Get sampling code */
2509 if (false == is_shadow_sampler)
2510 {
2511 getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, 0,
2512 fragment_shader_output, 0, sampler_name, sampling_code);
2513 }
2514 else
2515 {
2516 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, 0,
2517 fragment_shader_output, 0, sampler_name, sampling_code);
2518 }
2519
2520 /* Preamble */
2521 stream << shader_code_preamble << shader_precision << "/* Sampling fragment shader */" << std::endl;
2522
2523 /* uniform samplerType sampler */
2524 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2525
2526 stream << std::endl;
2527
2528 /* in type attribute */
2529 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2530 {
2531 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
2532 << routine_attribute_definitions[i].name << ";" << std::endl;
2533 }
2534 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2535 {
2536 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
2537 << type_attribute_definitions[i].name << ";" << std::endl;
2538 }
2539
2540 stream << std::endl;
2541
2542 /* layout(location = 0) out vec4 fs_out_color */
2543 stream << shader_layout << shader_output << color_type << fragment_shader_output << ";" << std::endl;
2544
2545 stream << std::endl;
2546
2547 /* Body */
2548 stream << fragment_shader_sampling_body_code;
2549
2550 /* Sampling code */
2551 stream << sampling_code;
2552
2553 stream << "}" << std::endl << std::endl;
2554
2555 /* Store result */
2556 out_fragment_shader_code = stream.str();
2557 }
2558
2559 /** Prepare sampling code
2560 *
2561 * @param sampling_function Type of sampling function
2562 * @param color_type Type of color
2563 * @param n_components Number of components
2564 * @param attribute_name_prefix Prefix for attributes
2565 * @param attribute_index Index for attributes
2566 * @param color_variable_name Name of color variable
2567 * @param color_variable_index Index for color variable
2568 * @param sampler_name_p Name of sampler
2569 * @param out_code Result code
2570 **/
getSamplingFunctionCall(samplingFunction sampling_function,const glw::GLchar * color_type,glw::GLuint n_components,const glw::GLchar * attribute_name_prefix,const glw::GLchar * attribute_index,const glw::GLchar * color_variable_name,const glw::GLchar * color_variable_index,const glw::GLchar * sampler_name_p,std::string & out_code)2571 void TextureCubeMapArraySamplingTest::getSamplingFunctionCall(samplingFunction sampling_function,
2572 const glw::GLchar* color_type, glw::GLuint n_components,
2573 const glw::GLchar* attribute_name_prefix,
2574 const glw::GLchar* attribute_index,
2575 const glw::GLchar* color_variable_name,
2576 const glw::GLchar* color_variable_index,
2577 const glw::GLchar* sampler_name_p, std::string& out_code)
2578 {
2579 std::stringstream stream;
2580
2581 switch (sampling_function)
2582 {
2583 case Texture:
2584 /* fs_in_color = texture(sampler, vs_out_texture_coordinates); */
2585 stream << " " << var2str(0, color_variable_name, color_variable_index);
2586
2587 stream << " = " << texture_func << "(" << sampler_name_p;
2588
2589 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);
2590
2591 if (1 == n_components)
2592 {
2593 stream << ").x;" << std::endl;
2594 }
2595 else
2596 {
2597 stream << ");" << std::endl;
2598 }
2599 break;
2600
2601 case TextureLod:
2602 /* fs_in_color = textureLod(sampler, vs_out_texture_coordinates, lod); */
2603 stream << " " << var2str(0, color_variable_name, color_variable_index);
2604 stream << " = " << textureLod_func << "(" << sampler_name_p;
2605
2606 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
2607 << var2str(attribute_name_prefix, attribute_lod, attribute_index);
2608
2609 if (1 == n_components)
2610 {
2611 stream << ").x;" << std::endl;
2612 }
2613 else
2614 {
2615 stream << ");" << std::endl;
2616 }
2617 break;
2618
2619 case TextureGrad:
2620 /* fs_in_color = textureGrad(sampler, vs_out_texture_coordinates, vs_out_grad_x, vs_out_grad_y); */
2621 stream << " " << var2str(0, color_variable_name, color_variable_index);
2622
2623 stream << " = " << textureGrad_func << "(" << sampler_name_p;
2624
2625 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
2626 << var2str(attribute_name_prefix, attribute_grad_x, attribute_index) << ", "
2627 << var2str(attribute_name_prefix, attribute_grad_y, attribute_index);
2628
2629 if (1 == n_components)
2630 {
2631 stream << ").x;" << std::endl;
2632 }
2633 else
2634 {
2635 stream << ");" << std::endl;
2636 }
2637 break;
2638
2639 case TextureGather:
2640 if (4 == n_components)
2641 {
2642 /**
2643 * color_type component_0 = textureGather(sampler, vs_out_texture_coordinates, 0);
2644 * color_type component_1 = textureGather(sampler, vs_out_texture_coordinates, 1);
2645 * color_type component_2 = textureGather(sampler, vs_out_texture_coordinates, 2);
2646 * color_type component_3 = textureGather(sampler, vs_out_texture_coordinates, 3);
2647 * fs_in_color = color_type(component_0.r, component_1.g, component_2.b, component_3.a);
2648 **/
2649 for (glw::GLuint i = 0; i < 4; ++i)
2650 {
2651 stream << " " << color_type << "component_" << i << " = " << textureGather_func << "("
2652 << sampler_name_p;
2653
2654 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);
2655
2656 stream << ", " << i << ");" << std::endl;
2657 }
2658
2659 stream << " " << var2str(0, color_variable_name, color_variable_index);
2660
2661 stream << " = " << color_type << "(component_0.r, "
2662 << "component_1.g, "
2663 << "component_2.b, "
2664 << "component_3.a);" << std::endl;
2665 }
2666 else
2667 {
2668 stream << " " << var2str(0, color_variable_name, color_variable_index);
2669
2670 stream << " = " << textureGather_func << "(" << sampler_name_p;
2671
2672 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index);
2673
2674 stream << ").x;" << std::endl;
2675 }
2676 break;
2677 }
2678
2679 out_code = stream.str();
2680 }
2681
2682 /** Prepare code for sampling geometry shader
2683 *
2684 * @param sampler_type Type of sampler
2685 * @param sampling_function Type of sampling function
2686 * @param out_geometry_shader_code Storage for code
2687 **/
getSamplingGeometryShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_geometry_shader_code)2688 void TextureCubeMapArraySamplingTest::getSamplingGeometryShaderCode(const samplerType& sampler_type,
2689 const samplingFunction& sampling_function,
2690 std::string& out_geometry_shader_code)
2691 {
2692 const glw::GLchar* color_type = 0;
2693 const glw::GLchar* interpolation_type = 0;
2694 bool is_shadow_sampler = false;
2695 glw::GLuint n_components = 0;
2696 glw::GLuint n_routine_attributes = 0;
2697 glw::GLuint n_type_attributes = 0;
2698 const attributeDefinition* routine_attribute_definitions = 0;
2699 const attributeDefinition* type_attribute_definitions = 0;
2700 const glw::GLchar* sampler_type_str = 0;
2701 std::string sampling_code;
2702 std::stringstream stream;
2703
2704 /* Get attributes for sampling function */
2705 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2706 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2707
2708 /* Get type for color variables */
2709 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);
2710
2711 /* Get sampling code */
2712 if (false == is_shadow_sampler)
2713 {
2714 getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "0",
2715 fragment_shader_input, 0, sampler_name, sampling_code);
2716 }
2717 else
2718 {
2719 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "0",
2720 fragment_shader_input, 0, sampler_name, sampling_code);
2721 }
2722
2723 /* Preamble, extension : require */
2724 stream << shader_code_preamble << geometry_shader_extension << shader_precision << std::endl
2725 << "/* Sampling geometry shader */" << std::endl;
2726
2727 /* In out layout */
2728 stream << geometry_shader_layout;
2729
2730 /* uniform samplerType sampler */
2731 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2732
2733 stream << std::endl;
2734
2735 /* in type attribute[]*/
2736 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2737 {
2738 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
2739 << routine_attribute_definitions[i].name << "[];" << std::endl;
2740 }
2741 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2742 {
2743 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
2744 << type_attribute_definitions[i].name << "[];" << std::endl;
2745 }
2746
2747 stream << std::endl;
2748
2749 /* out vec4 fs_in_color */
2750 stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;
2751
2752 stream << std::endl;
2753
2754 /* Body */
2755 stream << geometry_shader_sampling_body_code;
2756
2757 /* Sampling code */
2758 stream << sampling_code;
2759
2760 stream << geometry_shader_emit_vertex_code << std::endl;
2761
2762 /* Store result */
2763 out_geometry_shader_code = stream.str();
2764 }
2765
2766 /** Prepare code for sampling tesselation control shader
2767 *
2768 * @param sampler_type Type of sampler
2769 * @param sampling_function Type of sampling function
2770 * @param out_tesselation_control_shader_code Storage for code
2771 **/
getSamplingTesselationControlShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_tesselation_control_shader_code)2772 void TextureCubeMapArraySamplingTest::getSamplingTesselationControlShaderCode(
2773 const samplerType& sampler_type, const samplingFunction& sampling_function,
2774 std::string& out_tesselation_control_shader_code)
2775 {
2776 const glw::GLchar* color_type = 0;
2777 const glw::GLchar* interpolation_type = 0;
2778 bool is_shadow_sampler = false;
2779 glw::GLuint n_components = 0;
2780 glw::GLuint n_routine_attributes = 0;
2781 glw::GLuint n_type_attributes = 0;
2782 const attributeDefinition* routine_attribute_definitions = 0;
2783 const attributeDefinition* type_attribute_definitions = 0;
2784 const glw::GLchar* sampler_type_str = 0;
2785 std::string sampling_code;
2786 std::stringstream stream;
2787
2788 /* Get attributes for sampling function */
2789 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2790 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2791
2792 /* Get type for color variables */
2793 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);
2794
2795 /* Get sampling code */
2796 if (false == is_shadow_sampler)
2797 {
2798 getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output, "gl_InvocationID",
2799 tesselation_evaluation_shader_input, "gl_InvocationID", sampler_name, sampling_code);
2800 }
2801 else
2802 {
2803 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_output,
2804 "gl_InvocationID", tesselation_evaluation_shader_input, "gl_InvocationID",
2805 sampler_name, sampling_code);
2806 }
2807
2808 /* Preamble, extension : require */
2809 stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
2810 << "/* Sampling tesselation control shader */" << std::endl;
2811
2812 /* layout(vertices = 1) out */
2813 stream << tesselation_control_shader_layout;
2814
2815 /* uniform samplerType sampler */
2816 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2817
2818 stream << std::endl;
2819
2820 /* in type attribute[]*/
2821 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2822 {
2823 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_output
2824 << routine_attribute_definitions[i].name << "[];" << std::endl;
2825 }
2826 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2827 {
2828 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_output
2829 << type_attribute_definitions[i].name << "[];" << std::endl;
2830 }
2831
2832 stream << std::endl;
2833
2834 /* out vec4 tes_in_color */
2835 stream << interpolation_type << shader_output << color_type << tesselation_evaluation_shader_input << "[];"
2836 << std::endl;
2837
2838 stream << std::endl;
2839
2840 /* Body */
2841 stream << tesselation_control_shader_sampling_body_code;
2842
2843 /* Sampling code */
2844 stream << sampling_code;
2845
2846 stream << "}" << std::endl << std::endl;
2847
2848 /* Store result */
2849 out_tesselation_control_shader_code = stream.str();
2850 }
2851
2852 /** Prepare code for sampling tesselation evaluation shader
2853 *
2854 * @param sampler_type Type of sampler
2855 * @param sampling_function Type of sampling function
2856 * @param out_tesselation_evaluation_shader_code Storage for code
2857 **/
getSamplingTesselationEvaluationShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_tesselation_evaluation_shader_code)2858 void TextureCubeMapArraySamplingTest::getSamplingTesselationEvaluationShaderCode(
2859 const samplerType& sampler_type, const samplingFunction& sampling_function,
2860 std::string& out_tesselation_evaluation_shader_code)
2861 {
2862 const glw::GLchar* color_type = 0;
2863 const glw::GLchar* interpolation_type = 0;
2864 bool is_shadow_sampler = false;
2865 glw::GLuint n_components = 0;
2866 glw::GLuint n_routine_attributes = 0;
2867 glw::GLuint n_type_attributes = 0;
2868 const attributeDefinition* routine_attribute_definitions = 0;
2869 const attributeDefinition* type_attribute_definitions = 0;
2870 const glw::GLchar* sampler_type_str = 0;
2871 std::string sampling_code;
2872 std::stringstream stream;
2873 const glw::GLchar* prev_stage_output = (glu::isContextTypeES(m_context.getRenderContext().getType())) ?
2874 tesselation_control_shader_output :
2875 vertex_shader_output;
2876
2877 /* Get attributes for sampling function */
2878 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2879 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2880
2881 /* Get type for color variables */
2882 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);
2883
2884 /* Get sampling code */
2885 if (false == is_shadow_sampler)
2886 {
2887 getSamplingFunctionCall(sampling_function, color_type, n_components, prev_stage_output, "0",
2888 fragment_shader_input, 0, sampler_name, sampling_code);
2889 }
2890 else
2891 {
2892 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, prev_stage_output, "0",
2893 fragment_shader_input, 0, sampler_name, sampling_code);
2894 }
2895
2896 /* Preamble, extension : require */
2897 stream << shader_code_preamble << tesselation_shader_extension << shader_precision << std::endl
2898 << "/* Sampling tesselation evaluation shader */" << std::endl;
2899
2900 /* layout(point_mode) in; */
2901 stream << tesselation_evaluation_shader_layout;
2902
2903 /* uniform samplerType sampler */
2904 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2905
2906 stream << std::endl;
2907
2908 /* in type attribute[]*/
2909 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2910 {
2911 stream << shader_input << routine_attribute_definitions[i].type << prev_stage_output
2912 << routine_attribute_definitions[i].name << "[];" << std::endl;
2913 }
2914 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2915 {
2916 stream << shader_input << type_attribute_definitions[i].type << prev_stage_output
2917 << type_attribute_definitions[i].name << "[];" << std::endl;
2918 }
2919
2920 stream << std::endl;
2921
2922 /* out vec4 tes_in_color */
2923 stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;
2924
2925 stream << std::endl;
2926
2927 /* Body */
2928 stream << tesselation_evaluation_shader_sampling_body_code;
2929
2930 /* Sampling code */
2931 stream << sampling_code;
2932
2933 stream << "}" << std::endl << std::endl;
2934
2935 /* Store result */
2936 out_tesselation_evaluation_shader_code = stream.str();
2937 }
2938
2939 /** Prepare code for sampling vertex shader
2940 *
2941 * @param sampler_type Type of sampler
2942 * @param sampling_function Type of sampling function
2943 * @param out_vertex_shader_code Storage for code
2944 **/
getSamplingVertexShaderCode(const samplerType & sampler_type,const samplingFunction & sampling_function,std::string & out_vertex_shader_code)2945 void TextureCubeMapArraySamplingTest::getSamplingVertexShaderCode(const samplerType& sampler_type,
2946 const samplingFunction& sampling_function,
2947 std::string& out_vertex_shader_code)
2948 {
2949 const glw::GLchar* color_type = 0;
2950 const glw::GLchar* interpolation_type = 0;
2951 bool is_shadow_sampler = false;
2952 glw::GLuint n_components = 0;
2953 glw::GLuint n_routine_attributes = 0;
2954 glw::GLuint n_type_attributes = 0;
2955 const attributeDefinition* routine_attribute_definitions = 0;
2956 const attributeDefinition* type_attribute_definitions = 0;
2957 const glw::GLchar* sampler_type_str = 0;
2958 std::string sampling_code;
2959 std::stringstream stream;
2960
2961 /* Get attributes for sampling function */
2962 getAttributes(sampling_function, routine_attribute_definitions, n_routine_attributes);
2963 getAttributes(sampler_type, type_attribute_definitions, n_type_attributes);
2964
2965 /* Get type for color variables */
2966 getColorType(sampler_type, color_type, interpolation_type, sampler_type_str, n_components, is_shadow_sampler);
2967
2968 /* Get sampling code */
2969 if (false == is_shadow_sampler)
2970 {
2971 getSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_input, 0,
2972 fragment_shader_input, 0, sampler_name, sampling_code);
2973 }
2974 else
2975 {
2976 getShadowSamplingFunctionCall(sampling_function, color_type, n_components, vertex_shader_input, 0,
2977 fragment_shader_input, 0, sampler_name, sampling_code);
2978 }
2979
2980 /* Preamble */
2981 stream << shader_code_preamble << shader_precision << "/* Sampling vertex shader */" << std::endl;
2982
2983 /* uniform samplerType sampler */
2984 stream << shader_uniform << "highp " << sampler_type_str << sampler_name << ";" << std::endl;
2985
2986 stream << std::endl;
2987
2988 /* in vec4 vs_in_position */
2989 stream << shader_input << type_vec4 << vertex_shader_input << vertex_shader_position << ";" << std::endl;
2990
2991 /* in type attribute */
2992 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
2993 {
2994 stream << shader_input << routine_attribute_definitions[i].type << vertex_shader_input
2995 << routine_attribute_definitions[i].name << ";" << std::endl;
2996 }
2997 for (glw::GLuint i = 0; i < n_type_attributes; ++i)
2998 {
2999 stream << shader_input << type_attribute_definitions[i].type << vertex_shader_input
3000 << type_attribute_definitions[i].name << ";" << std::endl;
3001 }
3002
3003 stream << std::endl;
3004
3005 /* out vec4 fs_in_color; */
3006 stream << interpolation_type << shader_output << color_type << fragment_shader_input << ";" << std::endl;
3007
3008 stream << std::endl;
3009
3010 /* Body */
3011 stream << vertex_shader_body_code;
3012
3013 /* Sampling code */
3014 stream << sampling_code;
3015
3016 stream << "}" << std::endl << std::endl;
3017
3018 /* Store result */
3019 out_vertex_shader_code = stream.str();
3020 }
3021
3022 /** Prepare shadow sampling code
3023 *
3024 * @param sampling_function Type of sampling function
3025 * @param color_type Type of color
3026 * @param n_components Number of components
3027 * @param attribute_name_prefix Prefix for attributes
3028 * @param attribute_index Index for attributes
3029 * @param color_variable_name Name of color variable
3030 * @param color_variable_index Index for color variable
3031 * @param sampler_name_p Name of sampler
3032 * @param out_code Result code
3033 **/
getShadowSamplingFunctionCall(samplingFunction sampling_function,const glw::GLchar * color_type,glw::GLuint n_components,const glw::GLchar * attribute_name_prefix,const glw::GLchar * attribute_index,const glw::GLchar * color_variable_name,const glw::GLchar * color_variable_index,const glw::GLchar * sampler_name_p,std::string & out_code)3034 void TextureCubeMapArraySamplingTest::getShadowSamplingFunctionCall(
3035 samplingFunction sampling_function, const glw::GLchar* color_type, glw::GLuint n_components,
3036 const glw::GLchar* attribute_name_prefix, const glw::GLchar* attribute_index,
3037 const glw::GLchar* color_variable_name, const glw::GLchar* color_variable_index, const glw::GLchar* sampler_name_p,
3038 std::string& out_code)
3039 {
3040 std::stringstream stream;
3041
3042 switch (sampling_function)
3043 {
3044 case Texture:
3045 /* fs_in_color = texture(sampler, vs_out_texture_coordinates); */
3046 stream << " " << var2str(0, color_variable_name, color_variable_index);
3047
3048 stream << " = " << texture_func << "(" << sampler_name_p;
3049
3050 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
3051 << var2str(attribute_name_prefix, attribute_refZ, attribute_index);
3052
3053 stream << ");" << std::endl;
3054 break;
3055 case TextureLod:
3056 /* fs_in_color = textureLod(sampler, vs_out_texture_coordinates, lod); */
3057 stream << " " << var2str(0, color_variable_name, color_variable_index);
3058
3059 stream << " = " << textureLod_func << "(" << sampler_name_p;
3060
3061 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
3062 << var2str(attribute_name_prefix, attribute_lod, attribute_index) << ", "
3063 << var2str(attribute_name_prefix, attribute_refZ, attribute_index);
3064
3065 stream << ");" << std::endl;
3066 break;
3067 case TextureGrad:
3068 /* fs_in_color = textureGrad(sampler, vs_out_texture_coordinates, vs_out_grad_x, vs_out_grad_y); */
3069 throw tcu::NotSupportedError("textureGrad operation is not available for samplerCubeArrayShadow", "", __FILE__,
3070 __LINE__);
3071 break;
3072 case TextureGather:
3073 if (4 == n_components)
3074 {
3075 /**
3076 * color_type component_0 = textureGather(sampler, vs_out_texture_coordinates, 0);
3077 * color_type component_1 = textureGather(sampler, vs_out_texture_coordinates, 1);
3078 * color_type component_2 = textureGather(sampler, vs_out_texture_coordinates, 2);
3079 * color_type component_3 = textureGather(sampler, vs_out_texture_coordinates, 3);
3080 * fs_in_color = color_type(component_0.r, component_1.g, component_2.b, component_3.a);
3081 **/
3082 for (glw::GLuint i = 0; i < 4; ++i)
3083 {
3084 stream << " " << color_type << "component_" << i;
3085
3086 stream << " = " << textureGather_func << "(" << sampler_name_p;
3087
3088 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
3089 << var2str(attribute_name_prefix, attribute_refZ, attribute_index);
3090
3091 stream << ");" << std::endl;
3092 }
3093
3094 stream << " " << var2str(0, color_variable_name, color_variable_index);
3095
3096 stream << " = " << color_type << "(component_0.r, "
3097 << "component_1.g, "
3098 << "component_2.b, "
3099 << "component_3.a);" << std::endl;
3100 }
3101 else
3102 {
3103 stream << " " << var2str(0, color_variable_name, color_variable_index);
3104
3105 stream << " = " << textureGather_func << "(" << sampler_name_p;
3106
3107 stream << ", " << var2str(attribute_name_prefix, attribute_texture_coordinate, attribute_index) << ", "
3108 << var2str(attribute_name_prefix, attribute_refZ, attribute_index);
3109
3110 stream << ").x;" << std::endl;
3111 }
3112 break;
3113 }
3114
3115 out_code = stream.str();
3116 }
3117
3118 /** Check if combination of sampler type and sampling function is supported
3119 *
3120 * @param sampler_type Type of sampler
3121 * @param sampling_function Type of sampling function
3122 *
3123 * @return true When supported
3124 * false When not supported
3125 **/
isSamplerSupportedByFunction(const samplerType sampler_type,const samplingFunction sampling_function)3126 bool TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(const samplerType sampler_type,
3127 const samplingFunction sampling_function)
3128 {
3129 if ((Depth == sampler_type) && ((TextureLod == sampling_function) || (TextureGrad == sampling_function)))
3130 {
3131 return false;
3132 }
3133
3134 return true;
3135 }
3136
3137 /** Executes the test.
3138 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3139 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3140 * Note the function throws exception should an error occur!
3141 **/
iterate()3142 tcu::TestNode::IterateResult TextureCubeMapArraySamplingTest::iterate()
3143 {
3144 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION
3145
3146 for (resolutionsVectorType::iterator resolution = m_compressed_resolutions.begin(),
3147 end_resolution = m_compressed_resolutions.end();
3148 end_resolution != resolution; ++resolution)
3149 {
3150 prepareDumpForTextureCompression(*resolution);
3151 }
3152
3153 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3154
3155 return STOP;
3156
3157 #else /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */
3158
3159 if (false == m_is_texture_cube_map_array_supported)
3160 {
3161 throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3162 }
3163
3164 // These shader stages are always supported
3165 m_shaders.push_back(shaderConfiguration(Compute, GL_POINTS, "Compute"));
3166 m_shaders.push_back(shaderConfiguration(Fragment, GL_POINTS, "Fragment"));
3167 m_shaders.push_back(shaderConfiguration(Vertex, GL_POINTS, "Vertex"));
3168
3169 // Check if geometry shader is supported
3170 if (true == m_is_geometry_shader_extension_supported)
3171 {
3172 m_shaders.push_back(shaderConfiguration(Geometry, GL_POINTS, "Geometry"));
3173 }
3174
3175 // Check if tesselation shaders are supported
3176 if (true == m_is_tessellation_shader_supported)
3177 {
3178 m_shaders.push_back(shaderConfiguration(Tesselation_Control, m_glExtTokens.PATCHES, "Tesselation_Control"));
3179 m_shaders.push_back(
3180 shaderConfiguration(Tesselation_Evaluation, m_glExtTokens.PATCHES, "Tesselation_Evaluation"));
3181 }
3182
3183 /* GL functions */
3184 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3185
3186 gl.genFramebuffers(1, &m_framebuffer_object_id);
3187
3188 if (true == m_is_tessellation_shader_supported)
3189 {
3190 gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1);
3191 }
3192
3193 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
3194 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
3195
3196 testFormats(m_formats, m_resolutions);
3197 testFormats(m_compressed_formats, m_compressed_resolutions);
3198
3199 if (true == m_is_tessellation_shader_supported)
3200 {
3201 gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3);
3202 }
3203
3204 gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
3205 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
3206
3207 gl.deleteFramebuffers(1, &m_framebuffer_object_id);
3208 m_framebuffer_object_id = 0;
3209
3210 m_testCtx.getLog() << tcu::TestLog::Section("Summary", "");
3211 if ((0 != failed_cases) || (0 != invalid_type_cases))
3212 {
3213 m_testCtx.getLog() << tcu::TestLog::Message << "Test failed! Number of found errors: " << failed_cases
3214 << tcu::TestLog::EndMessage;
3215
3216 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid shaders: " << invalid_shaders
3217 << tcu::TestLog::EndMessage;
3218
3219 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid programs: " << invalid_programs
3220 << tcu::TestLog::EndMessage;
3221
3222 m_testCtx.getLog() << tcu::TestLog::Message
3223 << "glGetActiveUniform or glGetProgramResourceiv reported invalid type: "
3224 << invalid_type_cases << tcu::TestLog::EndMessage;
3225
3226 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3227 }
3228 else
3229 {
3230 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3231 }
3232
3233 m_testCtx.getLog() << tcu::TestLog::Message << "Number of executed test cases: " << tested_cases
3234 << tcu::TestLog::EndMessage;
3235
3236 m_testCtx.getLog() << tcu::TestLog::Message << "Total shaders: " << compiled_shaders << tcu::TestLog::EndMessage;
3237
3238 m_testCtx.getLog() << tcu::TestLog::Message << "Total programs: " << linked_programs << tcu::TestLog::EndMessage;
3239
3240 m_testCtx.getLog() << tcu::TestLog::EndSection;
3241
3242 return STOP;
3243 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */
3244 }
3245
3246 /** Link program
3247 *
3248 * @param info Program information
3249 **/
link(programDefinition & info)3250 void TextureCubeMapArraySamplingTest::link(programDefinition& info)
3251 {
3252 linked_programs += 1;
3253
3254 /* Not supported format */
3255 if (programDefinition::m_invalid_program_object_id == info.getProgramId())
3256 {
3257 return;
3258 }
3259
3260 if (false == info.link())
3261 {
3262 invalid_programs += 1;
3263
3264 logLinkingLog(info);
3265 logProgram(info);
3266 }
3267 }
3268
3269 /** Logs compilation log
3270 *
3271 * @param info Shader information
3272 **/
logCompilationLog(const shaderDefinition & info)3273 void TextureCubeMapArraySamplingTest::logCompilationLog(const shaderDefinition& info)
3274 {
3275 std::string info_log = getCompilationInfoLog(info.getShaderId());
3276 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failure:\n\n"
3277 << info_log << tcu::TestLog::EndMessage;
3278 m_testCtx.getLog() << tcu::TestLog::Message << "Shader source:\n\n" << info.getSource() << tcu::TestLog::EndMessage;
3279 }
3280
3281 /** Logs linkig log
3282 *
3283 * @param info Program information
3284 **/
logLinkingLog(const programDefinition & info)3285 void TextureCubeMapArraySamplingTest::logLinkingLog(const programDefinition& info)
3286 {
3287 glw::GLuint program_object_id = info.getProgramId();
3288
3289 if (programDefinition::m_invalid_program_object_id == program_object_id)
3290 {
3291 return;
3292 }
3293
3294 std::string info_log = getLinkingInfoLog(program_object_id);
3295 m_testCtx.getLog() << tcu::TestLog::Message << "Program linking failure:\n\n"
3296 << info_log << tcu::TestLog::EndMessage;
3297 }
3298
3299 /** Logs shaders used by program
3300 *
3301 * @param info Program information
3302 **/
logProgram(const programDefinition & info)3303 void TextureCubeMapArraySamplingTest::logProgram(const programDefinition& info)
3304 {
3305 glw::GLuint program_object_id = info.getProgramId();
3306
3307 if (programDefinition::m_invalid_program_object_id == program_object_id)
3308 {
3309 return;
3310 }
3311
3312 tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;
3313
3314 message << "Program id: " << program_object_id;
3315
3316 const shaderDefinition* compute = info.getShader(Compute);
3317 const shaderDefinition* fragment = info.getShader(Fragment);
3318 const shaderDefinition* geometry = info.getShader(Geometry);
3319 const shaderDefinition* tcs = info.getShader(Tesselation_Control);
3320 const shaderDefinition* tes = info.getShader(Tesselation_Evaluation);
3321 const shaderDefinition* vertex = info.getShader(Vertex);
3322
3323 if (0 != compute)
3324 {
3325 message << "\nCompute shader:\n" << compute->getSource();
3326 }
3327
3328 if (0 != vertex)
3329 {
3330 message << "\nVertex shader:\n" << vertex->getSource();
3331 }
3332
3333 if (0 != geometry)
3334 {
3335 message << "\nGeometry shader:\n" << geometry->getSource();
3336 }
3337
3338 if (0 != tcs)
3339 {
3340 message << "\nTCS shader:\n" << tcs->getSource();
3341 }
3342
3343 if (0 != tes)
3344 {
3345 message << "\nTES shader:\n" << tes->getSource();
3346 }
3347
3348 if (0 != fragment)
3349 {
3350 message << "\nFragment shader:\n" << fragment->getSource();
3351 }
3352
3353 message << tcu::TestLog::EndMessage;
3354 }
3355
3356 /** Prepare compressed textures
3357 *
3358 * @param texture Texture information
3359 * @param format Texture format
3360 * @param resolution Texture resolution
3361 * @param mutability Texture mutability
3362 **/
prepareCompresedTexture(const textureDefinition & texture,const formatDefinition & format,const resolutionDefinition & resolution,bool mutability)3363 void TextureCubeMapArraySamplingTest::prepareCompresedTexture(const textureDefinition& texture,
3364 const formatDefinition& format,
3365 const resolutionDefinition& resolution, bool mutability)
3366 {
3367 static const glw::GLint n_faces = 6;
3368
3369 const glw::GLint array_length = resolution.m_depth / n_faces;
3370 const glw::GLint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
3371 glw::GLsizei texture_width = 0;
3372 glw::GLsizei texture_height = 0;
3373
3374 /* GL functions */
3375 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3376
3377 texture.bind(GL_TEXTURE_CUBE_MAP_ARRAY);
3378
3379 if (false == mutability)
3380 {
3381 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, n_mipmap_levels, format.m_source.m_internal_format,
3382 resolution.m_width, resolution.m_height, resolution.m_depth);
3383
3384 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage3D");
3385
3386 texture_width = resolution.m_width;
3387 texture_height = resolution.m_height;
3388
3389 for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
3390 {
3391 const glw::GLubyte* image_data = 0;
3392 glw::GLuint image_size = 0;
3393
3394 getCompressedTexture(resolution.m_width, resolution.m_height, array_length, mipmap_level, image_data,
3395 image_size);
3396
3397 if (0 == image_data)
3398 {
3399 throw tcu::InternalError("Invalid compressed texture", "", __FILE__, __LINE__);
3400 }
3401
3402 gl.compressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, 0, /* x_offset */
3403 0, /* y offset */
3404 0, /* z offset */
3405 texture_width, texture_height, resolution.m_depth,
3406 format.m_source.m_internal_format, image_size, image_data);
3407
3408 GLU_EXPECT_NO_ERROR(gl.getError(), "compressedTexSubImage3D");
3409
3410 texture_width = de::max(1, texture_width / 2);
3411 texture_height = de::max(1, texture_height / 2);
3412 }
3413 }
3414 else
3415 {
3416 texture_width = resolution.m_width;
3417 texture_height = resolution.m_height;
3418
3419 for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
3420 {
3421 const glw::GLubyte* image_data = 0;
3422 glw::GLuint image_size = 0;
3423
3424 getCompressedTexture(resolution.m_width, resolution.m_height, array_length, mipmap_level, image_data,
3425 image_size);
3426
3427 if (0 == image_data)
3428 {
3429 throw tcu::InternalError("Invalid compressed texture", "", __FILE__, __LINE__);
3430 }
3431
3432 gl.compressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, format.m_source.m_internal_format,
3433 texture_width, texture_height, resolution.m_depth, 0 /* border */, image_size,
3434 image_data);
3435
3436 GLU_EXPECT_NO_ERROR(gl.getError(), "compressedTexImage3D");
3437
3438 texture_width = de::max(1, texture_width / 2);
3439 texture_height = de::max(1, texture_height / 2);
3440 }
3441 }
3442 }
3443
3444 /** Prepare not comporessed textures
3445 *
3446 * @param texture Texture information
3447 * @param format Texture format
3448 * @param resolution Texture resolution
3449 * @param mutability Texture mutability
3450 **/
prepareTexture(const textureDefinition & texture,const formatDefinition & texture_format,const resolutionDefinition & resolution,bool mutability)3451 void TextureCubeMapArraySamplingTest::prepareTexture(const textureDefinition& texture,
3452 const formatDefinition& texture_format,
3453 const resolutionDefinition& resolution, bool mutability)
3454 {
3455 static const glw::GLint n_faces = 6;
3456
3457 const glw::GLint n_elements = resolution.m_depth / n_faces;
3458 const glw::GLint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
3459 glw::GLsizei texture_width = 0;
3460 glw::GLsizei texture_height = 0;
3461
3462 /* GL functions */
3463 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3464
3465 texture.bind(GL_TEXTURE_CUBE_MAP_ARRAY);
3466
3467 if (false == mutability)
3468 {
3469 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, n_mipmap_levels, texture_format.m_source.m_internal_format,
3470 resolution.m_width, resolution.m_height, resolution.m_depth);
3471 }
3472 else
3473 {
3474 texture_width = resolution.m_width;
3475 texture_height = resolution.m_height;
3476
3477 for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
3478 {
3479 gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mipmap_level, texture_format.m_source.m_internal_format,
3480 texture_width, texture_height, resolution.m_depth, 0 /* border */,
3481 texture_format.m_source.m_format, texture_format.m_source.m_type, 0 /* data */);
3482
3483 texture_width = de::max(1, texture_width / 2);
3484 texture_height = de::max(1, texture_height / 2);
3485 }
3486 }
3487
3488 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to allocate storage for texture");
3489
3490 texture_width = resolution.m_width;
3491 texture_height = resolution.m_height;
3492
3493 for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
3494 {
3495 for (glw::GLint element_index = 0; element_index < n_elements; ++element_index)
3496 {
3497 for (glw::GLint face = 0; face < n_faces; ++face)
3498 {
3499 prepareTextureFace(gl, face, element_index, mipmap_level, n_elements, n_mipmap_levels,
3500 texture_format.m_source.m_format, texture_format.m_source.m_type, texture_width,
3501 texture_height);
3502 }
3503 }
3504
3505 texture_width = de::max(1, texture_width / 2);
3506 texture_height = de::max(1, texture_height / 2);
3507 }
3508
3509 // not texture filterable formats
3510 if ((texture_format.m_source.m_internal_format == GL_RGBA32UI) ||
3511 (texture_format.m_source.m_internal_format == GL_RGBA32I) ||
3512 (texture_format.m_source.m_internal_format == GL_STENCIL_INDEX8) ||
3513 (texture_format.m_source.m_internal_format == GL_DEPTH_COMPONENT32F))
3514 {
3515 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3516 gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3517 }
3518 }
3519
3520 /** Setup shader storabe buffer for use with compute shader
3521 *
3522 * @param attribute Attribute information
3523 * @param buffers Collection of buffers
3524 * @param program_id Program id
3525 **/
setupSharedStorageBuffer(const attributeDefinition & attribute,const bufferCollection & buffers,glw::GLuint program_id)3526 void TextureCubeMapArraySamplingTest::setupSharedStorageBuffer(const attributeDefinition& attribute,
3527 const bufferCollection& buffers, glw::GLuint program_id)
3528 {
3529 (void)program_id;
3530
3531 /* GL functions */
3532 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3533
3534 std::string attribute_name = attribute.name;
3535 const bufferDefinition* buffer = 0;
3536
3537 switch (attribute.attribute_id)
3538 {
3539 case Position:
3540 buffer = &buffers.postion;
3541 break;
3542 case TextureCoordinates:
3543 buffer = &buffers.texture_coordinate;
3544 break;
3545 case TextureCoordinatesForGather:
3546 buffer = &buffers.texture_coordinate_for_gather;
3547 break;
3548 case Lod:
3549 buffer = &buffers.lod;
3550 break;
3551 case GradX:
3552 buffer = &buffers.grad_x;
3553 break;
3554 case GradY:
3555 buffer = &buffers.grad_y;
3556 break;
3557 case RefZ:
3558 buffer = &buffers.refZ;
3559 break;
3560 }
3561
3562 buffer->bind(GL_SHADER_STORAGE_BUFFER, attribute.binding);
3563 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shared storage block");
3564 }
3565
3566 /** Setup shader storabe buffers for use with compute shader
3567 *
3568 * @param format Texture format
3569 * @param sampling_function Sampling routine
3570 * @param buffers Collection of buffers
3571 * @param program_id Program id
3572 **/
setupSharedStorageBuffers(const formatDefinition & format,const samplingFunction & sampling_function,const bufferCollection & buffers,glw::GLuint program_id)3573 void TextureCubeMapArraySamplingTest::setupSharedStorageBuffers(const formatDefinition& format,
3574 const samplingFunction& sampling_function,
3575 const bufferCollection& buffers, glw::GLuint program_id)
3576 {
3577 const attributeDefinition* format_attributes = 0;
3578 glw::GLuint n_format_attributes = 0;
3579 glw::GLuint n_routine_attributes = 0;
3580 const attributeDefinition* routine_attributes = 0;
3581
3582 getAttributes(format.m_sampler_type, format_attributes, n_format_attributes);
3583 getAttributes(sampling_function, routine_attributes, n_routine_attributes);
3584
3585 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
3586 {
3587 setupSharedStorageBuffer(routine_attributes[i], buffers, program_id);
3588 }
3589
3590 for (glw::GLuint i = 0; i < n_format_attributes; ++i)
3591 {
3592 setupSharedStorageBuffer(format_attributes[i], buffers, program_id);
3593 }
3594 }
3595
3596 /** Execute tests for set of formats and resolutions
3597 *
3598 * @param formats Set of texture formats
3599 * @param resolutions Set of texture resolutions
3600 **/
testFormats(formatsVectorType & formats,resolutionsVectorType & resolutions)3601 void TextureCubeMapArraySamplingTest::testFormats(formatsVectorType& formats, resolutionsVectorType& resolutions)
3602 {
3603 /* GL functions */
3604 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3605
3606 for (formatsVectorType::iterator format = formats.begin(), end_format = formats.end(); end_format != format;
3607 ++format)
3608 {
3609 shaderCollectionForTextureFormat shader_collection;
3610 programCollectionForFormat program_collection;
3611
3612 shader_collection.init(gl, *format, m_functions, *this);
3613 bool isContextES = (glu::isContextTypeES(m_context.getRenderContext().getType()));
3614 program_collection.init(gl, shader_collection, *this, isContextES);
3615
3616 for (mutablitiesVectorType::iterator mutability = m_mutabilities.begin(), end_muatbility = m_mutabilities.end();
3617 end_muatbility != mutability; ++mutability)
3618 {
3619 for (resolutionsVectorType::iterator resolution = resolutions.begin(), end_resolution = resolutions.end();
3620 end_resolution != resolution; ++resolution)
3621 {
3622 textureDefinition texture;
3623 texture.init(gl);
3624
3625 try
3626 {
3627 if (false == format->m_source.m_is_compressed)
3628 {
3629 prepareTexture(texture, *format, *resolution, *mutability);
3630 }
3631 else
3632 {
3633 prepareCompresedTexture(texture, *format, *resolution, *mutability);
3634 }
3635 }
3636 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
3637 catch (std::exception& exc)
3638 {
3639 m_testCtx.getLog() << tcu::TestLog::Section("Exception during texture creation", exc.what());
3640
3641 m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format->m_name
3642 << ", Mutability: " << *mutability << ", W: " << resolution->m_width
3643 << ", H: " << resolution->m_height << tcu::TestLog::EndMessage;
3644
3645 m_testCtx.getLog() << tcu::TestLog::EndSection;
3646 #else /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
3647 catch (...)
3648 {
3649 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
3650 continue;
3651 }
3652
3653 testTexture(*format, *mutability, *resolution, texture, program_collection);
3654 }
3655 }
3656 }
3657 }
3658
3659 /** Execute tests for given texture
3660 *
3661 * @param format Texture format
3662 * @param mutability Texture mutabilibty
3663 * @param resolution Texture resolution
3664 * @param texture Textue information
3665 * @param shader_collection Collection of shaders
3666 * @param program_collection Collection of programs
3667 **/
3668 void TextureCubeMapArraySamplingTest::testTexture(const formatDefinition& format, bool mutability,
3669 const resolutionDefinition& resolution, textureDefinition& texture,
3670 programCollectionForFormat& program_collection)
3671 {
3672 std::vector<unsigned char> result_image;
3673
3674 const glw::GLuint image_width = 3 * resolution.m_depth;
3675 const glw::GLuint image_height = 3;
3676 const glw::GLuint estimated_image_size =
3677 static_cast<glw::GLuint>(image_width * image_height * 4 /* components */ * sizeof(glw::GLuint));
3678
3679 result_image.resize(estimated_image_size);
3680
3681 /* GL functions */
3682 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3683
3684 bufferCollection buffers;
3685 buffers.init(gl, format, resolution);
3686
3687 for (samplingFunctionsVectorType::iterator function = m_functions.begin(), end_function = m_functions.end();
3688 end_function != function; ++function)
3689 {
3690 for (shadersVectorType::iterator shader = m_shaders.begin(), end_shader = m_shaders.end(); end_shader != shader;
3691 ++shader)
3692 {
3693 const programCollectionForFunction* programs = 0;
3694 const programDefinition* program = 0;
3695 glw::GLuint program_object_id = programDefinition::m_invalid_program_object_id;
3696 textureDefinition color_attachment;
3697
3698 programs = program_collection.getPrograms(function->m_function);
3699 program = programs->getProgram(shader->m_type);
3700 program_object_id = program->getProgramId();
3701
3702 if (programDefinition::m_invalid_program_object_id == program_object_id)
3703 {
3704 continue;
3705 }
3706
3707 tested_cases += 1;
3708
3709 color_attachment.init(gl);
3710
3711 if (Compute != shader->m_type)
3712 {
3713 setupFramebufferWithTextureAsAttachment(m_framebuffer_object_id, color_attachment.getTextureId(),
3714 format.m_destination.m_internal_format, image_width,
3715 image_height);
3716 }
3717 else
3718 {
3719 color_attachment.bind(GL_TEXTURE_2D);
3720 gl.texStorage2D(GL_TEXTURE_2D, 1, format.m_destination.m_internal_format, image_width, image_height);
3721 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3722 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3723 color_attachment.setupImage(0, format.m_destination.m_internal_format);
3724 }
3725
3726 try
3727 {
3728 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3729 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_object_id);
3730
3731 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
3732
3733 gl.useProgram(program_object_id);
3734
3735 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed glUseProgram call.");
3736
3737 texture.setupSampler(0, sampler_name, program_object_id, format.m_sampler_type == Depth);
3738
3739 if (Compute != shader->m_type)
3740 {
3741 vertexArrayObjectDefinition vao;
3742 vao.init(gl, format, function->m_function, buffers, program_object_id);
3743 draw(program_object_id, shader->m_primitive_type, image_width * image_height,
3744 format.m_destination.m_internal_format);
3745 }
3746 else
3747 {
3748 setupSharedStorageBuffers(format, function->m_function, buffers, program_object_id);
3749 dispatch(program_object_id, image_width, image_height);
3750 }
3751
3752 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3753 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_framebuffer_object_id);
3754
3755 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
3756
3757 color_attachment.bind(GL_TEXTURE_2D);
3758 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3759 color_attachment.getTextureId(), 0);
3760 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3761
3762 gl.viewport(0, 0, 3 * resolution.m_depth, 3);
3763 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
3764
3765 gl.memoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
3766 gl.readPixels(0 /* x */, 0 /* y */, image_width, image_height, format.m_destination.m_format,
3767 format.m_destination.m_type, &result_image[0]);
3768
3769 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3770
3771 /* GL_DEPTH_COMPONENT is nominally R32F, however R32F is not renderable, so we convert to
3772 * RGBA8 instead. Convert the red channel back to R32F for comparison.
3773 */
3774 if (format.m_source.m_format == GL_DEPTH_COMPONENT)
3775 {
3776 unsigned char* p = (unsigned char*)&result_image[0];
3777 float* f = (float*)&result_image[0];
3778
3779 for (unsigned int i = 0; i < image_width * image_height; i++)
3780 {
3781 *f = (float)p[0] / 255.0f;
3782 p += 4;
3783 f += 1;
3784 }
3785 }
3786
3787 /* GL_STENCIL_INDEX is nominally one-channel format, however ReadPixels supports only RGBA formats.
3788 * Convert the RGBA image to R for comparison.
3789 */
3790 if (format.m_source.m_format == GL_STENCIL_INDEX && format.m_destination.m_format == GL_RGBA_INTEGER)
3791 {
3792 unsigned int* pRGBA = (unsigned int*)&result_image[0];
3793 unsigned int* pR = (unsigned int*)&result_image[0];
3794 for (unsigned int i = 0; i < image_width * image_height; i++)
3795 {
3796 *pR = pRGBA[0];
3797 pR += 1;
3798 pRGBA += 4;
3799 }
3800 }
3801
3802 glw::GLuint get_type_api_status =
3803 checkUniformAndResourceApi(program_object_id, sampler_name, format.m_sampler_type);
3804 bool verification_result = verifyResult(format, resolution, function->m_function, &result_image[0]);
3805
3806 if ((true == verification_result) && (0 == get_type_api_status))
3807 {
3808 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG
3809 m_testCtx.getLog() << tcu::TestLog::Message << "Valid result. "
3810 << " Format: " << format.m_name << ", Mutability: " << mutability
3811 << ", Sampling shader: " << shader->m_name
3812 << ", Sampling function: " << function->m_name << ", W: " << resolution.m_width
3813 << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;
3814 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG
3815 logProgram(*program);
3816 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_PROGRAM_LOG */
3817 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_PASS_LOG */
3818 }
3819 else
3820 {
3821 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
3822 m_testCtx.getLog() << tcu::TestLog::Section("Invalid result", "");
3823
3824 if (true != verification_result)
3825 {
3826 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid image" << tcu::TestLog::EndMessage;
3827 }
3828
3829 if (0 != get_type_api_status)
3830 {
3831 if (0 != (m_get_type_api_status_uniform & get_type_api_status))
3832 {
3833 m_testCtx.getLog() << tcu::TestLog::Message
3834 << "glGetActiveUniform returns wrong type for sampler"
3835 << tcu::TestLog::EndMessage;
3836 }
3837
3838 if (0 != (m_get_type_api_status_program_resource & get_type_api_status))
3839 {
3840 m_testCtx.getLog() << tcu::TestLog::Message
3841 << "glGetProgramResourceiv returns wrong type for sampler"
3842 << tcu::TestLog::EndMessage;
3843 }
3844 }
3845
3846 m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format.m_name
3847 << ", Mutability: " << mutability << ", Sampling shader: " << shader->m_name
3848 << ", Sampling function: " << function->m_name << ", W: " << resolution.m_width
3849 << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;
3850
3851 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG
3852 logProgram(*program);
3853 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG */
3854
3855 m_testCtx.getLog() << tcu::TestLog::EndSection;
3856 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
3857
3858 if (false == verification_result)
3859 {
3860 failed_cases += 1;
3861 }
3862
3863 if (0 != get_type_api_status)
3864 {
3865 invalid_type_cases += 1;
3866 }
3867 }
3868 }
3869 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG
3870 catch (std::exception& exc)
3871 {
3872 m_testCtx.getLog() << tcu::TestLog::Section("Exception during test execution", exc.what());
3873
3874 m_testCtx.getLog() << tcu::TestLog::Message << "Format: " << format.m_name
3875 << ", Mutability: " << mutability << ", W: " << resolution.m_width
3876 << ", H: " << resolution.m_height << tcu::TestLog::EndMessage;
3877
3878 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG
3879 logProgram(*program);
3880 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_PROGRAM_LOG */
3881
3882 m_testCtx.getLog() << tcu::TestLog::EndSection;
3883 #else /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
3884 catch (...)
3885 {
3886 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_IS_FAIL_LOG */
3887
3888 failed_cases += 1;
3889 }
3890 //run()
3891 }
3892 }
3893 }
3894
3895 /** Verify that rendered image match expectations
3896 *
3897 * @param format Texture format
3898 * @param resolution Texture resolution
3899 * @param shader_type Shader type
3900 * @param sampling_function Type of sampling function
3901 * @param data Image data
3902 **/
3903 bool TextureCubeMapArraySamplingTest::verifyResult(const formatDefinition& format,
3904 const resolutionDefinition& resolution,
3905 const samplingFunction sampling_function, unsigned char* data)
3906 {
3907 componentProvider component_provider = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
3908
3909 switch (sampling_function)
3910 {
3911 case Texture:
3912 case TextureGather:
3913 component_provider.getColorFloatComponents = getExpectedColorFloatComponentsForTexture;
3914 component_provider.getColorUByteComponents = getExpectedColorIntComponentsForTexture<glw::GLubyte>;
3915 component_provider.getColorUintComponents = getExpectedColorIntComponentsForTexture<glw::GLuint>;
3916 component_provider.getColorIntComponents = getExpectedColorIntComponentsForTexture<glw::GLint>;
3917 component_provider.getDepthComponents = getExpectedDepthComponentsForTexture;
3918 component_provider.getStencilComponents = getExpectedStencilComponentsForTexture;
3919 component_provider.getCompressedComponents = getExpectedCompressedComponentsForTexture;
3920 break;
3921 case TextureLod:
3922 case TextureGrad:
3923 component_provider.getColorFloatComponents = getExpectedColorFloatComponentsForTextureLod;
3924 component_provider.getColorUByteComponents = getExpectedColorIntComponentsForTextureLod<glw::GLubyte>;
3925 component_provider.getColorUintComponents = getExpectedColorIntComponentsForTextureLod<glw::GLuint>;
3926 component_provider.getColorIntComponents = getExpectedColorIntComponentsForTextureLod<glw::GLint>;
3927 component_provider.getDepthComponents = getExpectedDepthComponentsForTextureLod;
3928 component_provider.getStencilComponents = getExpectedStencilComponentsForTextureLod;
3929 component_provider.getCompressedComponents = getExpectedCompressedComponentsForTextureLod;
3930 break;
3931 }
3932
3933 return verifyResultHelper(format, resolution, component_provider, data);
3934 }
3935
3936 /** Verify that rendered image match expectations
3937 *
3938 * @param format Texture format
3939 * @param resolution Texture resolution
3940 * @param shader_type Shader type
3941 * @param sampling_function Type of sampling function
3942 * @param data Image data
3943 **/
3944 bool TextureCubeMapArraySamplingTest::verifyResultHelper(const formatDefinition& format,
3945 const resolutionDefinition& resolution,
3946 const componentProvider& component_provider,
3947 unsigned char* data)
3948 {
3949 const glw::GLuint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
3950 const glw::GLuint n_layers = resolution.m_depth / 6;
3951
3952 bool result = false;
3953
3954 if (GL_RGBA == format.m_source.m_format)
3955 {
3956 if (GL_UNSIGNED_BYTE == format.m_source.m_type)
3957 {
3958 result = verifyResultImage<glw::GLubyte, 4, 3, 3>(n_mipmap_levels, n_layers,
3959 component_provider.getColorUByteComponents, data);
3960 }
3961 else if (GL_FLOAT == format.m_source.m_type)
3962 {
3963 result = verifyResultImage<glw::GLfloat, 4, 3, 3>(n_mipmap_levels, n_layers,
3964 component_provider.getColorFloatComponents, data);
3965 }
3966 else if (GL_COMPRESSED_RGBA8_ETC2_EAC == format.m_source.m_type)
3967 {
3968 result = verifyResultImage<glw::GLubyte, 4, 3, 3>(n_mipmap_levels, n_layers,
3969 component_provider.getCompressedComponents, data);
3970 }
3971 }
3972 else if (GL_RGBA_INTEGER == format.m_source.m_format)
3973 {
3974 if (GL_UNSIGNED_INT == format.m_source.m_type)
3975 {
3976 result = verifyResultImage<glw::GLuint, 4, 3, 3>(n_mipmap_levels, n_layers,
3977 component_provider.getColorUintComponents, data);
3978 }
3979 else if (GL_INT == format.m_source.m_type)
3980 {
3981 result = verifyResultImage<glw::GLint, 4, 3, 3>(n_mipmap_levels, n_layers,
3982 component_provider.getColorIntComponents, data);
3983 }
3984 }
3985 if (GL_DEPTH_COMPONENT == format.m_source.m_format)
3986 {
3987 if (GL_FLOAT == format.m_source.m_type)
3988 {
3989 result = verifyResultImage<glw::GLfloat, 1, 3, 3>(n_mipmap_levels, n_layers,
3990 component_provider.getDepthComponents, data);
3991 }
3992 }
3993 if (GL_STENCIL_INDEX == format.m_source.m_format)
3994 {
3995 if (GL_UNSIGNED_BYTE == format.m_source.m_type)
3996 {
3997 result = verifyResultImage<glw::GLuint, 1, 3, 3>(n_mipmap_levels, n_layers,
3998 component_provider.getStencilComponents, data);
3999 }
4000 }
4001
4002 return result;
4003 }
4004
4005 /****************************************************************************/
4006
4007 /** Initialize buffer collection
4008 *
4009 * @param gl GL functions
4010 * @param format Texture format
4011 * @param resolution Texture resolution
4012 **/
4013 void TextureCubeMapArraySamplingTest::bufferCollection::init(const glw::Functions& gl, const formatDefinition& format,
4014 const resolutionDefinition& resolution)
4015 {
4016 (void)format;
4017
4018 static const glw::GLuint n_faces = 6;
4019 static const glw::GLuint n_lods_components = 1;
4020 static const glw::GLuint n_grad_components = 4;
4021 static const glw::GLuint n_points_per_face = 9;
4022 static const glw::GLuint n_position_components = 4;
4023 static const glw::GLuint n_refZ_components = 1;
4024 static const glw::GLuint n_texture_coordinates_components = 4;
4025
4026 const glw::GLuint n_layers = resolution.m_depth / n_faces;
4027
4028 const glw::GLuint n_points_per_layer = n_points_per_face * n_faces;
4029 const glw::GLuint n_total_points = n_points_per_layer * n_layers;
4030
4031 const glw::GLuint n_position_step_per_face = n_position_components * n_points_per_face;
4032 const glw::GLuint n_texture_coordinates_step_per_face = n_texture_coordinates_components * n_points_per_face;
4033 const glw::GLuint n_lods_step_per_face = n_lods_components * n_points_per_face;
4034 const glw::GLuint n_grad_step_per_face = n_grad_components * n_points_per_face;
4035 const glw::GLuint n_refZ_step_per_face = n_refZ_components * n_points_per_face;
4036
4037 const glw::GLuint n_position_step_per_layer = n_faces * n_position_step_per_face;
4038 const glw::GLuint n_texture_coordinates_step_per_layer = n_faces * n_texture_coordinates_step_per_face;
4039 const glw::GLuint n_lods_step_per_layer = n_faces * n_lods_step_per_face;
4040 const glw::GLuint n_grad_step_per_layer = n_faces * n_grad_step_per_face;
4041 const glw::GLuint n_refZ_step_per_layer = n_faces * n_refZ_step_per_face;
4042
4043 const glw::GLuint texture_width = resolution.m_width;
4044 const glw::GLuint texture_height = resolution.m_height;
4045 const glw::GLuint n_mip_map_levels = getMipmapLevelCount(texture_width, texture_height);
4046
4047 std::vector<glw::GLfloat> position_buffer_data;
4048 std::vector<glw::GLfloat> texture_coordinate_buffer_data;
4049 std::vector<glw::GLfloat> texture_coordinate_for_gather_buffer_data;
4050 std::vector<glw::GLfloat> lod_buffer_data;
4051 std::vector<glw::GLfloat> grad_x_buffer_data;
4052 std::vector<glw::GLfloat> grad_y_buffer_data;
4053 std::vector<glw::GLfloat> refZ_buffer_data;
4054
4055 position_buffer_data.resize(n_total_points * n_position_components);
4056 texture_coordinate_buffer_data.resize(n_total_points * n_texture_coordinates_components);
4057 texture_coordinate_for_gather_buffer_data.resize(n_total_points * n_texture_coordinates_components);
4058 lod_buffer_data.resize(n_total_points * n_lods_components);
4059 grad_x_buffer_data.resize(n_total_points * n_grad_components);
4060 grad_y_buffer_data.resize(n_total_points * n_grad_components);
4061 refZ_buffer_data.resize(n_total_points * n_refZ_components);
4062
4063 /* Prepare data */
4064 for (glw::GLuint layer = 0; layer < n_layers; ++layer)
4065 {
4066 const glw::GLfloat layer_coordinate = (float)layer;
4067
4068 for (glw::GLuint face = 0; face < n_faces; ++face)
4069 {
4070 /* Offsets */
4071 const glw::GLuint position_offset = layer * n_position_step_per_layer + face * n_position_step_per_face;
4072 const glw::GLuint texture_coordinates_offset =
4073 layer * n_texture_coordinates_step_per_layer + face * n_texture_coordinates_step_per_face;
4074 const glw::GLuint lods_offset = layer * n_lods_step_per_layer + face * n_lods_step_per_face;
4075 const glw::GLuint grad_offset = layer * n_grad_step_per_layer + face * n_grad_step_per_face;
4076 const glw::GLuint refZ_offset = layer * n_refZ_step_per_layer + face * n_refZ_step_per_face;
4077
4078 /* Prepare data */
4079 preparePositionForFace(&position_buffer_data[0] + position_offset, face, layer, n_layers * n_faces);
4080 prepareTextureCoordinatesForFace(&texture_coordinate_buffer_data[0] + texture_coordinates_offset,
4081 texture_width, texture_height, layer_coordinate, face);
4082 prepareTextureCoordinatesForGatherForFace(&texture_coordinate_for_gather_buffer_data[0] +
4083 texture_coordinates_offset,
4084 texture_width, texture_height, layer_coordinate, face);
4085 prepareLodForFace(&lod_buffer_data[0] + lods_offset, n_mip_map_levels);
4086 prepareGradXForFace(&grad_x_buffer_data[0] + grad_offset, face,
4087 &texture_coordinate_buffer_data[0] + texture_coordinates_offset, texture_width);
4088 prepareGradYForFace(&grad_y_buffer_data[0] + grad_offset, face,
4089 &texture_coordinate_buffer_data[0] + texture_coordinates_offset, texture_width);
4090 prepareRefZForFace(&refZ_buffer_data[0] + refZ_offset, n_mip_map_levels, face, layer, n_layers);
4091 }
4092 }
4093
4094 /* Initialize buffers */
4095 postion.init(gl, (glw::GLsizeiptr)(position_buffer_data.size() * sizeof(glw::GLfloat)), &position_buffer_data[0]);
4096 texture_coordinate.init(gl, (glw::GLsizeiptr)(texture_coordinate_buffer_data.size() * sizeof(glw::GLfloat)),
4097 &texture_coordinate_buffer_data[0]);
4098 texture_coordinate_for_gather.init(
4099 gl, (glw::GLsizeiptr)(texture_coordinate_for_gather_buffer_data.size() * sizeof(glw::GLfloat)),
4100 &texture_coordinate_for_gather_buffer_data[0]);
4101 lod.init(gl, (glw::GLsizeiptr)(lod_buffer_data.size() * sizeof(glw::GLfloat)), &lod_buffer_data[0]);
4102 grad_x.init(gl, (glw::GLsizeiptr)(grad_x_buffer_data.size() * sizeof(glw::GLfloat)), &grad_x_buffer_data[0]);
4103 grad_y.init(gl, (glw::GLsizeiptr)(grad_y_buffer_data.size() * sizeof(glw::GLfloat)), &grad_y_buffer_data[0]);
4104 refZ.init(gl, (glw::GLsizeiptr)(refZ_buffer_data.size() * sizeof(glw::GLfloat)), &refZ_buffer_data[0]);
4105 }
4106
4107 /** Constructor.
4108 *
4109 **/
4110 TextureCubeMapArraySamplingTest::bufferDefinition::bufferDefinition()
4111 : m_gl(0), m_buffer_object_id(m_invalid_buffer_object_id)
4112 {
4113 }
4114
4115 /** Destructor
4116 *
4117 **/
4118 TextureCubeMapArraySamplingTest::bufferDefinition::~bufferDefinition()
4119 {
4120 if (m_invalid_buffer_object_id != m_buffer_object_id)
4121 {
4122 if (0 != m_gl)
4123 {
4124 m_gl->deleteBuffers(1, &m_buffer_object_id);
4125
4126 m_gl = 0;
4127 }
4128
4129 m_buffer_object_id = m_invalid_buffer_object_id;
4130 }
4131 }
4132
4133 /** Bind buffer
4134 *
4135 * @param target Target for bind
4136 **/
4137 void TextureCubeMapArraySamplingTest::bufferDefinition::bind(glw::GLenum target) const
4138 {
4139 if (m_invalid_buffer_object_id == m_buffer_object_id)
4140 {
4141 throw tcu::InternalError("Invalid buffer object id used", "", __FILE__, __LINE__);
4142 }
4143
4144 m_gl->bindBuffer(target, m_buffer_object_id);
4145 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");
4146 }
4147
4148 /** Bind buffer
4149 *
4150 * @param target Target for bind
4151 * @param index Index for target
4152 **/
4153 void TextureCubeMapArraySamplingTest::bufferDefinition::bind(glw::GLenum target, glw::GLuint index) const
4154 {
4155 if (m_invalid_buffer_object_id == m_buffer_object_id)
4156 {
4157 throw tcu::InternalError("Invalid buffer object id used", "", __FILE__, __LINE__);
4158 }
4159
4160 m_gl->bindBufferBase(target, index, m_buffer_object_id);
4161 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");
4162 }
4163
4164 /** Initialize buffer definition
4165 *
4166 * @param gl GL functions
4167 * @param buffer_size Size of buffer
4168 * @param buffer_data Buffer data
4169 **/
4170 void TextureCubeMapArraySamplingTest::bufferDefinition::init(const glw::Functions& gl, glw::GLsizeiptr buffer_size,
4171 glw::GLvoid* buffer_data)
4172 {
4173 m_gl = ≷
4174
4175 m_gl->genBuffers(1, &m_buffer_object_id);
4176 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to generate buffer.");
4177
4178 m_gl->bindBuffer(GL_ARRAY_BUFFER, m_buffer_object_id);
4179 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind buffer.");
4180
4181 m_gl->bufferData(GL_ARRAY_BUFFER, buffer_size, buffer_data, GL_STATIC_DRAW);
4182 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to update buffer's data.");
4183
4184 m_gl->bindBuffer(GL_ARRAY_BUFFER, 0);
4185 m_gl->getError();
4186 }
4187
4188 /** Constructor
4189 *
4190 * @param internal_format Internal format
4191 * @param format Format
4192 * @param type Type
4193 * @param is_compressed If format is compressed
4194 * @param sampler_type Type of sampler
4195 * @param name Name of format
4196 **/
4197 TextureCubeMapArraySamplingTest::formatDefinition::formatDefinition(glw::GLenum internal_format, glw::GLenum format,
4198 glw::GLenum type, bool is_compressed,
4199 samplerType sampler_type, const glw::GLchar* name)
4200 : m_source(internal_format, format, type, is_compressed)
4201 , m_destination(internal_format, format, type, false /* is_compressed*/)
4202 , m_sampler_type(sampler_type)
4203 , m_name(name)
4204 {
4205 }
4206
4207 /** Constructor
4208 *
4209 * @param src_internal_format Internal format of source image
4210 * @param src_format Format of source image
4211 * @param src_type Type of source image
4212 * @param src_is_compressed If format of source image is compressed
4213 * @param dst_internal_format Internal format of destination image
4214 * @param dst_format Format of destination image
4215 * @param dst_type Type of destination image
4216 * @param sampler_type Type of sampler
4217 * @param name Name of format
4218 **/
4219 TextureCubeMapArraySamplingTest::formatDefinition::formatDefinition(glw::GLenum src_internal_format,
4220 glw::GLenum src_format, glw::GLenum src_type,
4221 bool src_is_compressed,
4222 glw::GLenum dst_internal_format,
4223 glw::GLenum dst_format, glw::GLenum dst_type,
4224 samplerType sampler_type, const glw::GLchar* name)
4225 : m_source(src_internal_format, src_format, src_type, src_is_compressed)
4226 , m_destination(dst_internal_format, dst_format, dst_type, false /* is_compressed*/)
4227 , m_sampler_type(sampler_type)
4228 , m_name(name)
4229 {
4230 }
4231
4232 /** Constructor
4233 *
4234 * @param internal_format Internal format
4235 * @param format Format
4236 * @param type Type
4237 * @param is_compressed If format is compressed
4238 **/
4239 TextureCubeMapArraySamplingTest::formatInfo::formatInfo(glw::GLenum internal_format, glw::GLenum format,
4240 glw::GLenum type, bool is_compressed)
4241 : m_internal_format(internal_format), m_format(format), m_type(type), m_is_compressed(is_compressed)
4242 {
4243 }
4244
4245 /** Get collection of programs for sampling function
4246 *
4247 * @param function Type of sampling function
4248 *
4249 * @return Collection of programs for given sampling function
4250 **/
4251 const TextureCubeMapArraySamplingTest::programCollectionForFunction* TextureCubeMapArraySamplingTest::
4252 programCollectionForFormat::getPrograms(samplingFunction function) const
4253 {
4254 switch (function)
4255 {
4256 case Texture:
4257 return &m_programs_for_texture;
4258 break;
4259 case TextureLod:
4260 return &m_programs_for_textureLod;
4261 break;
4262 case TextureGrad:
4263 return &m_programs_for_textureGrad;
4264 break;
4265 case TextureGather:
4266 return &m_programs_for_textureGather;
4267 break;
4268 };
4269
4270 return 0;
4271 }
4272
4273 /** Initialize program collection for format
4274 *
4275 * @param gl GL functions
4276 * @param shader_collection Collection of shaders
4277 * @param test Instance of test class
4278 **/
4279 void TextureCubeMapArraySamplingTest::programCollectionForFormat::init(
4280 const glw::Functions& gl, const shaderCollectionForTextureFormat& shader_collection,
4281 TextureCubeMapArraySamplingTest& test, bool isContextES)
4282 {
4283 shaderGroup shader_group;
4284
4285 shader_collection.getShaderGroup(Texture, shader_group);
4286 m_programs_for_texture.init(gl, shader_group, test, isContextES);
4287
4288 shader_collection.getShaderGroup(TextureLod, shader_group);
4289 m_programs_for_textureLod.init(gl, shader_group, test, isContextES);
4290
4291 shader_collection.getShaderGroup(TextureGrad, shader_group);
4292 m_programs_for_textureGrad.init(gl, shader_group, test, isContextES);
4293
4294 shader_collection.getShaderGroup(TextureGather, shader_group);
4295 m_programs_for_textureGather.init(gl, shader_group, test, isContextES);
4296 }
4297
4298 /** Get program with specified sampling shader
4299 *
4300 * @param shader_type Type of shader
4301 *
4302 * @returns Program information
4303 **/
4304 const TextureCubeMapArraySamplingTest::programDefinition* TextureCubeMapArraySamplingTest::
4305 programCollectionForFunction::getProgram(shaderType shader_type) const
4306 {
4307 switch (shader_type)
4308 {
4309 case Compute:
4310 return &program_with_sampling_compute_shader;
4311 break;
4312 case Fragment:
4313 return &program_with_sampling_fragment_shader;
4314 break;
4315 case Geometry:
4316 return &program_with_sampling_geometry_shader;
4317 break;
4318 case Tesselation_Control:
4319 return &program_with_sampling_tesselation_control_shader;
4320 break;
4321 case Tesselation_Evaluation:
4322 return &program_with_sampling_tesselation_evaluation_shader;
4323 break;
4324 case Vertex:
4325 return &program_with_sampling_vertex_shader;
4326 break;
4327 }
4328
4329 return 0;
4330 }
4331
4332 /** Initialize program collection for sampling function
4333 *
4334 * @param gl GL functions
4335 * @param shader_group Group of shader compatible with sampling function
4336 * @param test Instance of test class
4337 **/
4338 void TextureCubeMapArraySamplingTest::programCollectionForFunction::init(const glw::Functions& gl,
4339 const shaderGroup& shader_group,
4340 TextureCubeMapArraySamplingTest& test,
4341 bool isContextES)
4342 {
4343 program_with_sampling_compute_shader.init(gl, shader_group, Compute, isContextES);
4344 program_with_sampling_fragment_shader.init(gl, shader_group, Fragment, isContextES);
4345 program_with_sampling_vertex_shader.init(gl, shader_group, Vertex, isContextES);
4346
4347 test.link(program_with_sampling_compute_shader);
4348 test.link(program_with_sampling_fragment_shader);
4349 test.link(program_with_sampling_vertex_shader);
4350
4351 if (test.m_is_geometry_shader_extension_supported)
4352 {
4353 program_with_sampling_geometry_shader.init(gl, shader_group, Geometry, isContextES);
4354 test.link(program_with_sampling_geometry_shader);
4355 }
4356
4357 if (test.m_is_tessellation_shader_supported)
4358 {
4359 program_with_sampling_tesselation_control_shader.init(gl, shader_group, Tesselation_Control, isContextES);
4360 program_with_sampling_tesselation_evaluation_shader.init(gl, shader_group, Tesselation_Evaluation, isContextES);
4361 test.link(program_with_sampling_tesselation_control_shader);
4362 test.link(program_with_sampling_tesselation_evaluation_shader);
4363 }
4364 }
4365
4366 /** Constructor
4367 *
4368 **/
4369 TextureCubeMapArraySamplingTest::programDefinition::programDefinition()
4370 : compute_shader(0)
4371 , geometry_shader(0)
4372 , fragment_shader(0)
4373 , tesselation_control_shader(0)
4374 , tesselation_evaluation_shader(0)
4375 , vertex_shader(0)
4376 , m_program_object_id(m_invalid_program_object_id)
4377 , m_gl(DE_NULL)
4378 {
4379 }
4380
4381 /** Destructor
4382 *
4383 **/
4384 TextureCubeMapArraySamplingTest::programDefinition::~programDefinition()
4385 {
4386 if (m_invalid_program_object_id != m_program_object_id)
4387 {
4388 if (0 != m_gl)
4389 {
4390 m_gl->deleteProgram(m_program_object_id);
4391 m_program_object_id = m_invalid_program_object_id;
4392 m_gl = 0;
4393 }
4394 }
4395 }
4396
4397 /** Get program id
4398 *
4399 * @returns Program id
4400 **/
4401 glw::GLuint TextureCubeMapArraySamplingTest::programDefinition::getProgramId() const
4402 {
4403 return m_program_object_id;
4404 }
4405
4406 /** Get shader
4407 *
4408 * @param shader_type Requested shader type
4409 *
4410 * @returns Pointer to shader information. Can be null.
4411 **/
4412 const TextureCubeMapArraySamplingTest::shaderDefinition* TextureCubeMapArraySamplingTest::programDefinition::getShader(
4413 shaderType shader_type) const
4414 {
4415 switch (shader_type)
4416 {
4417 case Compute:
4418 return compute_shader;
4419 break;
4420 case Fragment:
4421 return fragment_shader;
4422 break;
4423 case Geometry:
4424 return geometry_shader;
4425 break;
4426 case Tesselation_Control:
4427 return tesselation_control_shader;
4428 break;
4429 case Tesselation_Evaluation:
4430 return tesselation_evaluation_shader;
4431 break;
4432 case Vertex:
4433 return vertex_shader;
4434 break;
4435 }
4436
4437 return 0;
4438 }
4439
4440 /** Initialize program information
4441 *
4442 * @param gl GL functions
4443 * @param shader_group Group of shaders compatible with samplinbg function and texture format
4444 * @param shader_type Stage that will execute sampling
4445 **/
4446 void TextureCubeMapArraySamplingTest::programDefinition::init(const glw::Functions& gl, const shaderGroup& shader_group,
4447 shaderType shader_type, bool isContextES)
4448 {
4449 m_gl = ≷
4450
4451 bool is_program_defined = false;
4452
4453 switch (shader_type)
4454 {
4455 case Compute:
4456 compute_shader = shader_group.sampling_compute_shader;
4457 is_program_defined = (0 != compute_shader);
4458 break;
4459 case Fragment:
4460 fragment_shader = shader_group.sampling_fragment_shader;
4461 vertex_shader = shader_group.pass_through_vertex_shader;
4462 is_program_defined = ((0 != fragment_shader) && (0 != vertex_shader));
4463 break;
4464 case Geometry:
4465 fragment_shader = shader_group.pass_through_fragment_shader;
4466 geometry_shader = shader_group.sampling_geometry_shader;
4467 vertex_shader = shader_group.pass_through_vertex_shader;
4468 is_program_defined = ((0 != fragment_shader) && (0 != geometry_shader) && (0 != vertex_shader));
4469 break;
4470 case Tesselation_Control:
4471 fragment_shader = shader_group.pass_through_fragment_shader;
4472 tesselation_control_shader = shader_group.sampling_tesselation_control_shader;
4473 tesselation_evaluation_shader = shader_group.pass_through_tesselation_evaluation_shader;
4474 vertex_shader = shader_group.pass_through_vertex_shader;
4475 is_program_defined = ((0 != fragment_shader) && (0 != tesselation_control_shader) &&
4476 (0 != tesselation_evaluation_shader) && (0 != vertex_shader));
4477 break;
4478 case Tesselation_Evaluation:
4479 fragment_shader = shader_group.pass_through_fragment_shader;
4480 if (isContextES)
4481 {
4482 tesselation_control_shader = shader_group.pass_through_tesselation_control_shader;
4483 }
4484 tesselation_evaluation_shader = shader_group.sampling_tesselation_evaluation_shader;
4485 vertex_shader = shader_group.pass_through_vertex_shader;
4486 is_program_defined = ((0 != fragment_shader) && (0 != tesselation_control_shader) &&
4487 (0 != tesselation_evaluation_shader) && (0 != vertex_shader));
4488 break;
4489 case Vertex:
4490 fragment_shader = shader_group.pass_through_fragment_shader;
4491 vertex_shader = shader_group.sampling_vertex_shader;
4492 is_program_defined = ((0 != fragment_shader) && (0 != vertex_shader));
4493 break;
4494 }
4495
4496 if (true == is_program_defined)
4497 {
4498 m_program_object_id = m_gl->createProgram();
4499
4500 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create program");
4501
4502 if (m_invalid_program_object_id == m_program_object_id)
4503 {
4504 throw tcu::InternalError("glCreateProgram return invalid id", "", __FILE__, __LINE__);
4505 }
4506 }
4507 }
4508
4509 /** Link program
4510 *
4511 * @return true When linking was successful
4512 * false When linking failed
4513 **/
4514 bool TextureCubeMapArraySamplingTest::programDefinition::link()
4515 {
4516 if (m_invalid_program_object_id == m_program_object_id)
4517 {
4518 return false;
4519 }
4520
4521 if (0 != compute_shader)
4522 {
4523 compute_shader->attach(m_program_object_id);
4524 }
4525
4526 if (0 != geometry_shader)
4527 {
4528 geometry_shader->attach(m_program_object_id);
4529 }
4530
4531 if (0 != fragment_shader)
4532 {
4533 fragment_shader->attach(m_program_object_id);
4534 }
4535
4536 if (0 != tesselation_control_shader)
4537 {
4538 tesselation_control_shader->attach(m_program_object_id);
4539 }
4540
4541 if (0 != tesselation_evaluation_shader)
4542 {
4543 tesselation_evaluation_shader->attach(m_program_object_id);
4544 }
4545
4546 if (0 != vertex_shader)
4547 {
4548 vertex_shader->attach(m_program_object_id);
4549 }
4550
4551 /* Link Program */
4552 m_gl->linkProgram(m_program_object_id);
4553 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glLinkProgram() call failed.");
4554
4555 /* Check linking status */
4556 glw::GLint linkStatus = GL_FALSE;
4557 m_gl->getProgramiv(m_program_object_id, GL_LINK_STATUS, &linkStatus);
4558 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glGetProgramiv() call failed.");
4559
4560 if (linkStatus == GL_FALSE)
4561 {
4562 return false;
4563 }
4564
4565 return true;
4566 }
4567
4568 /** Constructor
4569 *
4570 * @param width Width
4571 * @param height Height
4572 * @param depth Depth
4573 **/
4574 TextureCubeMapArraySamplingTest::resolutionDefinition::resolutionDefinition(glw::GLuint width, glw::GLuint height,
4575 glw::GLuint depth)
4576 : m_width(width), m_height(height), m_depth(depth)
4577 {
4578 }
4579
4580 /** Constructor
4581 *
4582 * @param function Type of sampling function
4583 * @param name Name of sampling function
4584 **/
4585 TextureCubeMapArraySamplingTest::samplingFunctionDefinition::samplingFunctionDefinition(samplingFunction function,
4586 const glw::GLchar* name)
4587 : m_function(function), m_name(name)
4588 {
4589 }
4590
4591 /** Initialize shader collection for sampling function
4592 *
4593 * @param gl GL functions
4594 * @param format Texture format
4595 * @param sampling_function Sampling function
4596 * @param test Instance of test class
4597 **/
4598 void TextureCubeMapArraySamplingTest::shaderCollectionForSamplingRoutine::init(
4599 const glw::Functions& gl, const formatDefinition& format, const samplingFunction& sampling_function,
4600 TextureCubeMapArraySamplingTest& test)
4601 {
4602 m_sampling_function = sampling_function;
4603
4604 std::string pass_through_vertex_shader_source;
4605 std::string pass_through_tesselation_control_shader_source;
4606 std::string sampling_compute_shader_source;
4607 std::string sampling_fragment_shader_source;
4608 std::string sampling_geometry_shader_source;
4609 std::string sampling_tesselation_control_shader_source;
4610 std::string sampling_tesselation_evaluation_shader_source;
4611 std::string sampling_vertex_shader_source;
4612
4613 test.getPassThroughVertexShaderCode(format.m_sampler_type, m_sampling_function, pass_through_vertex_shader_source);
4614
4615 test.getPassThroughTesselationControlShaderCode(format.m_sampler_type, m_sampling_function,
4616 pass_through_tesselation_control_shader_source);
4617
4618 test.getSamplingComputeShaderCode(format.m_sampler_type, m_sampling_function, sampling_compute_shader_source);
4619
4620 test.getSamplingFragmentShaderCode(format.m_sampler_type, m_sampling_function, sampling_fragment_shader_source);
4621
4622 test.getSamplingGeometryShaderCode(format.m_sampler_type, m_sampling_function, sampling_geometry_shader_source);
4623
4624 test.getSamplingTesselationControlShaderCode(format.m_sampler_type, m_sampling_function,
4625 sampling_tesselation_control_shader_source);
4626
4627 test.getSamplingTesselationEvaluationShaderCode(format.m_sampler_type, m_sampling_function,
4628 sampling_tesselation_evaluation_shader_source);
4629
4630 test.getSamplingVertexShaderCode(format.m_sampler_type, m_sampling_function, sampling_vertex_shader_source);
4631
4632 pass_through_vertex_shader.init(gl, GL_VERTEX_SHADER, pass_through_vertex_shader_source, &test);
4633 sampling_compute_shader.init(gl, GL_COMPUTE_SHADER, sampling_compute_shader_source, &test);
4634 sampling_fragment_shader.init(gl, GL_FRAGMENT_SHADER, sampling_fragment_shader_source, &test);
4635 sampling_vertex_shader.init(gl, GL_VERTEX_SHADER, sampling_vertex_shader_source, &test);
4636
4637 test.compile(pass_through_vertex_shader);
4638 test.compile(sampling_compute_shader);
4639 test.compile(sampling_fragment_shader);
4640 test.compile(sampling_vertex_shader);
4641
4642 if (test.m_is_tessellation_shader_supported)
4643 {
4644 pass_through_tesselation_control_shader.init(gl, test.m_glExtTokens.TESS_CONTROL_SHADER,
4645 pass_through_tesselation_control_shader_source, &test);
4646 sampling_tesselation_control_shader.init(gl, test.m_glExtTokens.TESS_CONTROL_SHADER,
4647 sampling_tesselation_control_shader_source, &test);
4648 sampling_tesselation_evaluation_shader.init(gl, test.m_glExtTokens.TESS_EVALUATION_SHADER,
4649 sampling_tesselation_evaluation_shader_source, &test);
4650
4651 test.compile(pass_through_tesselation_control_shader);
4652 test.compile(sampling_tesselation_control_shader);
4653 test.compile(sampling_tesselation_evaluation_shader);
4654 }
4655
4656 if (test.m_is_geometry_shader_extension_supported)
4657 {
4658 sampling_geometry_shader.init(gl, test.m_glExtTokens.GEOMETRY_SHADER, sampling_geometry_shader_source, &test);
4659
4660 test.compile(sampling_geometry_shader);
4661 }
4662 }
4663
4664 /** Get group of shader compatible with sampling function and texture format
4665 *
4666 * @param function Sampling function
4667 * @param shader_group Group of shaders
4668 **/
4669 void TextureCubeMapArraySamplingTest::shaderCollectionForTextureFormat::getShaderGroup(samplingFunction function,
4670 shaderGroup& shader_group) const
4671 {
4672 shader_group.init();
4673
4674 for (shaderCollectionForSamplingFunctionVectorType::const_iterator it = per_sampling_routine.begin(),
4675 end = per_sampling_routine.end();
4676 end != it; ++it)
4677 {
4678 if (it->m_sampling_function == function)
4679 {
4680 shader_group.pass_through_fragment_shader = &pass_through_fragment_shader;
4681 shader_group.pass_through_tesselation_control_shader = &it->pass_through_tesselation_control_shader;
4682 shader_group.pass_through_tesselation_evaluation_shader = &pass_through_tesselation_evaluation_shader;
4683 shader_group.pass_through_vertex_shader = &it->pass_through_vertex_shader;
4684
4685 shader_group.sampling_compute_shader = &it->sampling_compute_shader;
4686 shader_group.sampling_fragment_shader = &it->sampling_fragment_shader;
4687 shader_group.sampling_geometry_shader = &it->sampling_geometry_shader;
4688 shader_group.sampling_tesselation_control_shader = &it->sampling_tesselation_control_shader;
4689 shader_group.sampling_tesselation_evaluation_shader = &it->sampling_tesselation_evaluation_shader;
4690 shader_group.sampling_vertex_shader = &it->sampling_vertex_shader;
4691
4692 return;
4693 }
4694 }
4695 }
4696
4697 /** Initialize shader collection for texture format
4698 *
4699 * @param gl GL functions
4700 * @param format Texture format
4701 * @param sampling_routines Set of sampling functions
4702 * @param test Instance of test class
4703 **/
4704 void TextureCubeMapArraySamplingTest::shaderCollectionForTextureFormat::init(
4705 const glw::Functions& gl, const formatDefinition& format, const samplingFunctionsVectorType& sampling_routines,
4706 TextureCubeMapArraySamplingTest& test)
4707 {
4708 std::string pass_through_fragment_shader_source;
4709 std::string pass_through_tesselation_evaluation_shader_source;
4710 glw::GLuint n_routines_supporting_format = 0;
4711
4712 test.getPassThroughFragmentShaderCode(format.m_sampler_type, pass_through_fragment_shader_source);
4713 test.getPassThroughTesselationEvaluationShaderCode(format.m_sampler_type,
4714 pass_through_tesselation_evaluation_shader_source);
4715
4716 pass_through_fragment_shader.init(gl, GL_FRAGMENT_SHADER, pass_through_fragment_shader_source, &test);
4717
4718 if (test.m_is_tessellation_shader_supported)
4719 {
4720 pass_through_tesselation_evaluation_shader.init(gl, test.m_glExtTokens.TESS_EVALUATION_SHADER,
4721 pass_through_tesselation_evaluation_shader_source, &test);
4722 }
4723
4724 test.compile(pass_through_fragment_shader);
4725
4726 if (test.m_is_tessellation_shader_supported)
4727 {
4728 test.compile(pass_through_tesselation_evaluation_shader);
4729 }
4730
4731 for (samplingFunctionsVectorType::const_iterator it = sampling_routines.begin(), end = sampling_routines.end();
4732 end != it; ++it)
4733 {
4734 if (TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(format.m_sampler_type, it->m_function))
4735 {
4736 n_routines_supporting_format += 1;
4737 }
4738 }
4739
4740 per_sampling_routine.resize(n_routines_supporting_format);
4741 shaderCollectionForSamplingFunctionVectorType::iterator jt = per_sampling_routine.begin();
4742
4743 for (samplingFunctionsVectorType::const_iterator it = sampling_routines.begin(), end = sampling_routines.end();
4744 end != it; ++it)
4745 {
4746 if (TextureCubeMapArraySamplingTest::isSamplerSupportedByFunction(format.m_sampler_type, it->m_function))
4747 {
4748 jt->init(gl, format, it->m_function, test);
4749 ++jt;
4750 }
4751 }
4752 }
4753
4754 /** Constructor
4755 *
4756 * @param type Type of shader
4757 * @param is_supported If configuration is supported
4758 * @param primitive_type Type of primitive
4759 * @param name Name of sampling shader stage
4760 **/
4761 TextureCubeMapArraySamplingTest::shaderConfiguration::shaderConfiguration(shaderType type, glw::GLenum primitive_type,
4762 const glw::GLchar* name)
4763 : m_type(type), m_primitive_type(primitive_type), m_name(name)
4764 {
4765 }
4766
4767 /** Constructor
4768 *
4769 **/
4770 TextureCubeMapArraySamplingTest::shaderDefinition::shaderDefinition()
4771 : m_gl(0), m_shader_stage(0), m_shader_object_id(m_invalid_shader_object_id)
4772 {
4773 }
4774
4775 /** Destructor
4776 *
4777 **/
4778 TextureCubeMapArraySamplingTest::shaderDefinition::~shaderDefinition()
4779 {
4780 if (m_invalid_shader_object_id != m_shader_object_id)
4781 {
4782 if (0 != m_gl)
4783 {
4784 m_gl->deleteShader(m_shader_object_id);
4785
4786 m_gl = 0;
4787 }
4788
4789 m_shader_object_id = m_invalid_shader_object_id;
4790 }
4791
4792 m_source.clear();
4793 }
4794
4795 /** Attach shade to program
4796 *
4797 * @parma program_object_id Progam id
4798 **/
4799 void TextureCubeMapArraySamplingTest::shaderDefinition::attach(glw::GLuint program_object_id) const
4800 {
4801 if (0 == m_gl)
4802 {
4803 throw tcu::InternalError("shaderDefinition not initialized", "", __FILE__, __LINE__);
4804 }
4805
4806 m_gl->attachShader(program_object_id, m_shader_object_id);
4807
4808 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glAttachShader() call failed.");
4809 }
4810
4811 /** Compile shader
4812 *
4813 * @returns true When successful
4814 * false When compilation failed
4815 **/
4816 bool TextureCubeMapArraySamplingTest::shaderDefinition::compile()
4817 {
4818 glw::GLint compile_status = GL_FALSE;
4819 const glw::GLchar* source = m_source.c_str();
4820
4821 /* Set shaders source */
4822 m_gl->shaderSource(m_shader_object_id, 1, &source, NULL);
4823
4824 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glShaderSource() call failed.");
4825
4826 /* Try to compile the shader */
4827 m_gl->compileShader(m_shader_object_id);
4828
4829 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glCompileShader() call failed.");
4830
4831 /* Check if all shaders compiled successfully */
4832 m_gl->getShaderiv(m_shader_object_id, GL_COMPILE_STATUS, &compile_status);
4833
4834 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glGetShaderiv() call failed.");
4835
4836 if (compile_status == GL_FALSE)
4837 {
4838 return false;
4839 }
4840
4841 return true;
4842 }
4843
4844 /** Get shader id
4845 *
4846 * @returns Shader id
4847 **/
4848 glw::GLuint TextureCubeMapArraySamplingTest::shaderDefinition::getShaderId() const
4849 {
4850 return m_shader_object_id;
4851 }
4852
4853 /** Get source
4854 *
4855 * @returns Code of shader
4856 **/
4857 const std::string& TextureCubeMapArraySamplingTest::shaderDefinition::getSource() const
4858 {
4859 return m_source;
4860 }
4861
4862 /** Initialize shader informations
4863 *
4864 * @param gl GL functions
4865 * @param shader_stage Stage of shader
4866 * @param source Source of shader
4867 **/
4868 void TextureCubeMapArraySamplingTest::shaderDefinition::init(const glw::Functions& gl, glw::GLenum shader_stage,
4869 const std::string& source,
4870 TextureCubeMapArraySamplingTest* test)
4871 {
4872 m_gl = ≷
4873 m_shader_stage = shader_stage;
4874 const glw::GLchar* source_cstr = source.c_str();
4875 m_source = test->specializeShader(1, &source_cstr);
4876
4877 if (m_invalid_shader_object_id == m_shader_object_id)
4878 {
4879 if (0 != m_gl)
4880 {
4881 m_shader_object_id = m_gl->createShader(m_shader_stage);
4882
4883 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shader");
4884
4885 if (m_invalid_shader_object_id == m_shader_object_id)
4886 {
4887 throw tcu::InternalError("glCreateShader returned invalid id", "", __FILE__, __LINE__);
4888 }
4889 }
4890 }
4891 }
4892
4893 /** Initialize shader group
4894 *
4895 **/
4896 void TextureCubeMapArraySamplingTest::shaderGroup::init()
4897 {
4898 pass_through_fragment_shader = 0;
4899 pass_through_tesselation_control_shader = 0;
4900 pass_through_tesselation_evaluation_shader = 0;
4901 pass_through_vertex_shader = 0;
4902 sampling_compute_shader = 0;
4903 sampling_fragment_shader = 0;
4904 sampling_geometry_shader = 0;
4905 sampling_tesselation_control_shader = 0;
4906 sampling_tesselation_evaluation_shader = 0;
4907 sampling_vertex_shader = 0;
4908 }
4909
4910 /** Constructor
4911 *
4912 **/
4913 TextureCubeMapArraySamplingTest::textureDefinition::textureDefinition()
4914 : m_gl(0), m_texture_object_id(m_invalid_texture_object_id)
4915 {
4916 }
4917
4918 /** Destructor
4919 *
4920 **/
4921 TextureCubeMapArraySamplingTest::textureDefinition::~textureDefinition()
4922 {
4923 if (m_invalid_texture_object_id != m_texture_object_id)
4924 {
4925 if (0 != m_gl)
4926 {
4927 m_gl->deleteTextures(1, &m_texture_object_id);
4928
4929 m_gl = 0;
4930 }
4931
4932 m_texture_object_id = m_invalid_texture_object_id;
4933 }
4934 }
4935
4936 /** Bind texture
4937 *
4938 * @param binding_point Where texture will be bound
4939 **/
4940 void TextureCubeMapArraySamplingTest::textureDefinition::bind(glw::GLenum binding_point) const
4941 {
4942 if (0 == m_gl)
4943 {
4944 throw tcu::InternalError("TextureDefinition not initialized", "", __FILE__, __LINE__);
4945 }
4946
4947 m_gl->bindTexture(binding_point, m_texture_object_id);
4948 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind texture");
4949 }
4950
4951 /** Get texture id
4952 *
4953 * @returns Texture id
4954 **/
4955 glw::GLuint TextureCubeMapArraySamplingTest::textureDefinition::getTextureId() const
4956 {
4957 return m_texture_object_id;
4958 }
4959
4960 /** Initialize texture information
4961 *
4962 * @param gl GL functions
4963 * @param bind_image Address of glBindImageTexture procedure
4964 **/
4965 void TextureCubeMapArraySamplingTest::textureDefinition::init(const glw::Functions& gl)
4966 {
4967 m_gl = ≷
4968
4969 gl.genTextures(1, &m_texture_object_id);
4970 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to generate texture");
4971 }
4972
4973 /** Set texture as image
4974 *
4975 * @param image_unit Index of image unit
4976 * @param internal_format Format for image unit
4977 **/
4978 void TextureCubeMapArraySamplingTest::textureDefinition::setupImage(glw::GLuint image_unit, glw::GLenum internal_format)
4979 {
4980 if ((0 == m_gl) || (m_invalid_texture_object_id == m_texture_object_id))
4981 {
4982 throw tcu::InternalError("Not initialized textureDefinition", "", __FILE__, __LINE__);
4983 }
4984
4985 m_gl->bindImageTexture(image_unit, m_texture_object_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, internal_format);
4986
4987 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glBindImageTexture");
4988 }
4989
4990 /** Setup texture unit with this
4991 *
4992 * @param texture_unit Index of texture unit
4993 * @param sampler_name_p Name of sampler uniform
4994 * @param program_id Program id
4995 * @param is_shadow If depth comparison should be enabled
4996 **/
4997 void TextureCubeMapArraySamplingTest::textureDefinition::setupSampler(glw::GLuint texture_unit,
4998 const glw::GLchar* sampler_name_p,
4999 glw::GLuint program_id, bool is_shadow)
5000 {
5001 if ((0 == m_gl) || (m_invalid_texture_object_id == m_texture_object_id))
5002 {
5003 throw tcu::InternalError("Not initialized textureDefinition", "", __FILE__, __LINE__);
5004 }
5005
5006 glw::GLint sampler_location = m_gl->getUniformLocation(program_id, sampler_name_p);
5007 if ((m_invalid_uniform_location == (glw::GLuint)sampler_location) || (GL_NO_ERROR != m_gl->getError()))
5008 {
5009 //throw tcu::InternalError("Failed to get sampler location", sampler_name_p, __FILE__, __LINE__);
5010 return;
5011 }
5012
5013 m_gl->activeTexture(GL_TEXTURE0 + texture_unit);
5014 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to activate texture unit");
5015
5016 m_gl->bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_texture_object_id);
5017 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind texture to GL_TEXTURE_CUBE_MAP_ARRAY_EXT");
5018
5019 if (true == is_shadow)
5020 {
5021 m_gl->texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
5022 m_gl->texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
5023 }
5024
5025 m_gl->uniform1i(sampler_location, texture_unit);
5026 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to set sampler uniform");
5027 }
5028
5029 /** Constructor
5030 *
5031 **/
5032 TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::vertexArrayObjectDefinition()
5033 : m_gl(0), m_vertex_array_object_id(m_invalid_vertex_array_object_id)
5034 {
5035 }
5036
5037 /** Destructor
5038 *
5039 **/
5040 TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::~vertexArrayObjectDefinition()
5041 {
5042 if (m_invalid_vertex_array_object_id != m_vertex_array_object_id)
5043 {
5044 if (0 != m_gl)
5045 {
5046 m_gl->deleteVertexArrays(1, &m_vertex_array_object_id);
5047
5048 m_gl = 0;
5049 }
5050
5051 m_vertex_array_object_id = m_invalid_vertex_array_object_id;
5052 }
5053 }
5054
5055 /** Initialize vertex array object
5056 *
5057 * @param gl GL functions
5058 * @param format Texture format
5059 * @param sampling_function Type of sampling function
5060 * @param buffers Buffer collection
5061 * @param program_id Program id
5062 **/
5063 void TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::init(const glw::Functions& gl,
5064 const formatDefinition& format,
5065 const samplingFunction& sampling_function,
5066 const bufferCollection& buffers,
5067 glw::GLuint program_id)
5068 {
5069 m_gl = ≷
5070
5071 m_gl->genVertexArrays(1, &m_vertex_array_object_id);
5072 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to generate VAO.");
5073
5074 m_gl->bindVertexArray(m_vertex_array_object_id);
5075 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to bind VAO.");
5076
5077 attributeDefinition positionAttribute = { vertex_shader_position, type_vec4, Position, 0 };
5078 const attributeDefinition* format_attributes;
5079 glw::GLuint n_format_attributes;
5080 const attributeDefinition* routine_attributes = 0;
5081 glw::GLuint n_routine_attributes = 0;
5082
5083 getAttributes(format.m_sampler_type, format_attributes, n_format_attributes);
5084 getAttributes(sampling_function, routine_attributes, n_routine_attributes);
5085
5086 setupAttribute(positionAttribute, buffers, program_id);
5087
5088 for (glw::GLuint i = 0; i < n_routine_attributes; ++i)
5089 {
5090 setupAttribute(routine_attributes[i], buffers, program_id);
5091 }
5092
5093 for (glw::GLuint i = 0; i < n_format_attributes; ++i)
5094 {
5095 setupAttribute(format_attributes[i], buffers, program_id);
5096 }
5097 }
5098
5099 /** Setup vertex array object
5100 *
5101 * @param attribute Attribute information
5102 * @param buffers Buffer collection
5103 * @param program_id Program id
5104 **/
5105 void TextureCubeMapArraySamplingTest::vertexArrayObjectDefinition::setupAttribute(const attributeDefinition& attribute,
5106 const bufferCollection& buffers,
5107 glw::GLuint program_id)
5108 {
5109 std::string attribute_name = vertex_shader_input;
5110 const bufferDefinition* buffer = 0;
5111 glw::GLuint n_components = 0;
5112 glw::GLenum type = GL_FLOAT;
5113
5114 attribute_name.append(attribute.name);
5115
5116 switch (attribute.attribute_id)
5117 {
5118 case Position:
5119 n_components = 4;
5120 buffer = &buffers.postion;
5121 break;
5122 case TextureCoordinates:
5123 n_components = 4;
5124 buffer = &buffers.texture_coordinate;
5125 break;
5126 case TextureCoordinatesForGather:
5127 n_components = 4;
5128 buffer = &buffers.texture_coordinate_for_gather;
5129 break;
5130 case Lod:
5131 n_components = 1;
5132 buffer = &buffers.lod;
5133 break;
5134 case GradX:
5135 n_components = 4;
5136 buffer = &buffers.grad_x;
5137 break;
5138 case GradY:
5139 n_components = 4;
5140 buffer = &buffers.grad_y;
5141 break;
5142 case RefZ:
5143 n_components = 1;
5144 buffer = &buffers.refZ;
5145 break;
5146 }
5147
5148 /* Get attribute location */
5149 glw::GLint attribute_location = m_gl->getAttribLocation(program_id, attribute_name.c_str());
5150
5151 if ((m_invalid_attribute_location == (glw::GLuint)attribute_location) || (GL_NO_ERROR != m_gl->getError()))
5152 {
5153 //throw tcu::InternalError("Failed to get location of attribute:", attribute_name.c_str(), __FILE__, __LINE__);
5154 return;
5155 }
5156
5157 buffer->bind(GL_ARRAY_BUFFER);
5158
5159 m_gl->enableVertexAttribArray(attribute_location);
5160 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to enable attribute");
5161
5162 m_gl->vertexAttribPointer(attribute_location, n_components, type, GL_FALSE, 0 /* stride */, 0 /* offset */);
5163
5164 GLU_EXPECT_NO_ERROR(m_gl->getError(), "Failed to setup vertex attribute arrays");
5165 }
5166
5167 #if TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION
5168 /** Get file name for given face
5169 * Such pattern is used: texture_cube_map_array_sampling_test_w_WIDTH_h_HEIGHT_l_LEVEL_i_INDEX_f_FACE
5170 *
5171 * @param width Width of texture
5172 * @param height Height of texture
5173 * @param level Mipmap level
5174 * @param index Index of element in array
5175 * @param face Cube map's face index
5176 * @param name File name
5177 **/
5178 void getTextureFileName(glw::GLuint width, glw::GLuint height, glw::GLuint level, glw::GLuint index, glw::GLuint face,
5179 std::string& name)
5180 {
5181 std::stringstream file_name;
5182
5183 file_name << TEXTURECUBEMAPARRAYSAMPLINGTEST_PATH_FOR_COMPRESSION;
5184
5185 file_name << "texture_cube_map_array_sampling_test_"
5186 << "w_" << width << "_h_" << height << "_l_" << level << "_i_" << index << "_f_" << face;
5187
5188 name = file_name.str();
5189 }
5190
5191 /** Store whole cube map as TGA files. Each face is stored as separate image.
5192 *
5193 * @param resolution Resolution of base level
5194 **/
5195 void prepareDumpForTextureCompression(const TextureCubeMapArraySamplingTest::resolutionDefinition& resolution)
5196 {
5197 glw::GLsizei texture_width = resolution.m_width;
5198 glw::GLsizei texture_height = resolution.m_height;
5199
5200 const glw::GLuint n_components = 4;
5201 const glw::GLuint n_faces = 6;
5202 const glw::GLint n_array_elements = resolution.m_depth / n_faces;
5203 const glw::GLint n_mipmap_levels = getMipmapLevelCount(resolution.m_width, resolution.m_height);
5204
5205 const unsigned char tga_id_length = 0; // no id
5206 const unsigned char tga_color_map_type = 0; // no color map
5207 const unsigned char tga_image_type = 2; // rgb no compression
5208 const unsigned short tga_color_map_offset = 0; // no color map
5209 const unsigned short tga_color_map_length = 0; // no color map
5210 const unsigned char tga_color_map_bits_per_pixel = 0; // no color map
5211 const unsigned short tga_image_x = 0;
5212 const unsigned short tga_image_y = 0;
5213 const unsigned char tga_image_bits_per_pixel = 32;
5214 const unsigned char tga_image_descriptor = 0x8; // 8 per alpha
5215
5216 for (glw::GLint mipmap_level = 0; mipmap_level < n_mipmap_levels; ++mipmap_level)
5217 {
5218 const unsigned short tga_image_width = texture_width;
5219 const unsigned short tga_image_height = texture_height;
5220
5221 for (glw::GLint array_index = 0; array_index < n_array_elements; ++array_index)
5222 {
5223 for (glw::GLint face = 0; face < n_faces; ++face)
5224 {
5225 std::fstream file;
5226 std::string file_name;
5227 getTextureFileName(resolution.m_width, resolution.m_height, mipmap_level, array_index, face, file_name);
5228 file_name.append(".tga");
5229
5230 file.open(file_name.c_str(), std::fstream::out | std::fstream::binary);
5231
5232 file.write((const char*)&tga_id_length, sizeof(tga_id_length));
5233 file.write((const char*)&tga_color_map_type, sizeof(tga_color_map_type));
5234 file.write((const char*)&tga_image_type, sizeof(tga_image_type));
5235 file.write((const char*)&tga_color_map_offset, sizeof(tga_color_map_offset));
5236 file.write((const char*)&tga_color_map_length, sizeof(tga_color_map_length));
5237 file.write((const char*)&tga_color_map_bits_per_pixel, sizeof(tga_color_map_bits_per_pixel));
5238 file.write((const char*)&tga_image_x, sizeof(tga_image_x));
5239 file.write((const char*)&tga_image_y, sizeof(tga_image_y));
5240 file.write((const char*)&tga_image_width, sizeof(tga_image_width));
5241 file.write((const char*)&tga_image_height, sizeof(tga_image_height));
5242 file.write((const char*)&tga_image_bits_per_pixel, sizeof(tga_image_bits_per_pixel));
5243 file.write((const char*)&tga_image_descriptor, sizeof(tga_image_descriptor));
5244
5245 glw::GLubyte components[n_components];
5246
5247 getCompressedColorUByteComponents(face, array_index, mipmap_level, n_array_elements, n_mipmap_levels,
5248 components);
5249
5250 for (glw::GLuint y = 0; y < texture_height; ++y)
5251 {
5252 for (glw::GLuint x = 0; x < texture_width; ++x)
5253 {
5254 for (glw::GLuint i = 0; i < n_components; ++i)
5255 {
5256 file.write((const char*)&components[i], sizeof(glw::GLubyte));
5257 }
5258 }
5259 }
5260 }
5261 }
5262
5263 texture_width = de::max(1, texture_width / 2);
5264 texture_height = de::max(1, texture_height / 2);
5265 }
5266 }
5267
5268 #endif /* TEXTURECUBEMAPARRAYSAMPLINGTEST_DUMP_TEXTURES_FOR_COMPRESSION */
5269
5270 } /* glcts */
5271