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