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