1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
25 * \file gl4cTextureViewTests.cpp
26 * \brief Implements conformance tests for "texture view" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "gl4cTextureViewTests.hpp"
30 #include "deFloat16.h"
32 #include "gluContextInfo.hpp"
33 #include "glwFunctions.hpp"
34 #include "tcuFloat.hpp"
35 #include "tcuTestLog.hpp"
38 /* Type definitions needed to handle GL_R11F_G11F_B10F internal format */
39 typedef tcu::Float<deUint32, 5, 5, 15, 0> Float10;
40 typedef tcu::Float<deUint32, 5, 6, 15, 0> Float11;
44 using namespace TextureView;
46 /** Stores internalformat->view class associations */
47 const int internalformat_view_compatibility_array[] = {
48 /* [internalformat] [view class] */
49 GL_RGBA32F, VIEW_CLASS_128_BITS, GL_RGBA32UI, VIEW_CLASS_128_BITS, GL_RGBA32I, VIEW_CLASS_128_BITS, GL_RGB32F,
50 VIEW_CLASS_96_BITS, GL_RGB32UI, VIEW_CLASS_96_BITS, GL_RGB32I, VIEW_CLASS_96_BITS, GL_RGBA16F, VIEW_CLASS_64_BITS,
51 GL_RG32F, VIEW_CLASS_64_BITS, GL_RGBA16UI, VIEW_CLASS_64_BITS, GL_RG32UI, VIEW_CLASS_64_BITS, GL_RGBA16I,
52 VIEW_CLASS_64_BITS, GL_RG32I, VIEW_CLASS_64_BITS, GL_RGBA16, VIEW_CLASS_64_BITS, GL_RGBA16_SNORM,
53 VIEW_CLASS_64_BITS, GL_RGB16, VIEW_CLASS_48_BITS, GL_RGB16_SNORM, VIEW_CLASS_48_BITS, GL_RGB16F, VIEW_CLASS_48_BITS,
54 GL_RGB16UI, VIEW_CLASS_48_BITS, GL_RGB16I, VIEW_CLASS_48_BITS, GL_RG16F, VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F,
55 VIEW_CLASS_32_BITS, GL_R32F, VIEW_CLASS_32_BITS, GL_RGB10_A2UI, VIEW_CLASS_32_BITS, GL_RGBA8UI, VIEW_CLASS_32_BITS,
56 GL_RG16UI, VIEW_CLASS_32_BITS, GL_R32UI, VIEW_CLASS_32_BITS, GL_RGBA8I, VIEW_CLASS_32_BITS, GL_RG16I,
57 VIEW_CLASS_32_BITS, GL_R32I, VIEW_CLASS_32_BITS, GL_RGB10_A2, VIEW_CLASS_32_BITS, GL_RGBA8, VIEW_CLASS_32_BITS,
58 GL_RG16, VIEW_CLASS_32_BITS, GL_RGBA8_SNORM, VIEW_CLASS_32_BITS, GL_RG16_SNORM, VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8,
59 VIEW_CLASS_32_BITS, GL_RGB9_E5, VIEW_CLASS_32_BITS, GL_RGB8, VIEW_CLASS_24_BITS, GL_RGB8_SNORM, VIEW_CLASS_24_BITS,
60 GL_SRGB8, VIEW_CLASS_24_BITS, GL_RGB8UI, VIEW_CLASS_24_BITS, GL_RGB8I, VIEW_CLASS_24_BITS, GL_R16F,
61 VIEW_CLASS_16_BITS, GL_RG8UI, VIEW_CLASS_16_BITS, GL_R16UI, VIEW_CLASS_16_BITS, GL_RG8I, VIEW_CLASS_16_BITS,
62 GL_R16I, VIEW_CLASS_16_BITS, GL_RG8, VIEW_CLASS_16_BITS, GL_R16, VIEW_CLASS_16_BITS, GL_RG8_SNORM,
63 VIEW_CLASS_16_BITS, GL_R16_SNORM, VIEW_CLASS_16_BITS, GL_R8UI, VIEW_CLASS_8_BITS, GL_R8I, VIEW_CLASS_8_BITS, GL_R8,
64 VIEW_CLASS_8_BITS, GL_R8_SNORM, VIEW_CLASS_8_BITS,
66 /* Compressed texture formats. */
67 GL_COMPRESSED_RED_RGTC1, VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1, VIEW_CLASS_RGTC1_RED,
68 GL_COMPRESSED_RG_RGTC2, VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2, VIEW_CLASS_RGTC2_RG,
69 GL_COMPRESSED_RGBA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, VIEW_CLASS_BPTC_UNORM,
70 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
74 const int n_internalformat_view_compatibility_array_entries =
75 sizeof(internalformat_view_compatibility_array) / sizeof(internalformat_view_compatibility_array[0]);
77 /** Stores all internalformats valid in OpenGL 4.x. Information whether particular internalformat
78 * can be considered supported can be retrieved by calling TextureViewTests::isInternalformatSupported()
81 const glw::GLenum valid_gl_internalformats[] = {
83 GL_RGBA32F, /* >= GL 4.0 */
84 GL_RGBA32I, /* >= GL 4.0 */
85 GL_RGBA32UI, /* >= GL 4.0 */
86 GL_RGBA16, /* >= GL 4.0 */
87 GL_RGBA16F, /* >= GL 4.0 */
88 GL_RGBA16I, /* >= GL 4.0 */
89 GL_RGBA16UI, /* >= GL 4.0 */
90 GL_RGBA8, /* >= GL 4.0 */
91 GL_RGBA8I, /* >= GL 4.0 */
92 GL_RGBA8UI, /* >= GL 4.0 */
93 GL_SRGB8_ALPHA8, /* >= GL 4.0 */
94 GL_RGB10_A2, /* >= GL 4.0 */
95 GL_RGB10_A2UI, /* >= GL 4.0 */
96 GL_RGB5_A1, /* >= GL 4.0 */
97 GL_RGBA4, /* >= GL 4.0 */
98 GL_R11F_G11F_B10F, /* >= GL 4.0 */
99 GL_RGB565, /* >= GL 4.2 */
100 GL_RG32F, /* >= GL 4.0 */
101 GL_RG32I, /* >= GL 4.0 */
102 GL_RG32UI, /* >= GL 4.0 */
103 GL_RG16, /* >= GL 4.0 */
104 GL_RG16F, /* >= GL 4.0 */
105 GL_RG16I, /* >= GL 4.0 */
106 GL_RG16UI, /* >= GL 4.0 */
107 GL_RG8, /* >= GL 4.0 */
108 GL_RG8I, /* >= GL 4.0 */
109 GL_RG8UI, /* >= GL 4.0 */
110 GL_R32F, /* >= GL 4.0 */
111 GL_R32I, /* >= GL 4.0 */
112 GL_R32UI, /* >= GL 4.0 */
113 GL_R16F, /* >= GL 4.0 */
114 GL_R16I, /* >= GL 4.0 */
115 GL_R16UI, /* >= GL 4.0 */
116 GL_R16, /* >= GL 4.0 */
117 GL_R8, /* >= GL 4.0 */
118 GL_R8I, /* >= GL 4.0 */
119 GL_R8UI, /* >= GL 4.0 */
120 GL_RGBA16_SNORM, /* >= GL 4.0 */
121 GL_RGBA8_SNORM, /* >= GL 4.0 */
122 GL_RGB32F, /* >= GL 4.0 */
123 GL_RGB32I, /* >= GL 4.0 */
124 GL_RGB32UI, /* >= GL 4.0 */
125 GL_RGB16_SNORM, /* >= GL 4.0 */
126 GL_RGB16F, /* >= GL 4.0 */
127 GL_RGB16I, /* >= GL 4.0 */
128 GL_RGB16UI, /* >= GL 4.0 */
129 GL_RGB16, /* >= GL 4.0 */
130 GL_RGB8_SNORM, /* >= GL 4.0 */
131 GL_RGB8, /* >= GL 4.0 */
132 GL_RGB8I, /* >= GL 4.0 */
133 GL_RGB8UI, /* >= GL 4.0 */
134 GL_SRGB8, /* >= GL 4.0 */
135 GL_RGB9_E5, /* >= GL 4.0 */
136 GL_RG16_SNORM, /* >= GL 4.0 */
137 GL_RG8_SNORM, /* >= GL 4.0 */
138 GL_R16_SNORM, /* >= GL 4.0 */
139 GL_R8_SNORM, /* >= GL 4.0 */
141 GL_DEPTH_COMPONENT32F, /* >= GL 4.0 */
142 GL_DEPTH_COMPONENT24, /* >= GL 4.0 */
143 GL_DEPTH_COMPONENT16, /* >= GL 4.0 */
145 GL_DEPTH32F_STENCIL8, /* >= GL 4.0 */
146 GL_DEPTH24_STENCIL8, /* >= GL 4.0 */
148 /* Table 8.14: generic compressed internalformats have been removed */
149 GL_COMPRESSED_RED_RGTC1, /* >= GL 4.0 */
150 GL_COMPRESSED_SIGNED_RED_RGTC1, /* >= GL 4.0 */
151 GL_COMPRESSED_RG_RGTC2, /* >= GL 4.0 */
152 GL_COMPRESSED_SIGNED_RG_RGTC2, /* >= GL 4.0 */
153 GL_COMPRESSED_RGBA_BPTC_UNORM, /* >= GL 4.2 */
154 GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, /* >= GL 4.2 */
155 GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, /* >= GL 4.2 */
156 GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, /* >= GL 4.2 */
157 GL_COMPRESSED_RGB8_ETC2, /* >= GL 4.3 */
158 GL_COMPRESSED_SRGB8_ETC2, /* >= GL 4.3 */
159 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */
160 GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, /* >= GL 4.3 */
161 GL_COMPRESSED_RGBA8_ETC2_EAC, /* >= GL 4.3 */
162 GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, /* >= GL 4.3 */
163 GL_COMPRESSED_R11_EAC, /* >= GL 4.3 */
164 GL_COMPRESSED_SIGNED_R11_EAC, /* >= GL 4.3 */
165 GL_COMPRESSED_RG11_EAC, /* >= GL 4.3 */
166 GL_COMPRESSED_SIGNED_RG11_EAC, /* >= GL 4.3 */
169 const int n_valid_gl_internalformats = sizeof(valid_gl_internalformats) / sizeof(valid_gl_internalformats[0]);
171 /** An array of texture targets that is used by a number of TextureViewUtilities methods. */
172 static glw::GLenum valid_texture_targets[] = { GL_TEXTURE_1D,
176 GL_TEXTURE_2D_MULTISAMPLE,
177 GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
181 GL_TEXTURE_CUBE_MAP_ARRAY,
182 GL_TEXTURE_RECTANGLE };
183 const unsigned int n_valid_texture_targets = sizeof(valid_texture_targets) / sizeof(valid_texture_targets[0]);
185 /** Retrieves amount of components defined by user-specified internalformat.
187 * This function throws TestError exception if @param internalformat is not recognized.
189 * @param internalformat Internalformat to use for the query.
191 * @return Requested value.
193 unsigned int TextureViewUtilities::getAmountOfComponentsForInternalformat(const glw::GLenum internalformat)
195 unsigned int result = 0;
197 switch (internalformat)
199 case GL_COMPRESSED_RGBA_BPTC_UNORM:
200 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
208 case GL_RGBA16_SNORM:
217 case GL_SRGB8_ALPHA8:
224 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
225 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
226 case GL_R11F_G11F_B10F:
248 case GL_COMPRESSED_RG_RGTC2:
249 case GL_COMPRESSED_SIGNED_RG_RGTC2:
268 case GL_COMPRESSED_RED_RGTC1:
269 case GL_COMPRESSED_SIGNED_RED_RGTC1:
270 case GL_DEPTH_COMPONENT16:
271 case GL_DEPTH_COMPONENT24:
272 case GL_DEPTH32F_STENCIL8: /* only one piece of information can be retrieved at a time */
273 case GL_DEPTH24_STENCIL8: /* only one piece of information can be retrieved at a time */
294 TCU_FAIL("Unrecognized internalformat");
296 } /* switch (interalformat) */
301 /** Retrieves block size used by user-specified compressed internalformat.
303 * Throws TestError exception if @param internalformat is not recognized.
305 * @param internalformat Compressed internalformat to use for the query.
307 * @return Requested information (in bytes).
309 unsigned int TextureViewUtilities::getBlockSizeForCompressedInternalformat(const glw::GLenum internalformat)
311 unsigned int result = 0;
313 switch (internalformat)
315 case GL_COMPRESSED_RED_RGTC1:
316 case GL_COMPRESSED_SIGNED_RED_RGTC1:
323 case GL_COMPRESSED_RG_RGTC2:
324 case GL_COMPRESSED_SIGNED_RG_RGTC2:
325 case GL_COMPRESSED_RGBA_BPTC_UNORM:
326 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
327 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
328 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
337 TCU_FAIL("Unrecognized internalformat");
339 } /* switch (internalformat) */
344 /** Retrieves amount of bits used for R/G/B/A components by user-specified
345 * *non-compressed* internalformat.
347 * Throws TestError exception if @param internalformat is not recognized.
349 * @param internalformat Internalformat to use for the query. Must not describe
350 * compressed internalformat.
351 * @param out_rgba_size Must be spacious enough to hold 4 ints. Deref will be
352 * used to store requested information for R/G/B/A channels.
355 void TextureViewUtilities::getComponentSizeForInternalformat(const glw::GLenum internalformat,
356 unsigned int* out_rgba_size)
358 /* Note: Compressed textures are not supported by this function */
360 /* Reset all the values before we continue. */
361 memset(out_rgba_size, 0, 4 /* rgba */ * sizeof(unsigned int));
363 /* Depending on the user-specified internalformat, update relevant arguments */
364 switch (internalformat)
370 out_rgba_size[0] = 32;
371 out_rgba_size[1] = 32;
372 out_rgba_size[2] = 32;
373 out_rgba_size[3] = 32;
382 case GL_RGBA16_SNORM:
384 out_rgba_size[0] = 16;
385 out_rgba_size[1] = 16;
386 out_rgba_size[2] = 16;
387 out_rgba_size[3] = 16;
396 case GL_SRGB8_ALPHA8:
398 out_rgba_size[0] = 8;
399 out_rgba_size[1] = 8;
400 out_rgba_size[2] = 8;
401 out_rgba_size[3] = 8;
409 out_rgba_size[0] = 10;
410 out_rgba_size[1] = 10;
411 out_rgba_size[2] = 10;
412 out_rgba_size[3] = 2;
419 out_rgba_size[0] = 5;
420 out_rgba_size[1] = 5;
421 out_rgba_size[2] = 5;
422 out_rgba_size[3] = 1;
429 out_rgba_size[0] = 4;
430 out_rgba_size[1] = 4;
431 out_rgba_size[2] = 4;
432 out_rgba_size[3] = 4;
439 out_rgba_size[0] = 9;
440 out_rgba_size[1] = 9;
441 out_rgba_size[2] = 9;
442 out_rgba_size[3] = 5;
447 case GL_R11F_G11F_B10F:
449 out_rgba_size[0] = 11;
450 out_rgba_size[1] = 11;
451 out_rgba_size[2] = 10;
458 out_rgba_size[0] = 5;
459 out_rgba_size[1] = 6;
460 out_rgba_size[2] = 5;
469 out_rgba_size[0] = 32;
470 out_rgba_size[1] = 32;
471 out_rgba_size[2] = 32;
482 out_rgba_size[0] = 16;
483 out_rgba_size[1] = 16;
484 out_rgba_size[2] = 16;
495 out_rgba_size[0] = 8;
496 out_rgba_size[1] = 8;
497 out_rgba_size[2] = 8;
506 out_rgba_size[0] = 32;
507 out_rgba_size[1] = 32;
518 out_rgba_size[0] = 16;
519 out_rgba_size[1] = 16;
529 out_rgba_size[0] = 8;
530 out_rgba_size[1] = 8;
539 out_rgba_size[0] = 32;
549 case GL_DEPTH_COMPONENT16:
551 out_rgba_size[0] = 16;
561 out_rgba_size[0] = 8;
566 case GL_DEPTH_COMPONENT24:
568 out_rgba_size[0] = 24;
573 case GL_DEPTH32F_STENCIL8:
575 out_rgba_size[0] = 32;
576 out_rgba_size[1] = 8;
581 case GL_DEPTH24_STENCIL8:
583 out_rgba_size[0] = 24;
584 out_rgba_size[1] = 8;
591 TCU_FAIL("Unrecognized internalformat");
593 } /* switch (interalformat) */
596 /** Tells how many bits per components should be used to define input data with
597 * user-specified type.
599 * Throws TestError exception if @param type is not recognized.
601 * @param type Type to use for the query.
602 * @param out_rgba_size Deref will be used to store requested information. Must
603 * not be NULL. Must be capacious enough to hold 4 ints.
606 void TextureViewUtilities::getComponentSizeForType(const glw::GLenum type, unsigned int* out_rgba_size)
608 memset(out_rgba_size, 0, sizeof(unsigned int) * 4 /* rgba */);
613 case GL_UNSIGNED_BYTE:
615 out_rgba_size[0] = 8;
616 out_rgba_size[1] = 8;
617 out_rgba_size[2] = 8;
618 out_rgba_size[3] = 8;
624 case GL_UNSIGNED_INT:
627 out_rgba_size[0] = 32;
628 out_rgba_size[1] = 32;
629 out_rgba_size[2] = 32;
630 out_rgba_size[3] = 32;
635 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
637 out_rgba_size[0] = 8;
638 out_rgba_size[1] = 24;
639 out_rgba_size[2] = 32;
640 out_rgba_size[3] = 0;
646 case GL_UNSIGNED_SHORT:
649 out_rgba_size[0] = 16;
650 out_rgba_size[1] = 16;
651 out_rgba_size[2] = 16;
652 out_rgba_size[3] = 16;
657 case GL_UNSIGNED_INT_10_10_10_2:
659 out_rgba_size[0] = 10;
660 out_rgba_size[1] = 10;
661 out_rgba_size[2] = 10;
662 out_rgba_size[3] = 2;
667 case GL_UNSIGNED_INT_10F_11F_11F_REV:
669 out_rgba_size[0] = 11;
670 out_rgba_size[1] = 11;
671 out_rgba_size[2] = 10;
676 case GL_UNSIGNED_INT_24_8:
678 out_rgba_size[0] = 24;
679 out_rgba_size[1] = 8;
680 out_rgba_size[2] = 0;
681 out_rgba_size[3] = 0;
686 case GL_UNSIGNED_INT_2_10_10_10_REV:
688 out_rgba_size[0] = 10;
689 out_rgba_size[1] = 10;
690 out_rgba_size[2] = 10;
691 out_rgba_size[3] = 2;
696 case GL_UNSIGNED_INT_5_9_9_9_REV:
698 out_rgba_size[0] = 9;
699 out_rgba_size[1] = 9;
700 out_rgba_size[2] = 9;
701 out_rgba_size[3] = 5;
708 TCU_FAIL("Unrecognized type");
710 } /* switch (type) */
713 /** Returns strings naming GL error codes.
715 * @param error_code GL error code.
717 * @return Requested strings or "[?]" if @param error_code was not
720 const char* TextureViewUtilities::getErrorCodeString(const glw::GLint error_code)
724 case GL_INVALID_ENUM:
725 return "GL_INVALID_ENUM";
726 case GL_INVALID_FRAMEBUFFER_OPERATION:
727 return "GL_INVALID_FRAMEBUFFER_OPERATION";
728 case GL_INVALID_OPERATION:
729 return "GL_INVALID_OPERATION";
730 case GL_INVALID_VALUE:
731 return "GL_INVALID_VALUE";
733 return "GL_NO_ERROR";
734 case GL_OUT_OF_MEMORY:
735 return "GL_OUT_OF_MEMORY";
736 case GL_STACK_OVERFLOW:
737 return "GL_STACK_OVERFLOW";
738 case GL_STACK_UNDERFLOW:
739 return "GL_STACK_UNDERFLOW";
745 /** Tells what the format of user-specified internalformat is (eg. whether it's a FP,
746 * unorm, snorm, etc.). Note: this is NOT the GL-speak format.
748 * Supports both compressed and non-compressed internalformats.
749 * Throws TestError exception if @param internalformat is not recognized.
751 * @param internalformat Internalformat to use for the query.
753 * @return Requested information.
756 _format TextureViewUtilities::getFormatOfInternalformat(const glw::GLenum internalformat)
758 _format result = FORMAT_UNDEFINED;
760 switch (internalformat)
762 case GL_COMPRESSED_RG_RGTC2:
763 case GL_COMPRESSED_RGBA_BPTC_UNORM:
764 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
765 case GL_COMPRESSED_RED_RGTC1:
779 case GL_SRGB8_ALPHA8:
781 result = FORMAT_UNORM;
786 case GL_COMPRESSED_SIGNED_RED_RGTC1:
787 case GL_COMPRESSED_SIGNED_RG_RGTC2:
788 case GL_RGBA16_SNORM:
797 result = FORMAT_SNORM;
816 result = FORMAT_UNSIGNED_INTEGER;
823 result = FORMAT_RGBE;
828 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
829 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
830 case GL_DEPTH_COMPONENT16:
831 case GL_DEPTH_COMPONENT24:
832 case GL_DEPTH_COMPONENT32F:
833 case GL_R11F_G11F_B10F:
843 result = FORMAT_FLOAT;
861 result = FORMAT_SIGNED_INTEGER;
868 TCU_FAIL("Unrecognized internalformat");
870 } /* switch (interalformat) */
875 /** Returns GL format that is compatible with user-specified internalformat.
877 * Throws TestError exception if @param internalformat is not recognized.
879 * @param internalformat Internalformat to use for the query.
881 * @return Requested information.
883 glw::GLenum TextureViewUtilities::getGLFormatOfInternalformat(const glw::GLenum internalformat)
885 glw::GLenum result = FORMAT_UNDEFINED;
887 switch (internalformat)
889 case GL_COMPRESSED_RGBA_BPTC_UNORM:
890 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
891 case GL_COMPRESSED_RGBA8_ETC2_EAC:
892 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
893 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
894 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
896 result = GL_COMPRESSED_RGBA;
905 case GL_RGBA16_SNORM:
910 case GL_SRGB8_ALPHA8:
925 result = GL_RGBA_INTEGER;
930 case GL_COMPRESSED_RGB8_ETC2:
931 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
932 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
933 case GL_COMPRESSED_SRGB8_ETC2:
935 result = GL_COMPRESSED_RGB;
940 case GL_R11F_G11F_B10F:
963 result = GL_RGB_INTEGER;
968 case GL_COMPRESSED_RG_RGTC2:
969 case GL_COMPRESSED_RG11_EAC:
970 case GL_COMPRESSED_SIGNED_RG_RGTC2:
971 case GL_COMPRESSED_SIGNED_RG11_EAC:
973 result = GL_COMPRESSED_RG;
997 result = GL_RG_INTEGER;
1002 case GL_COMPRESSED_R11_EAC:
1003 case GL_COMPRESSED_RED_RGTC1:
1004 case GL_COMPRESSED_SIGNED_R11_EAC:
1005 case GL_COMPRESSED_SIGNED_RED_RGTC1:
1007 result = GL_COMPRESSED_RED;
1031 result = GL_RED_INTEGER;
1036 case GL_DEPTH_COMPONENT16:
1037 case GL_DEPTH_COMPONENT24:
1038 case GL_DEPTH_COMPONENT32F:
1040 result = GL_DEPTH_COMPONENT;
1045 case GL_DEPTH24_STENCIL8:
1046 case GL_DEPTH32F_STENCIL8:
1048 result = GL_DEPTH_STENCIL;
1055 TCU_FAIL("Unrecognized internalformat");
1057 } /* switch (internalformat) */
1062 /** Returns a string that corresponds to a GLSL type that can act as input to user-specified
1063 * sampler type, and which can hold user-specified amount of components.
1065 * Throws TestError exception if either of the arguments was found invalid.
1067 * @param sampler_type Type of the sampler to use for the query.
1068 * @param n_components Amount of components to use for the query.
1070 * @return Requested string.
1072 const char* TextureViewUtilities::getGLSLDataTypeForSamplerType(const _sampler_type sampler_type,
1073 const unsigned int n_components)
1075 const char* result = "";
1077 switch (sampler_type)
1079 case SAMPLER_TYPE_FLOAT:
1081 switch (n_components)
1098 TCU_FAIL("Unsupported number of components");
1100 } /* switch (n_components) */
1105 case SAMPLER_TYPE_SIGNED_INTEGER:
1107 switch (n_components)
1124 TCU_FAIL("Unsupported number of components");
1126 } /* switch (n_components) */
1131 case SAMPLER_TYPE_UNSIGNED_INTEGER:
1133 switch (n_components)
1150 TCU_FAIL("Unsupported number of components");
1152 } /* switch (n_components) */
1159 TCU_FAIL("Unrecognized sampler type");
1161 } /* switch (sampler_type) */
1166 /** Retrieves a string defining a sampler type in GLSL which corresponds to user-specified internal
1169 * Throws TestError exception if @param sampler_type was not recognized.
1171 * @param sampler_type Internal sampler type to use for the query.
1173 * @return Requested string.
1175 const char* TextureViewUtilities::getGLSLTypeForSamplerType(const _sampler_type sampler_type)
1177 const char* result = "";
1179 switch (sampler_type)
1181 case SAMPLER_TYPE_FLOAT:
1182 result = "sampler2D";
1184 case SAMPLER_TYPE_SIGNED_INTEGER:
1185 result = "isampler2D";
1187 case SAMPLER_TYPE_UNSIGNED_INTEGER:
1188 result = "usampler2D";
1193 TCU_FAIL("Unrecognized sampler type");
1195 } /* switch (sampler_type) */
1200 /** Returns a vector of texture+view internalformat combinations that are known to be incompatible.
1202 * @return Requested information.
1204 TextureViewUtilities::_incompatible_internalformat_pairs TextureViewUtilities::
1205 getIllegalTextureAndViewInternalformatCombinations()
1207 TextureViewUtilities::_incompatible_internalformat_pairs result;
1209 /* Iterate in two loops over the set of supported internalformats */
1210 for (int n_texture_internalformat = 0;
1211 n_texture_internalformat <
1212 (n_internalformat_view_compatibility_array_entries / 2); /* the array stores two values per entry */
1213 ++n_texture_internalformat)
1215 glw::GLenum src_internalformat = internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 0];
1216 _view_class src_view_class =
1217 (_view_class)internalformat_view_compatibility_array[(n_texture_internalformat * 2) + 1];
1219 for (int n_view_internalformat = n_texture_internalformat + 1;
1220 n_view_internalformat < (n_internalformat_view_compatibility_array_entries >> 1); ++n_view_internalformat)
1222 glw::GLenum view_internalformat = internalformat_view_compatibility_array[(n_view_internalformat * 2) + 0];
1223 _view_class view_view_class =
1224 (_view_class)internalformat_view_compatibility_array[(n_view_internalformat * 2) + 1];
1226 if (src_view_class != view_view_class)
1228 result.push_back(_internalformat_pair(src_internalformat, view_internalformat));
1230 } /* for (all internalformats we can use for the texture view) */
1231 } /* for (all internalformats we can use for the parent texture) */
1236 /** Returns a vector of texture+view target texture combinations that are known to be incompatible.
1238 * @return Requested information.
1240 TextureViewUtilities::_incompatible_texture_target_pairs TextureViewUtilities::
1241 getIllegalTextureAndViewTargetCombinations()
1243 _incompatible_texture_target_pairs result;
1245 /* Iterate through all combinations of texture targets and store those that are
1246 * reported as invalid
1248 for (unsigned int n_parent_texture_target = 0; n_parent_texture_target < n_valid_texture_targets;
1249 ++n_parent_texture_target)
1251 glw::GLenum parent_texture_target = valid_texture_targets[n_parent_texture_target];
1253 for (unsigned int n_view_texture_target = 0; n_view_texture_target < n_valid_texture_targets;
1254 ++n_view_texture_target)
1256 glw::GLenum view_texture_target = valid_texture_targets[n_view_texture_target];
1258 if (!isLegalTextureTargetForTextureView(parent_texture_target, view_texture_target))
1260 result.push_back(_internalformat_pair(parent_texture_target, view_texture_target));
1262 } /* for (all texture targets considered for views) */
1263 } /* for (all texture targets considered for parent texture) */
1268 /** Returns internalformats associated with user-specified view class.
1270 * @param view_class View class to use for the query.
1272 * @return Requested information.
1274 TextureViewUtilities::_internalformats TextureViewUtilities::getInternalformatsFromViewClass(_view_class view_class)
1276 _internalformats result;
1278 /* Iterate over the data array and push those internalformats that match the requested view class */
1279 const unsigned int n_array_elements = n_internalformat_view_compatibility_array_entries;
1281 for (unsigned int n_array_pair = 0; n_array_pair < (n_array_elements >> 1); ++n_array_pair)
1283 const glw::GLenum internalformat = internalformat_view_compatibility_array[n_array_pair * 2 + 0];
1284 const _view_class current_view_class =
1285 (_view_class)internalformat_view_compatibility_array[n_array_pair * 2 + 1];
1287 if (current_view_class == view_class)
1289 result.push_back(internalformat);
1291 } /* for (all pairs in the data array) */
1296 /** Returns a string defining user-specified internalformat.
1298 * Throws a TestError exception if @param internalformat was not recognized.
1300 * @param internalformat Internalformat to use for the query.
1302 * @return Requested string.
1304 const char* TextureViewUtilities::getInternalformatString(const glw::GLenum internalformat)
1306 const char* result = "[?]";
1308 switch (internalformat)
1311 result = "GL_RGBA32F";
1314 result = "GL_RGBA32I";
1317 result = "GL_RGBA32UI";
1320 result = "GL_RGBA16";
1323 result = "GL_RGBA16F";
1326 result = "GL_RGBA16I";
1329 result = "GL_RGBA16UI";
1332 result = "GL_RGBA8";
1335 result = "GL_RGBA8I";
1338 result = "GL_RGBA8UI";
1340 case GL_SRGB8_ALPHA8:
1341 result = "GL_SRGB8_ALPHA8";
1344 result = "GL_RGB10_A2";
1347 result = "GL_RGB10_A2UI";
1350 result = "GL_RGB5_A1";
1353 result = "GL_RGBA4";
1355 case GL_R11F_G11F_B10F:
1356 result = "GL_R11F_G11F_B10F";
1359 result = "GL_RGB565";
1362 result = "GL_RG32F";
1365 result = "GL_RG32I";
1368 result = "GL_RG32UI";
1374 result = "GL_RG16F";
1377 result = "GL_RG16I";
1380 result = "GL_RG16UI";
1389 result = "GL_RG8UI";
1398 result = "GL_R32UI";
1407 result = "GL_R16UI";
1421 case GL_RGBA16_SNORM:
1422 result = "GL_RGBA16_SNORM";
1424 case GL_RGBA8_SNORM:
1425 result = "GL_RGBA8_SNORM";
1428 result = "GL_RGB32F";
1431 result = "GL_RGB32I";
1434 result = "GL_RGB32UI";
1436 case GL_RGB16_SNORM:
1437 result = "GL_RGB16_SNORM";
1440 result = "GL_RGB16F";
1443 result = "GL_RGB16I";
1446 result = "GL_RGB16UI";
1449 result = "GL_RGB16";
1452 result = "GL_RGB8_SNORM";
1458 result = "GL_RGB8I";
1461 result = "GL_RGB8UI";
1464 result = "GL_SRGB8";
1467 result = "GL_RGB9_E5";
1470 result = "GL_RG16_SNORM";
1473 result = "GL_RG8_SNORM";
1476 result = "GL_R16_SNORM";
1479 result = "GL_R8_SNORM";
1481 case GL_DEPTH_COMPONENT32F:
1482 result = "GL_DEPTH_COMPONENT32F";
1484 case GL_DEPTH_COMPONENT24:
1485 result = "GL_DEPTH_COMPONENT24";
1487 case GL_DEPTH_COMPONENT16:
1488 result = "GL_DEPTH_COMPONENT16";
1490 case GL_DEPTH32F_STENCIL8:
1491 result = "GL_DEPTH32F_STENCIL8";
1493 case GL_DEPTH24_STENCIL8:
1494 result = "GL_DEPTH24_STENCIL8";
1496 case GL_COMPRESSED_RED_RGTC1:
1497 result = "GL_COMPRESSED_RED_RGTC1";
1499 case GL_COMPRESSED_SIGNED_RED_RGTC1:
1500 result = "GL_COMPRESSED_SIGNED_RED_RGTC1";
1502 case GL_COMPRESSED_RG_RGTC2:
1503 result = "GL_COMPRESSED_RG_RGTC2";
1505 case GL_COMPRESSED_SIGNED_RG_RGTC2:
1506 result = "GL_COMPRESSED_SIGNED_RG_RGTC2";
1508 case GL_COMPRESSED_RGBA_BPTC_UNORM:
1509 result = "GL_COMPRESSED_RGBA_BPTC_UNORM";
1511 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
1512 result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
1514 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
1515 result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
1517 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
1518 result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
1520 case GL_COMPRESSED_RGB8_ETC2:
1521 result = "GL_COMPRESSED_RGB8_ETC2";
1523 case GL_COMPRESSED_SRGB8_ETC2:
1524 result = "GL_COMPRESSED_SRGB8_ETC2";
1526 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1527 result = "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
1529 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
1530 result = "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
1532 case GL_COMPRESSED_RGBA8_ETC2_EAC:
1533 result = "GL_COMPRESSED_RGBA8_ETC2_EAC";
1535 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
1536 result = "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
1538 case GL_COMPRESSED_R11_EAC:
1539 result = "GL_COMPRESSED_R11_EAC";
1541 case GL_COMPRESSED_SIGNED_R11_EAC:
1542 result = "GL_COMPRESSED_SIGNED_R11_EAC";
1544 case GL_COMPRESSED_RG11_EAC:
1545 result = "GL_COMPRESSED_RG11_EAC";
1547 case GL_COMPRESSED_SIGNED_RG11_EAC:
1548 result = "GL_COMPRESSED_SIGNED_RG11_EAC";
1552 TCU_FAIL("Unrecognized internalformat");
1558 /** Returns all texture+view internalformat pairs that are valid in light of GL_ARB_texture_view specification.
1560 * @return As described.
1562 TextureViewUtilities::_compatible_internalformat_pairs TextureViewUtilities::
1563 getLegalTextureAndViewInternalformatCombinations()
1565 _compatible_internalformat_pairs result;
1567 /* Iterate over all view classes */
1568 for (int current_view_class_it = static_cast<int>(VIEW_CLASS_FIRST);
1569 current_view_class_it != static_cast<int>(VIEW_CLASS_COUNT); current_view_class_it++)
1571 _view_class current_view_class = static_cast<_view_class>(current_view_class_it);
1572 _internalformats view_class_internalformats = getInternalformatsFromViewClass(current_view_class);
1574 /* Store all combinations in the result vector */
1575 for (_internalformats_const_iterator left_iterator = view_class_internalformats.begin();
1576 left_iterator != view_class_internalformats.end(); left_iterator++)
1578 for (_internalformats_const_iterator right_iterator = view_class_internalformats.begin();
1579 right_iterator != view_class_internalformats.end(); ++right_iterator)
1581 result.push_back(_internalformat_pair(*left_iterator, *right_iterator));
1582 } /* for (all internalformats to be used as right-side values) */
1583 } /* for (all internalformats to be used as left-side values) */
1584 } /* for (all view classes) */
1589 /** Returns all valid texture+view texture targets pairs.
1591 * @return As per description.
1593 TextureViewUtilities::_compatible_texture_target_pairs TextureViewUtilities::getLegalTextureAndViewTargetCombinations()
1595 _compatible_texture_target_pairs result;
1597 /* Iterate over all texture targets valid for a glTextureView() call. Consider each one of them as
1598 * original texture target.
1600 for (unsigned int n_original_texture_target = 0; n_original_texture_target < n_valid_texture_targets;
1601 ++n_original_texture_target)
1603 const glw::GLenum original_texture_target = valid_texture_targets[n_original_texture_target];
1605 /* Iterate again, but this time consider each texture target as a valid new target */
1606 for (unsigned int n_compatible_texture_target = 0; n_compatible_texture_target < n_valid_texture_targets;
1607 ++n_compatible_texture_target)
1609 const glw::GLenum view_texture_target = valid_texture_targets[n_compatible_texture_target];
1611 if (TextureViewUtilities::isLegalTextureTargetForTextureView(original_texture_target, view_texture_target))
1613 result.push_back(_texture_target_pair(original_texture_target, view_texture_target));
1615 } /* for (all texture targets that are potentially compatible) */
1616 } /* for (all original texture targets) */
1621 /** Returns major & minor version for user-specified CTS rendering context type.
1623 * @param context_type CTS rendering context type.
1624 * @param out_major_version Deref will be used to store major version. Must not be NULL.
1625 * @param out_minor_version Deref will be used to store minor version. Must not be NULL.
1628 void TextureViewUtilities::getMajorMinorVersionFromContextVersion(const glu::ContextType& context_type,
1629 glw::GLint* out_major_version,
1630 glw::GLint* out_minor_version)
1632 if (context_type.getAPI() == glu::ApiType::core(4, 0))
1634 *out_major_version = 4;
1635 *out_minor_version = 0;
1637 else if (context_type.getAPI() == glu::ApiType::core(4, 1))
1639 *out_major_version = 4;
1640 *out_minor_version = 1;
1642 else if (context_type.getAPI() == glu::ApiType::core(4, 2))
1644 *out_major_version = 4;
1645 *out_minor_version = 2;
1647 else if (context_type.getAPI() == glu::ApiType::core(4, 3))
1649 *out_major_version = 4;
1650 *out_minor_version = 3;
1652 else if (context_type.getAPI() == glu::ApiType::core(4, 4))
1654 *out_major_version = 4;
1655 *out_minor_version = 4;
1657 else if (context_type.getAPI() == glu::ApiType::core(4, 5))
1659 *out_major_version = 4;
1660 *out_minor_version = 5;
1664 TCU_FAIL("Unrecognized rendering context version");
1668 /** Tells which sampler can be used to sample a texture defined with user-specified
1671 * Supports both compressed and non-compressed internalformats.
1672 * Throws TestError exception if @param internalformat was not recognized.
1674 * @param internalformat Internalformat to use for the query.
1676 * @return Requested information.
1678 _sampler_type TextureViewUtilities::getSamplerTypeForInternalformat(const glw::GLenum internalformat)
1680 _sampler_type result = SAMPLER_TYPE_UNDEFINED;
1682 /* Compressed internalformats not supported at the moment */
1684 switch (internalformat)
1686 case GL_COMPRESSED_RED_RGTC1:
1687 case GL_COMPRESSED_SIGNED_RED_RGTC1:
1688 case GL_COMPRESSED_RG_RGTC2:
1689 case GL_COMPRESSED_SIGNED_RG_RGTC2:
1690 case GL_COMPRESSED_RGBA_BPTC_UNORM:
1691 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
1692 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
1693 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
1694 case GL_DEPTH_COMPONENT16:
1695 case GL_DEPTH_COMPONENT24:
1696 case GL_DEPTH_COMPONENT32F:
1698 case GL_RGBA16_SNORM:
1703 case GL_RGBA8_SNORM:
1706 case GL_RGB16_SNORM:
1720 case GL_R11F_G11F_B10F:
1727 case GL_SRGB8_ALPHA8:
1730 result = SAMPLER_TYPE_FLOAT;
1749 result = SAMPLER_TYPE_UNSIGNED_INTEGER;
1767 result = SAMPLER_TYPE_SIGNED_INTEGER;
1774 TCU_FAIL("Unrecognized internalformat");
1776 } /* switch (interalformat) */
1781 /** Tells how many bytes are required to define a texture mip-map using
1782 * user-specified internalformat and type, assuming user-defined mip-map
1783 * resolution. Compressed internalformats are NOT supported.
1785 * Throws TestError exception if @param internalformat or @param type are
1788 * @param internalformat Internalformat to use for the query.
1789 * @param type Type to use for the query.
1790 * @param width Mip-map width to use for the query.
1791 * @param height Mip-map height to use for the query.
1793 * @return Requested information.
1795 unsigned int TextureViewUtilities::getTextureDataSize(const glw::GLenum internalformat, const glw::GLenum type,
1796 const unsigned int width, const unsigned int height)
1798 unsigned int internalformat_rgba_size[4] = { 0 };
1799 unsigned int type_rgba_size[4] = { 0 };
1800 unsigned int texel_size = 0;
1802 TextureViewUtilities::getComponentSizeForInternalformat(internalformat, internalformat_rgba_size);
1803 TextureViewUtilities::getComponentSizeForType(type, type_rgba_size);
1805 if (internalformat_rgba_size[0] == 0)
1807 type_rgba_size[0] = 0;
1810 if (internalformat_rgba_size[1] == 0)
1812 type_rgba_size[1] = 0;
1815 if (internalformat_rgba_size[2] == 0)
1817 type_rgba_size[2] = 0;
1820 if (internalformat_rgba_size[3] == 0)
1822 type_rgba_size[3] = 0;
1825 texel_size = type_rgba_size[0] + type_rgba_size[1] + type_rgba_size[2] + type_rgba_size[3];
1827 /* Current implementation assumes we do not need to use bit resolution when
1828 * preparing texel data. Make extra sure we're not wrong. */
1829 DE_ASSERT((texel_size % 8) == 0);
1831 texel_size /= 8; /* bits per byte */
1833 return texel_size * width * height;
1836 /** Returns a string corresponding to a GL enum describing a texture target.
1838 * @return As per description or "[?]" if the enum was not recognized.
1840 const char* TextureViewUtilities::getTextureTargetString(const glw::GLenum texture_target)
1842 const char* result = "[?]";
1844 switch (texture_target)
1847 result = "GL_TEXTURE_1D";
1849 case GL_TEXTURE_1D_ARRAY:
1850 result = "GL_TEXTURE_1D_ARRAY";
1853 result = "GL_TEXTURE_2D";
1855 case GL_TEXTURE_2D_ARRAY:
1856 result = "GL_TEXTURE_2D_ARRAY";
1858 case GL_TEXTURE_2D_MULTISAMPLE:
1859 result = "GL_TEXTURE_2D_MULTISAMPLE";
1861 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1862 result = "GL_TEXTURE_2D_MULTISAMPLE_ARRAY";
1865 result = "GL_TEXTURE_3D";
1867 case GL_TEXTURE_BUFFER:
1868 result = "GL_TEXTURE_BUFFER";
1870 case GL_TEXTURE_CUBE_MAP:
1871 result = "GL_TEXTURE_CUBE_MAP";
1873 case GL_TEXTURE_CUBE_MAP_ARRAY:
1874 result = "GL_TEXTURE_CUBE_MAP_ARRAY";
1876 case GL_TEXTURE_RECTANGLE:
1877 result = "GL_TEXTURE_RECTANGLE";
1884 /** Returns GL type that can be used to define a texture mip-map defined
1885 * with an internalformat of @param internalformat.
1887 * Throws TestError exception if @param internalformat was found to be invalid.
1889 * @param internalformat Internalformat to use for the query.
1891 * @return Requested information.
1893 glw::GLenum TextureViewUtilities::getTypeCompatibleWithInternalformat(const glw::GLenum internalformat)
1895 glw::GLenum result = GL_NONE;
1897 /* Compressed internalformats not supported at the moment */
1899 switch (internalformat)
1901 case GL_RGBA8_SNORM:
1915 case GL_DEPTH24_STENCIL8:
1917 result = GL_UNSIGNED_INT_24_8;
1922 case GL_DEPTH32F_STENCIL8:
1924 result = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
1934 result = GL_HALF_FLOAT;
1939 case GL_DEPTH_COMPONENT32F:
1943 case GL_R11F_G11F_B10F:
1951 case GL_RGBA16_SNORM:
1952 case GL_RGB16_SNORM:
1970 case GL_SRGB8_ALPHA8:
1977 result = GL_UNSIGNED_BYTE;
1992 case GL_DEPTH_COMPONENT16:
2002 result = GL_UNSIGNED_SHORT;
2017 case GL_DEPTH_COMPONENT24:
2023 result = GL_UNSIGNED_INT;
2030 result = GL_UNSIGNED_INT_2_10_10_10_REV;
2037 TCU_FAIL("Unrecognized internalformat");
2039 } /* switch (interalformat) */
2044 /** Tells what view class is the user-specified internalformat associated with.
2046 * Implements Table 8.21 from OpenGL Specification 4.3
2048 * @param internalformat Internalformat to use for the query.
2050 * @return Requested information or VIEW_CLASS_UNDEFINED if @param internalformat
2051 * has not been recognized.
2053 _view_class TextureViewUtilities::getViewClassForInternalformat(const glw::GLenum internalformat)
2055 _view_class result = VIEW_CLASS_UNDEFINED;
2057 /* Note that n_internalformat_view_compatibility_array_entries needs to be divided by 2
2058 * because the value refers to a total number of entries in the array, not to the number
2059 * of pairs that can be read.
2061 for (int n_entry = 0; n_entry < (n_internalformat_view_compatibility_array_entries >> 1); n_entry++)
2063 glw::GLenum array_internalformat = internalformat_view_compatibility_array[(n_entry * 2) + 0];
2064 _view_class view_class = (_view_class)internalformat_view_compatibility_array[(n_entry * 2) + 1];
2066 if (array_internalformat == internalformat)
2068 result = view_class;
2072 } /* for (all pairs in data array) */
2077 /** Initializes texture storage for either an immutable or mutable texture object,
2078 * depending on configuration of the test run the storage is to be initialized for.
2080 * @param gl GL entry-points to use for storage initialization.
2081 * @param init_mutable_to true if a mutable texture storage should be initialized,
2082 * false to initialize immutable texture storage.
2083 * @param texture_target Texture target to be used.
2084 * @param texture_depth Depth to be used for texture storage. Only used
2085 * for texture targets that use the depth information.
2086 * @param texture_height Height to be used for texture storage. Only used
2087 * for texture targets that use the height information.
2088 * @param texture_width Width to be used for texture storage.
2089 * @param texture_internalformat Internalformat to be used for texture storage.
2090 * @param texture_format Format to be used for texture storage.
2091 * @param texture_type Type to be used for texture storage.
2092 * @param n_levels_needed Amount of mip-map levels that should be used for texture storage.
2093 * Only used for texture targets that support mip-maps.
2094 * @param n_cubemaps_needed Amount of cube-maps to be used for initialization of cube map
2095 * array texture storage. Only used if @param texture_internalformat
2096 * is set to GL_TEXTURE_CUBE_MAP_ARRAY.
2097 * @param bo_id ID of a buffer object to be used for initialization of
2098 * buffer texture storage. Only used if @param texture_internalformat
2099 * is set to GL_TEXTURE_BUFFEER.
2102 void TextureViewUtilities::initTextureStorage(const glw::Functions& gl, bool init_mutable_to,
2103 glw::GLenum texture_target, glw::GLint texture_depth,
2104 glw::GLint texture_height, glw::GLint texture_width,
2105 glw::GLenum texture_internalformat, glw::GLenum texture_format,
2106 glw::GLenum texture_type, unsigned int n_levels_needed,
2107 unsigned int n_cubemaps_needed, glw::GLint bo_id)
2109 const glw::GLenum cubemap_texture_targets[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
2110 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
2111 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
2112 const unsigned int n_cubemap_texture_targets = sizeof(cubemap_texture_targets) / sizeof(cubemap_texture_targets[0]);
2114 /* If we're going to be initializing a multisample texture object,
2115 * determine how many samples can be used for GL_RGBA8 internalformat,
2116 * given texture target that is of our interest */
2117 glw::GLint gl_max_color_texture_samples_value = 0;
2119 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value);
2120 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES");
2122 if (texture_target == GL_TEXTURE_BUFFER)
2124 gl.texBuffer(GL_TEXTURE_BUFFER, texture_internalformat, bo_id);
2126 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed for GL_TEXTURE_BUFFER target");
2128 else if (init_mutable_to)
2130 for (unsigned int n_level = 0; n_level < n_levels_needed; ++n_level)
2132 /* If level != 0 and we're trying to initialize a texture target which
2133 * only accepts a single level, leave now
2136 (texture_target == GL_TEXTURE_RECTANGLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
2137 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_BUFFER))
2142 /* Initialize mutable texture storage */
2143 switch (texture_target)
2147 gl.texImage1D(texture_target, n_level, texture_internalformat, texture_width >> n_level, 0, /* border */
2148 texture_format, texture_type, DE_NULL); /* pixels */
2150 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D() call failed for GL_TEXTURE_1D texture target");
2155 case GL_TEXTURE_1D_ARRAY:
2157 case GL_TEXTURE_RECTANGLE:
2159 gl.texImage2D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
2160 texture_height >> n_level, 0, /* border */
2161 texture_format, texture_type, DE_NULL); /* pixels */
2163 GLU_EXPECT_NO_ERROR(gl.getError(),
2164 (texture_target == GL_TEXTURE_1D_ARRAY) ?
2165 "glTexImage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
2166 (texture_target == GL_TEXTURE_2D) ?
2167 "glTexImage2D() call failed for GL_TEXTURE_2D texture target" :
2168 "glTexImage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
2173 case GL_TEXTURE_2D_ARRAY:
2176 gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
2177 texture_height >> n_level, texture_depth >> n_level, 0, /* border */
2178 texture_format, texture_type, DE_NULL); /* pixels */
2180 GLU_EXPECT_NO_ERROR(gl.getError(),
2181 (texture_target == GL_TEXTURE_2D_ARRAY) ?
2182 "glTexImage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
2183 "glTexImage3D() call failed for GL_TEXTURE_3D texture target");
2188 case GL_TEXTURE_2D_MULTISAMPLE:
2190 gl.texImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
2191 texture_internalformat, texture_width >> n_level, texture_height >> n_level,
2192 GL_TRUE); /* fixedsamplelocations */
2194 GLU_EXPECT_NO_ERROR(
2196 "glTexImage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
2201 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2203 gl.texImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
2204 texture_internalformat, texture_width >> n_level, texture_height >> n_level,
2205 texture_depth >> n_level, GL_TRUE); /* fixedsamplelocations */
2207 GLU_EXPECT_NO_ERROR(
2209 "glTexImage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
2214 case GL_TEXTURE_CUBE_MAP:
2216 for (unsigned int n_cubemap_texture_target = 0; n_cubemap_texture_target < n_cubemap_texture_targets;
2217 ++n_cubemap_texture_target)
2219 glw::GLenum cubemap_texture_target = cubemap_texture_targets[n_cubemap_texture_target];
2221 gl.texImage2D(cubemap_texture_target, n_level, texture_internalformat, texture_width >> n_level,
2222 texture_height >> n_level, 0, /* border */
2223 texture_format, texture_type, DE_NULL); /* pixels */
2225 GLU_EXPECT_NO_ERROR(gl.getError(),
2226 "glTexImage2D() call failed for one of the cube-map texture targets");
2229 } /* for (all cube-map texture targets) */
2234 case GL_TEXTURE_CUBE_MAP_ARRAY:
2236 gl.texImage3D(texture_target, n_level, texture_internalformat, texture_width >> n_level,
2237 texture_height >> n_level, 6 /* layer-faces */ * n_cubemaps_needed, 0, /* border */
2238 texture_format, texture_type, DE_NULL); /* pixels */
2240 GLU_EXPECT_NO_ERROR(gl.getError(),
2241 "glTexImage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
2248 TCU_FAIL("Unrecognized texture target");
2250 } /* switch (texture_target) */
2251 } /* for (all levels) */
2252 } /* if (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT) */
2255 /* Initialize immutable texture storage */
2256 switch (texture_target)
2260 gl.texStorage1D(texture_target, n_levels_needed, texture_internalformat, texture_width);
2262 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed for GL_TEXTURE_1D texture target");
2267 case GL_TEXTURE_1D_ARRAY:
2269 case GL_TEXTURE_CUBE_MAP:
2270 case GL_TEXTURE_RECTANGLE:
2272 const unsigned n_levels = (texture_target == GL_TEXTURE_RECTANGLE) ? 1 : n_levels_needed;
2274 gl.texStorage2D(texture_target, n_levels, texture_internalformat, texture_width, texture_height);
2276 GLU_EXPECT_NO_ERROR(gl.getError(),
2277 (texture_target == GL_TEXTURE_1D_ARRAY) ?
2278 "glTexStorage2D() call failed for GL_TEXTURE_1D_ARRAY texture target" :
2279 (texture_target == GL_TEXTURE_2D) ?
2280 "glTexStorage2D() call failed for GL_TEXTURE_2D texture target" :
2281 (texture_target == GL_TEXTURE_CUBE_MAP) ?
2282 "glTexStorage2D() call failed for GL_TEXTURE_CUBE_MAP texture target" :
2283 "glTexStorage2D() call failed for GL_TEXTURE_RECTANGLE texture target");
2288 case GL_TEXTURE_2D_ARRAY:
2291 gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
2294 GLU_EXPECT_NO_ERROR(gl.getError(),
2295 (texture_target == GL_TEXTURE_2D_ARRAY) ?
2296 "glTexStorage3D() call failed for GL_TEXTURE_2D_ARRAY texture target" :
2297 "glTexStorage3D() call failed for GL_TEXTURE_3D texture target");
2302 case GL_TEXTURE_2D_MULTISAMPLE:
2304 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_color_texture_samples_value,
2305 texture_internalformat, texture_width, texture_height,
2306 GL_TRUE); /* fixedsamplelocations */
2308 GLU_EXPECT_NO_ERROR(gl.getError(),
2309 "glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
2314 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2316 gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, gl_max_color_texture_samples_value,
2317 texture_internalformat, texture_width, texture_height, texture_depth,
2318 GL_TRUE); /* fixedsamplelocations */
2320 GLU_EXPECT_NO_ERROR(
2322 "glTexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY texture target");
2327 case GL_TEXTURE_CUBE_MAP_ARRAY:
2329 const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
2331 gl.texStorage3D(texture_target, n_levels_needed, texture_internalformat, texture_width, texture_height,
2332 actual_texture_depth);
2334 GLU_EXPECT_NO_ERROR(gl.getError(),
2335 "glTexStorage3D() call failed for GL_TEXTURE_CUBE_MAP_ARRAY texture target");
2342 TCU_FAIL("Unrecognized texture target");
2344 } /* switch (texture_target) */
2348 /** Tells whether a parent texture object, storage of which uses @param original_internalformat
2349 * internalformat, can be used to generate a texture view using @param view_internalformat
2352 * @param original_internalformat Internalformat used for parent texture object storage.
2353 * @param view_internalformat Internalformat to be used for view texture object storage.
2355 * @return true if the internalformats are compatible, false otherwise.
2357 bool TextureViewUtilities::isInternalformatCompatibleForTextureView(glw::GLenum original_internalformat,
2358 glw::GLenum view_internalformat)
2360 const _view_class original_internalformat_view_class = getViewClassForInternalformat(original_internalformat);
2361 const _view_class view_internalformat_view_class = getViewClassForInternalformat(view_internalformat);
2363 return (original_internalformat_view_class == view_internalformat_view_class);
2366 /** Tells whether user-specified internalformat is compressed.
2368 * @param internalformat Internalformat to use for the query.
2370 * @return true if @param internalformat is a known compressed internalformat,
2373 bool TextureViewUtilities::isInternalformatCompressed(const glw::GLenum internalformat)
2375 bool result = false;
2377 switch (internalformat)
2379 case GL_COMPRESSED_RED_RGTC1:
2380 case GL_COMPRESSED_SIGNED_RED_RGTC1:
2381 case GL_COMPRESSED_RG_RGTC2:
2382 case GL_COMPRESSED_SIGNED_RG_RGTC2:
2383 case GL_COMPRESSED_RGBA_BPTC_UNORM:
2384 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
2385 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
2386 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
2387 case GL_COMPRESSED_RGB8_ETC2:
2388 case GL_COMPRESSED_SRGB8_ETC2:
2389 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
2390 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
2391 case GL_COMPRESSED_RGBA8_ETC2_EAC:
2392 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
2393 case GL_COMPRESSED_R11_EAC:
2394 case GL_COMPRESSED_SIGNED_R11_EAC:
2395 case GL_COMPRESSED_RG11_EAC:
2396 case GL_COMPRESSED_SIGNED_RG11_EAC:
2402 } /* switch (internalformat) */
2407 /** Tells whether user-specified internalformat operates in sRGB color space.
2409 * @param internalformat Internalformat to use for the query.
2411 * @return true if @param internalformat is a known sRGB internalformat,
2414 bool TextureViewUtilities::isInternalformatSRGB(const glw::GLenum internalformat)
2416 return (internalformat == GL_SRGB8 || internalformat == GL_SRGB8_ALPHA8 ||
2417 internalformat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM);
2420 /** Tells whether user-specified internalformat is supported by OpenGL of a given version.
2422 * @param internalformat Internalformat to use for the query.
2423 * @param major_version Major version of the rendering context.
2424 * @param minor_version Minor version of the rendering context.
2426 * @return true if the internalformat is supported, false otherwise.
2428 bool TextureViewUtilities::isInternalformatSupported(glw::GLenum internalformat, const glw::GLint major_version,
2429 const glw::GLint minor_version)
2431 (void)major_version;
2432 /* NOTE: This function, as it stands right now, does not consider OpenGL contexts
2435 glw::GLint minimum_minor_version = 0;
2437 DE_ASSERT(major_version >= 4);
2439 switch (internalformat)
2452 case GL_SRGB8_ALPHA8:
2457 case GL_R11F_G11F_B10F:
2478 case GL_RGBA16_SNORM:
2479 case GL_RGBA8_SNORM:
2483 case GL_RGB16_SNORM:
2498 case GL_DEPTH_COMPONENT32F:
2499 case GL_DEPTH_COMPONENT24:
2500 case GL_DEPTH_COMPONENT16:
2501 case GL_DEPTH32F_STENCIL8:
2502 case GL_DEPTH24_STENCIL8:
2503 case GL_COMPRESSED_RED_RGTC1:
2504 case GL_COMPRESSED_SIGNED_RED_RGTC1:
2505 case GL_COMPRESSED_RG_RGTC2:
2506 case GL_COMPRESSED_SIGNED_RG_RGTC2:
2508 /* Already covered by default value of minimum_minor_version */
2515 case GL_COMPRESSED_RGBA_BPTC_UNORM:
2516 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
2517 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
2518 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
2520 minimum_minor_version = 2;
2526 case GL_COMPRESSED_RGB8_ETC2:
2527 case GL_COMPRESSED_SRGB8_ETC2:
2528 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
2529 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
2530 case GL_COMPRESSED_RGBA8_ETC2_EAC:
2531 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
2532 case GL_COMPRESSED_R11_EAC:
2533 case GL_COMPRESSED_SIGNED_R11_EAC:
2534 case GL_COMPRESSED_RG11_EAC:
2535 case GL_COMPRESSED_SIGNED_RG11_EAC:
2537 minimum_minor_version = 3;
2543 TCU_FAIL("Unrecognized internalformat");
2546 return (minor_version >= minimum_minor_version);
2549 /** Tells whether a parent texture object using @param original_texture_target texture target
2550 * can be used to generate a texture view of @param view_texture_target texture target.
2552 * @param original_texture_target Texture target used by parent texture;
2553 * @param view_texture_target Texture target to be used for view texture;
2555 * @return true if the texture targets are compatible, false otherwise.
2557 bool TextureViewUtilities::isLegalTextureTargetForTextureView(glw::GLenum original_texture_target,
2558 glw::GLenum view_texture_target)
2560 bool result = false;
2562 switch (original_texture_target)
2566 result = (view_texture_target == GL_TEXTURE_1D || view_texture_target == GL_TEXTURE_1D_ARRAY);
2573 result = (view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_2D_ARRAY);
2580 result = (view_texture_target == GL_TEXTURE_3D);
2585 case GL_TEXTURE_CUBE_MAP:
2587 result = (view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_2D ||
2588 view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
2593 case GL_TEXTURE_RECTANGLE:
2595 result = (view_texture_target == GL_TEXTURE_RECTANGLE);
2600 case GL_TEXTURE_BUFFER:
2602 /* No targets supported */
2607 case GL_TEXTURE_1D_ARRAY:
2609 result = (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_1D);
2614 case GL_TEXTURE_2D_ARRAY:
2616 result = (view_texture_target == GL_TEXTURE_2D_ARRAY || view_texture_target == GL_TEXTURE_2D ||
2617 view_texture_target == GL_TEXTURE_CUBE_MAP || view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
2622 case GL_TEXTURE_CUBE_MAP_ARRAY:
2624 result = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY ||
2625 view_texture_target == GL_TEXTURE_2D || view_texture_target == GL_TEXTURE_CUBE_MAP);
2630 case GL_TEXTURE_2D_MULTISAMPLE:
2632 result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
2633 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2638 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2640 result = (view_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
2641 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2645 } /* switch (original_texture_target) */
2652 * @param context Rendering context.
2654 TextureViewTestGetTexParameter::TextureViewTestGetTexParameter(deqp::Context& context)
2655 : TestCase(context, "gettexparameter", "Verifies glGetTexParameterfv() and glGetTexParameteriv() "
2656 "work as specified")
2658 /* Left blank on purpose */
2661 /** De-initializes all GL objects created for the test. */
2662 void TextureViewTestGetTexParameter::deinit()
2664 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2666 /* Deinitialize all test runs */
2667 for (_test_runs_iterator it = m_test_runs.begin(); it != m_test_runs.end(); ++it)
2669 _test_run& test_run = *it;
2671 if (test_run.parent_texture_object_id != 0)
2673 gl.deleteTextures(1, &test_run.parent_texture_object_id);
2675 test_run.parent_texture_object_id = 0;
2678 if (test_run.texture_view_object_created_from_immutable_to_id != 0)
2680 gl.deleteTextures(1, &test_run.texture_view_object_created_from_immutable_to_id);
2682 test_run.texture_view_object_created_from_immutable_to_id = 0;
2685 if (test_run.texture_view_object_created_from_view_to_id != 0)
2687 gl.deleteTextures(1, &test_run.texture_view_object_created_from_view_to_id);
2689 test_run.texture_view_object_created_from_view_to_id = 0;
2692 m_test_runs.clear();
2695 /** Initializes test run descriptors used by the test. This also includes
2696 * all GL objects used by all the iterations.
2698 void TextureViewTestGetTexParameter::initTestRuns()
2700 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2701 const int n_cubemaps_needed = 4; /* only used for GL_TEXTURE_CUBE_MAP_ARRAY */
2702 const int texture_depth = 16;
2703 const int texture_height = 32;
2704 const int texture_width = 64;
2706 const glw::GLenum texture_targets[] = {
2707 GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D,
2708 GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
2709 GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY,
2710 GL_TEXTURE_RECTANGLE
2712 const _test_texture_type texture_types[] = { TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED,
2713 TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT,
2714 TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT,
2715 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT,
2716 TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW };
2717 const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
2718 const unsigned int n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]);
2720 /* Iterate through all texture types supported by the test */
2721 for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type)
2723 const _test_texture_type texture_type = texture_types[n_texture_type];
2725 /* Iterate through all texture targets supported by the test */
2726 for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2728 _test_run new_test_run;
2729 const glw::GLenum texture_target = texture_targets[n_texture_target];
2731 /* Texture buffers are neither immutable nor mutable. In order to avoid testing
2732 * them in both cases, let's assume they are immutable objects */
2733 if (texture_target == GL_TEXTURE_BUFFER && texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT)
2738 /* Set up test run properties. Since we're only testing a single
2739 * configuration, we can set these to predefined values..
2741 const int n_levels_needed = 6;
2742 glw::GLint n_min_layer = 1;
2743 glw::GLint n_num_layers = 2;
2744 glw::GLint n_min_level = 2;
2745 glw::GLint n_num_levels = 3;
2746 int parent_texture_depth = texture_depth;
2747 int parent_texture_height = texture_height;
2748 int parent_texture_width = texture_width;
2750 new_test_run.texture_target = texture_target;
2751 new_test_run.texture_type = texture_type;
2753 /* Take note of target-specific restrictions */
2754 if (texture_target == GL_TEXTURE_CUBE_MAP || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
2756 n_num_layers = 6 /* layer-faces */ * 2; /* as per spec */
2758 /* Make sure that cube face width matches its height */
2759 parent_texture_height = 64;
2760 parent_texture_width = 64;
2762 /* Also change the depth so that there's at least a few layers
2763 * we can use in the test for GL_TEXTURE_CUBE_MAP_ARRAY case
2765 parent_texture_depth = 64;
2768 if (texture_target == GL_TEXTURE_CUBE_MAP)
2770 /* Texture views created from a cube map texture should always
2771 * use a minimum layer of zero
2777 if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
2779 /* Slightly modify the values we'll use for <minlayer>
2780 * and <numlayers> arguments passed to glTextureView() calls
2781 * so that we can test the "view from view from texture" case
2786 if (texture_target == GL_TEXTURE_1D || texture_target == GL_TEXTURE_2D ||
2787 texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_3D ||
2788 texture_target == GL_TEXTURE_RECTANGLE)
2790 /* All these texture targets are single-layer only. glTextureView()
2791 * also requires <numlayers> argument to be set to 1 for them, so
2792 * take this into account.
2798 if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
2799 texture_target == GL_TEXTURE_RECTANGLE)
2801 /* All these texture targets do not support mip-maps */
2805 /* Initialize parent texture object */
2806 gl.genTextures(1, &new_test_run.parent_texture_object_id);
2807 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
2809 gl.bindTexture(texture_target, new_test_run.parent_texture_object_id);
2810 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
2812 if (texture_type != TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED)
2814 TextureViewUtilities::initTextureStorage(gl, (texture_type == TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT),
2815 texture_target, parent_texture_depth, parent_texture_height,
2816 parent_texture_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
2817 n_levels_needed, n_cubemaps_needed, 0); /* bo_id */
2820 /* Update expected view-specific property values to include interactions
2821 * with immutable textures. */
2822 if (texture_type == TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT ||
2823 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
2824 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
2826 /* Set expected GL_TEXTURE_IMMUTABLE_LEVELS property value to the number
2827 * of levels we'll be using for the immutable texture storage. For selected
2828 * texture targets that do no take <levels> argument, we'll change this
2829 * value on a case-by-case basis.
2831 new_test_run.expected_n_immutable_levels = n_levels_needed;
2833 /* Set expected GL_TEXTURE_VIEW_NUM_LAYERS property value to 1, as per GL spec.
2834 * This value will be modified for selected texture targets */
2835 new_test_run.expected_n_num_layers = 1;
2837 /* Configured expected GL_TEXTURE_VIEW_NUM_LEVELS value as per GL spec */
2838 new_test_run.expected_n_num_levels = n_levels_needed;
2840 /* Initialize immutable texture storage */
2841 switch (texture_target)
2843 case GL_TEXTURE_1D_ARRAY:
2845 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
2846 new_test_run.expected_n_num_layers = texture_height;
2851 case GL_TEXTURE_CUBE_MAP:
2853 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
2854 new_test_run.expected_n_num_layers = 6;
2859 case GL_TEXTURE_RECTANGLE:
2861 new_test_run.expected_n_immutable_levels = 1;
2862 new_test_run.expected_n_num_levels = 1;
2867 case GL_TEXTURE_2D_ARRAY:
2869 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
2870 new_test_run.expected_n_num_layers = texture_depth;
2875 case GL_TEXTURE_2D_MULTISAMPLE:
2877 /* 2D multisample texture are not mip-mapped, so update
2878 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
2879 * value accordingly */
2880 new_test_run.expected_n_immutable_levels = 1;
2881 new_test_run.expected_n_num_levels = 1;
2886 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
2888 /* 2D multisample array textures are not mip-mapped, so update
2889 * expected GL_TEXTURE_IMMUTABLE_LEVELS and GL_TEXTURE_VIEW_NUM_LEVELS
2890 * values accordingly */
2891 new_test_run.expected_n_immutable_levels = 1;
2892 new_test_run.expected_n_num_levels = 1;
2894 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
2895 new_test_run.expected_n_num_layers = texture_depth;
2900 case GL_TEXTURE_CUBE_MAP_ARRAY:
2902 const unsigned int actual_texture_depth = 6 /* layer-faces */ * n_cubemaps_needed;
2904 /* Update expected GL_TEXTURE_VIEW_NUM_LAYERS property value as per GL specification */
2905 new_test_run.expected_n_num_layers = actual_texture_depth;
2909 } /* switch (texture_target) */
2912 /* Initialize the view(s) */
2913 if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
2914 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW)
2916 const unsigned int n_iterations =
2917 (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) ? 2 : 1;
2919 for (unsigned int n_iteration = 0; n_iteration < n_iterations; ++n_iteration)
2921 glw::GLuint* parent_id_ptr = (n_iteration == 0) ?
2922 &new_test_run.parent_texture_object_id :
2923 &new_test_run.texture_view_object_created_from_immutable_to_id;
2924 glw::GLuint* view_id_ptr = (n_iteration == 0) ?
2925 &new_test_run.texture_view_object_created_from_immutable_to_id :
2926 &new_test_run.texture_view_object_created_from_view_to_id;
2928 gl.genTextures(1, view_id_ptr);
2929 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
2931 gl.textureView(*view_id_ptr, new_test_run.texture_target, *parent_id_ptr,
2932 GL_RGBA8, /* use the parent texture object's internalformat */
2933 n_min_level, n_num_levels, n_min_layer, n_num_layers);
2934 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
2936 /* Query parent object's properties */
2937 glw::GLint parent_min_level = -1;
2938 glw::GLint parent_min_layer = -1;
2939 glw::GLint parent_num_layers = -1;
2940 glw::GLint parent_num_levels = -1;
2941 glw::GLint parent_n_immutable_levels = -1;
2943 gl.bindTexture(texture_target, *parent_id_ptr);
2944 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
2946 gl.getTexParameteriv(texture_target, GL_TEXTURE_IMMUTABLE_LEVELS, &parent_n_immutable_levels);
2947 GLU_EXPECT_NO_ERROR(
2949 "glGetTexParameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname queried for parent object");
2951 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LAYER, &parent_min_layer);
2952 GLU_EXPECT_NO_ERROR(
2954 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname queried for parent object");
2956 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_MIN_LEVEL, &parent_min_level);
2957 GLU_EXPECT_NO_ERROR(
2959 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname queried for parent object");
2961 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LAYERS, &parent_num_layers);
2962 GLU_EXPECT_NO_ERROR(
2964 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname queried for parent object");
2966 gl.getTexParameteriv(texture_target, GL_TEXTURE_VIEW_NUM_LEVELS, &parent_num_levels);
2967 GLU_EXPECT_NO_ERROR(
2969 "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname queried for parent object");
2971 /* Update test run-specific expected values as per GL_ARB_texture_view extension specification */
2973 * - TEXTURE_IMMUTABLE_LEVELS is set to the value of TEXTURE_IMMUTABLE_LEVELS
2974 * from the original texture.
2976 new_test_run.expected_n_immutable_levels = parent_n_immutable_levels;
2979 * - TEXTURE_VIEW_MIN_LEVEL is set to <minlevel> plus the value of
2980 * TEXTURE_VIEW_MIN_LEVEL from the original texture.
2982 new_test_run.expected_n_min_level = n_min_level + parent_min_level;
2985 * - TEXTURE_VIEW_MIN_LAYER is set to <minlayer> plus the value of
2986 * TEXTURE_VIEW_MIN_LAYER from the original texture.
2988 new_test_run.expected_n_min_layer = n_min_layer + parent_min_layer;
2991 * - TEXTURE_VIEW_NUM_LAYERS is set to the lesser of <numlayers> and the
2992 * value of TEXTURE_VIEW_NUM_LAYERS from the original texture minus
2996 if ((parent_num_layers - n_min_layer) < n_num_layers)
2998 new_test_run.expected_n_num_layers = parent_num_layers - n_min_layer;
3002 new_test_run.expected_n_num_layers = n_num_layers;
3006 * - TEXTURE_VIEW_NUM_LEVELS is set to the lesser of <numlevels> and the
3007 * value of TEXTURE_VIEW_NUM_LEVELS from the original texture minus
3011 if ((parent_num_levels - n_min_level) < n_num_levels)
3013 new_test_run.expected_n_num_levels = parent_num_levels - n_min_level;
3017 new_test_run.expected_n_num_levels = n_num_levels;
3019 } /* for (all iterations) */
3020 } /* if (texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT ||
3021 texture_type == TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW) */
3023 /* Store the descriptor */
3024 m_test_runs.push_back(new_test_run);
3025 } /* for (all texture targets) */
3026 } /* for (all texture types) */
3029 /** Executes test iteration.
3031 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3033 tcu::TestNode::IterateResult TextureViewTestGetTexParameter::iterate()
3035 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3037 /* Make sure GL_ARB_texture_view is reported as supported before carrying on
3038 * with actual execution */
3039 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
3041 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
3043 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
3046 /* Initialize all objects necessary to execute the test */
3049 /* Iterate through all test runs and issue the queries */
3050 for (_test_runs_const_iterator test_run_iterator = m_test_runs.begin(); test_run_iterator != m_test_runs.end();
3051 test_run_iterator++)
3053 glw::GLfloat query_texture_immutable_levels_value_float = -1.0f;
3054 glw::GLint query_texture_immutable_levels_value_int = -1;
3055 glw::GLfloat query_texture_view_min_layer_value_float = -1.0f;
3056 glw::GLint query_texture_view_min_layer_value_int = -1;
3057 glw::GLfloat query_texture_view_min_level_value_float = -1.0f;
3058 glw::GLint query_texture_view_min_level_value_int = -1;
3059 glw::GLfloat query_texture_view_num_layers_value_float = -1.0f;
3060 glw::GLint query_texture_view_num_layers_value_int = -1;
3061 glw::GLfloat query_texture_view_num_levels_value_float = -1.0f;
3062 glw::GLint query_texture_view_num_levels_value_int = -1;
3063 const _test_run& test_run = *test_run_iterator;
3064 glw::GLint texture_object_id = 0;
3066 switch (test_run.texture_type)
3068 case TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT:
3069 texture_object_id = test_run.parent_texture_object_id;
3071 case TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT:
3072 texture_object_id = test_run.parent_texture_object_id;
3074 case TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED:
3075 texture_object_id = test_run.parent_texture_object_id;
3077 case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT:
3078 texture_object_id = test_run.texture_view_object_created_from_immutable_to_id;
3080 case TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW:
3081 texture_object_id = test_run.texture_view_object_created_from_view_to_id;
3086 TCU_FAIL("Unrecognized texture type");
3090 /* Bind the texture object of our interest to the target */
3091 gl.bindTexture(test_run.texture_target, texture_object_id);
3092 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3094 /* Run all the queries */
3095 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
3096 &query_texture_immutable_levels_value_float);
3097 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
3099 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_IMMUTABLE_LEVELS,
3100 &query_texture_immutable_levels_value_int);
3101 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexPrameteriv() failed for GL_TEXTURE_IMMUTABLE_LEVELS pname");
3103 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
3104 &query_texture_view_min_layer_value_float);
3105 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
3107 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LAYER,
3108 &query_texture_view_min_layer_value_int);
3109 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LAYER pname");
3111 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
3112 &query_texture_view_min_level_value_float);
3113 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
3115 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_MIN_LEVEL,
3116 &query_texture_view_min_level_value_int);
3117 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_MIN_LEVEL pname");
3119 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
3120 &query_texture_view_num_layers_value_float);
3121 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
3123 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LAYERS,
3124 &query_texture_view_num_layers_value_int);
3125 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LAYERS pname");
3127 gl.getTexParameterfv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
3128 &query_texture_view_num_levels_value_float);
3129 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
3131 gl.getTexParameteriv(test_run.texture_target, GL_TEXTURE_VIEW_NUM_LEVELS,
3132 &query_texture_view_num_levels_value_int);
3133 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv() failed for GL_TEXTURE_VIEW_NUM_LEVELS pname");
3135 /* Verify the results */
3136 const float epsilon = 1e-5f;
3138 if (de::abs(query_texture_immutable_levels_value_float - (float)test_run.expected_n_immutable_levels) > epsilon)
3140 m_testCtx.getLog() << tcu::TestLog::Message
3141 << "Invalid floating-point value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
3142 << "(expected: " << test_run.expected_n_immutable_levels
3143 << " found: " << query_texture_immutable_levels_value_float << ")."
3144 << tcu::TestLog::EndMessage;
3146 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
3149 if (query_texture_immutable_levels_value_int != test_run.expected_n_immutable_levels)
3151 m_testCtx.getLog() << tcu::TestLog::Message
3152 << "Invalid integer value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname "
3153 << "(expected: " << test_run.expected_n_immutable_levels
3154 << " found: " << query_texture_immutable_levels_value_int << ")."
3155 << tcu::TestLog::EndMessage;
3157 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_IMMUTABLE_LEVELS pname");
3160 if (de::abs(query_texture_view_min_layer_value_float - (float)test_run.expected_n_min_layer) > epsilon)
3162 m_testCtx.getLog() << tcu::TestLog::Message
3163 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
3164 << "(expected: " << test_run.expected_n_min_layer
3165 << " found: " << query_texture_view_min_layer_value_float << ")."
3166 << tcu::TestLog::EndMessage;
3168 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
3171 if (query_texture_view_min_layer_value_int != test_run.expected_n_min_layer)
3173 m_testCtx.getLog() << tcu::TestLog::Message
3174 << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LAYER pname "
3175 << "(expected: " << test_run.expected_n_min_layer
3176 << " found: " << query_texture_view_min_layer_value_int << ")."
3177 << tcu::TestLog::EndMessage;
3179 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LAYER pname");
3182 if (de::abs(query_texture_view_min_level_value_float - (float)test_run.expected_n_min_level) > epsilon)
3184 m_testCtx.getLog() << tcu::TestLog::Message
3185 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
3186 << "(expected: " << test_run.expected_n_min_level
3187 << " found: " << query_texture_view_min_level_value_float << ")."
3188 << tcu::TestLog::EndMessage;
3190 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
3193 if (query_texture_view_min_level_value_int != test_run.expected_n_min_level)
3195 m_testCtx.getLog() << tcu::TestLog::Message
3196 << "Invalid integer value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname "
3197 << "(expected: " << test_run.expected_n_min_level
3198 << " found: " << query_texture_view_min_level_value_int << ")."
3199 << tcu::TestLog::EndMessage;
3201 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_MIN_LEVEL pname");
3204 if (de::abs(query_texture_view_num_layers_value_float - (float)test_run.expected_n_num_layers) > epsilon)
3206 m_testCtx.getLog() << tcu::TestLog::Message
3207 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
3208 << "(expected: " << test_run.expected_n_num_layers
3209 << " found: " << query_texture_view_num_layers_value_float << ")."
3210 << tcu::TestLog::EndMessage;
3212 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
3215 if (query_texture_view_num_layers_value_int != test_run.expected_n_num_layers)
3217 m_testCtx.getLog() << tcu::TestLog::Message
3218 << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname "
3219 << "(expected: " << test_run.expected_n_num_layers
3220 << " found: " << query_texture_view_num_layers_value_int << ")."
3221 << tcu::TestLog::EndMessage;
3223 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LAYERS pname");
3226 if (de::abs(query_texture_view_num_levels_value_float - (float)test_run.expected_n_num_levels) > epsilon)
3228 m_testCtx.getLog() << tcu::TestLog::Message
3229 << "Invalid floating-point value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
3230 << "(expected: " << test_run.expected_n_num_levels
3231 << " found: " << query_texture_view_num_levels_value_float << ")."
3232 << tcu::TestLog::EndMessage;
3234 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
3237 if (query_texture_view_num_levels_value_int != test_run.expected_n_num_levels)
3239 m_testCtx.getLog() << tcu::TestLog::Message
3240 << "Invalid integer value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname "
3241 << "(expected: " << test_run.expected_n_num_levels
3242 << " found: " << query_texture_view_num_levels_value_int << ")."
3243 << tcu::TestLog::EndMessage;
3245 TCU_FAIL("Invalid FP value reported for GL_TEXTURE_VIEW_NUM_LEVELS pname");
3247 } /* for (all test runs) */
3249 /* Test case passed */
3250 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3257 * @param context Rendering context
3259 TextureViewTestErrors::TextureViewTestErrors(deqp::Context& context)
3260 : TestCase(context, "errors", "test_description")
3262 , m_reference_immutable_to_1d_id(0)
3263 , m_reference_immutable_to_2d_id(0)
3264 , m_reference_immutable_to_2d_array_id(0)
3265 , m_reference_immutable_to_2d_array_32_by_33_id(0)
3266 , m_reference_immutable_to_2d_multisample_id(0)
3267 , m_reference_immutable_to_3d_id(0)
3268 , m_reference_immutable_to_cube_map_id(0)
3269 , m_reference_immutable_to_cube_map_array_id(0)
3270 , m_reference_immutable_to_rectangle_id(0)
3271 , m_reference_mutable_to_2d_id(0)
3272 , m_test_modified_to_id_1(0)
3273 , m_test_modified_to_id_2(0)
3274 , m_test_modified_to_id_3(0)
3275 , m_view_bound_to_id(0)
3276 , m_view_never_bound_to_id(0)
3278 /* Left blank on purpose */
3281 /** Deinitializes all GL objects that may have been generated for the test. */
3282 void TextureViewTestErrors::deinit()
3284 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3288 gl.deleteBuffers(1, &m_bo_id);
3293 if (m_reference_immutable_to_1d_id != 0)
3295 gl.deleteTextures(1, &m_reference_immutable_to_1d_id);
3297 m_reference_immutable_to_1d_id = 0;
3300 if (m_reference_immutable_to_2d_id != 0)
3302 gl.deleteTextures(1, &m_reference_immutable_to_2d_id);
3304 m_reference_immutable_to_2d_id = 0;
3307 if (m_reference_immutable_to_2d_array_id != 0)
3309 gl.deleteTextures(1, &m_reference_immutable_to_2d_array_id);
3311 m_reference_immutable_to_2d_array_id = 0;
3314 if (m_reference_immutable_to_2d_array_32_by_33_id != 0)
3316 gl.deleteTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id);
3318 m_reference_immutable_to_2d_array_32_by_33_id = 0;
3321 if (m_reference_immutable_to_2d_multisample_id != 0)
3323 gl.deleteTextures(1, &m_reference_immutable_to_2d_multisample_id);
3325 m_reference_immutable_to_2d_multisample_id = 0;
3328 if (m_reference_immutable_to_3d_id != 0)
3330 gl.deleteTextures(1, &m_reference_immutable_to_3d_id);
3332 m_reference_immutable_to_3d_id = 0;
3335 if (m_reference_immutable_to_cube_map_id != 0)
3337 gl.deleteTextures(1, &m_reference_immutable_to_cube_map_id);
3339 m_reference_immutable_to_cube_map_id = 0;
3342 if (m_reference_immutable_to_cube_map_array_id != 0)
3344 gl.deleteTextures(1, &m_reference_immutable_to_cube_map_array_id);
3346 m_reference_immutable_to_cube_map_array_id = 0;
3349 if (m_reference_immutable_to_rectangle_id != 0)
3351 gl.deleteTextures(1, &m_reference_immutable_to_rectangle_id);
3353 m_reference_immutable_to_rectangle_id = 0;
3356 if (m_reference_mutable_to_2d_id != 0)
3358 gl.deleteTextures(1, &m_reference_mutable_to_2d_id);
3360 m_reference_mutable_to_2d_id = 0;
3363 if (m_test_modified_to_id_1 != 0)
3365 gl.deleteTextures(1, &m_test_modified_to_id_1);
3367 m_test_modified_to_id_1 = 0;
3370 if (m_test_modified_to_id_2 != 0)
3372 gl.deleteTextures(1, &m_test_modified_to_id_2);
3374 m_test_modified_to_id_2 = 0;
3377 if (m_test_modified_to_id_3 != 0)
3379 gl.deleteTextures(1, &m_test_modified_to_id_3);
3381 m_test_modified_to_id_3 = 0;
3384 if (m_view_bound_to_id != 0)
3386 gl.deleteTextures(1, &m_view_bound_to_id);
3388 m_view_bound_to_id = 0;
3391 if (m_view_never_bound_to_id != 0)
3393 gl.deleteTextures(1, &m_view_never_bound_to_id);
3395 m_view_never_bound_to_id = 0;
3399 /** Executes test iteration.
3401 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3403 tcu::TestNode::IterateResult TextureViewTestErrors::iterate()
3405 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3407 /* Make sure GL_ARB_texture_view is reported as supported before carrying on
3408 * with actual execution */
3409 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
3411 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
3413 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
3416 /* Create a buffer object that we'll need to use to define storage of
3417 * buffer textures */
3418 gl.genBuffers(1, &m_bo_id);
3419 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed");
3421 gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo_id);
3422 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed");
3424 gl.bufferData(GL_TEXTURE_BUFFER, 123, /* arbitrary size */
3427 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed");
3429 /* Create reference texture objects */
3430 const glw::GLint reference_bo_id = m_bo_id;
3431 const glw::GLint reference_to_depth = 2;
3432 const glw::GLenum reference_to_format = GL_RGBA;
3433 const glw::GLint reference_to_height = 64;
3434 const glw::GLenum reference_to_internalformat = GL_RGBA32F;
3435 const glw::GLint reference_n_cubemaps = 1;
3436 const glw::GLint reference_n_levels = 1;
3437 const glw::GLenum reference_to_type = GL_FLOAT;
3438 const glw::GLint reference_to_width = 64;
3440 gl.genTextures(1, &m_reference_immutable_to_1d_id);
3441 gl.genTextures(1, &m_reference_immutable_to_2d_id);
3442 gl.genTextures(1, &m_reference_immutable_to_2d_array_id);
3443 gl.genTextures(1, &m_reference_immutable_to_2d_array_32_by_33_id);
3444 gl.genTextures(1, &m_reference_immutable_to_2d_multisample_id);
3445 gl.genTextures(1, &m_reference_immutable_to_3d_id);
3446 gl.genTextures(1, &m_reference_immutable_to_cube_map_id);
3447 gl.genTextures(1, &m_reference_immutable_to_cube_map_array_id);
3448 gl.genTextures(1, &m_reference_immutable_to_rectangle_id);
3449 gl.genTextures(1, &m_reference_mutable_to_2d_id);
3450 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
3452 /* Retrieve GL_SAMPLES value - we'll need it to initialize multisample storage */
3453 glw::GLint gl_max_samples_value = 0;
3455 gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, reference_to_internalformat, GL_SAMPLES,
3456 1 /* bufSize - first result */, &gl_max_samples_value);
3457 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_SAMPLES pname");
3459 /* Set up texture storage for single-dimensional texture object */
3460 gl.bindTexture(GL_TEXTURE_1D, m_reference_immutable_to_1d_id);
3461 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3463 gl.texStorage1D(GL_TEXTURE_1D, reference_n_levels, reference_to_internalformat, reference_to_width);
3464 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed");
3466 /* Set up immutable texture storage for two-dimensional texture object */
3467 gl.bindTexture(GL_TEXTURE_2D, m_reference_immutable_to_2d_id);
3468 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3470 gl.texStorage2D(GL_TEXTURE_2D, reference_n_levels, reference_to_internalformat, reference_to_width,
3471 reference_to_height);
3472 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
3474 /* Set up immutable texture storage for two-dimensional array texture object */
3475 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id);
3476 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3478 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width,
3479 reference_to_height, reference_to_depth);
3480 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
3482 /* Set up immutable texture storage for two-dimensional array texture object, base
3483 * level of which uses a resolution of 32x33. We'll need it to check case r) */
3484 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id);
3485 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3487 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, reference_n_levels, reference_to_internalformat, 32, /* width */
3489 6); /* depth - 6 layers so that a cube-map/cube-map array view can be created from this texture */
3490 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
3492 /* Set up immutable texture storage for two-dimensional multisample texture object */
3493 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id);
3494 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3496 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, gl_max_samples_value, reference_to_internalformat,
3497 reference_to_width, reference_to_height, GL_TRUE); /* fixedsamplelocations */
3498 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed");
3500 /* Set up immutable texture storage for three-dimensional texture object */
3501 gl.bindTexture(GL_TEXTURE_3D, m_reference_immutable_to_3d_id);
3502 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3504 gl.texStorage3D(GL_TEXTURE_3D, reference_n_levels, reference_to_internalformat, reference_to_width,
3505 reference_to_height, reference_to_depth);
3506 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed");
3508 /* Set up immutable texture storage for cube-map texture object */
3509 gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id);
3510 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3512 gl.texStorage2D(GL_TEXTURE_CUBE_MAP, reference_n_levels, reference_to_internalformat, reference_to_width,
3513 reference_to_height);
3514 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
3516 /* Set up immutable texture storage for cube-map array texture object */
3517 gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id);
3518 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3520 gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, reference_n_levels, reference_to_internalformat, reference_to_width,
3521 reference_to_height, 6 /* layer-faces */ * reference_to_depth);
3522 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
3524 /* Set up immutable texture storage for rectangular texture object */
3525 gl.bindTexture(GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id);
3526 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3528 gl.texStorage2D(GL_TEXTURE_RECTANGLE, reference_n_levels, reference_to_internalformat, reference_to_width,
3529 reference_to_height);
3530 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
3532 /* Set up mutable texture storage for two-dimensional texture object */
3533 gl.bindTexture(GL_TEXTURE_2D, m_reference_mutable_to_2d_id);
3534 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3536 for (glw::GLint n_level = 0; n_level < reference_n_levels; ++n_level)
3538 gl.texImage2D(GL_TEXTURE_2D, n_level, reference_to_internalformat, reference_to_width << n_level,
3539 reference_to_height << n_level, 0, /* border */
3540 reference_to_format, reference_to_type, DE_NULL); /* pixels */
3542 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed");
3545 /* Create texture objects we'll be attempting to define as texture views */
3546 gl.genTextures(1, &m_view_bound_to_id);
3547 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
3549 gl.genTextures(1, &m_view_never_bound_to_id);
3550 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
3552 gl.bindTexture(GL_TEXTURE_2D, m_view_bound_to_id);
3553 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3555 /* a) GL_INVALID_VALUE should be generated if <texture> is 0. */
3556 glw::GLint error_code = GL_NO_ERROR;
3558 gl.textureView(0, /* texture */
3559 GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat, 0, /* minlevel */
3560 reference_n_levels, 0, /* minlayer */
3563 error_code = gl.getError();
3564 if (error_code != GL_INVALID_VALUE)
3566 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3568 " error generated when passing <texture> argument of 0"
3569 " to a glTextureView(), whereas GL_INVALID_VALUE was "
3571 << tcu::TestLog::EndMessage;
3573 TCU_FAIL("GL_INVALID_VALUE not generated when passing 0 as <texture> argument to a "
3574 "glTextureView() call.");
3577 /* b) GL_INVALID_OPERATION should be generated if <texture> is not
3578 * a valid name returned by glGenTextures().
3580 const glw::GLint invalid_to_id = 0xFFFFFFFF;
3582 gl.textureView(invalid_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
3584 reference_n_levels, 0, /* minlayer */
3587 error_code = gl.getError();
3588 if (error_code != GL_INVALID_OPERATION)
3590 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3592 " error generated when passing <texture> argument of"
3593 " value that does not correspond to a valid texture "
3594 "object ID, whereas GL_INVALID_OPERATION was expected."
3595 << tcu::TestLog::EndMessage;
3597 TCU_FAIL("GL_INVALID_OPERATION not generated when passing 0xFFFFFFFF as <texture> "
3598 "argument to a glTextureView() call.");
3601 /* c) GL_INVALID_OPERATION should be generated if <texture> has
3602 * already been bound and given a target.
3604 gl.textureView(m_view_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
3606 reference_n_levels, 0, /* minlayer */
3609 error_code = gl.getError();
3610 if (error_code != GL_INVALID_OPERATION)
3612 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3614 " error generated when passing <texture> argument "
3615 " that refers to an ID of a texture object that has "
3616 "already been bound to a texture target, whereas "
3617 "GL_INVALID_OPERATION was expected."
3618 << tcu::TestLog::EndMessage;
3620 TCU_FAIL("GL_INVALID_OPERATION not generated when passing <texture> set"
3621 " to an ID of a texture object, that has already been bound to"
3622 " a texture target, to a glTextureView() call.");
3625 /* d) GL_INVALID_VALUE should be generated if <origtexture> is not
3626 * the name of a texture object.
3628 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, invalid_to_id, reference_to_internalformat,
3630 reference_n_levels, 0, /* minlayer */
3633 error_code = gl.getError();
3634 if (error_code != GL_INVALID_VALUE)
3636 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3638 " error generated when passing <origtexture> argument "
3639 " of value 0xFFFFFFFF, whereas GL_INVALID_VALUE was "
3641 << tcu::TestLog::EndMessage;
3643 TCU_FAIL("GL_INVALID_VALUE not generated when passing an invalid ID of a texture "
3644 "object to <origtexture> argument.");
3647 /* e) GL_INVALID_OPERATION error should be generated if <origtexture>
3648 * is a mutable texture object.
3650 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_mutable_to_2d_id, reference_to_internalformat,
3652 reference_n_levels, 0, /* minlayer */
3655 error_code = gl.getError();
3656 if (error_code != GL_INVALID_OPERATION)
3658 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3660 " error generated when passing <origtexture> argument "
3661 " set to refer to a mutable texture object, whereas "
3662 "GL_INVALID_OPERATION was expected."
3663 << tcu::TestLog::EndMessage;
3665 TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable "
3666 "texture object through <origtexture> argument.");
3669 /* f) GL_INVALID_OPERATION error should be generated whenever the
3670 * application tries to generate a texture view for a target
3671 * that is incompatible with original texture's target. (as per
3672 * table 8.20 from OpenGL 4.3 specification)
3674 * NOTE: All invalid original+view texture target combinations
3675 * should be checked.
3677 TextureViewUtilities::_incompatible_texture_target_pairs incompatible_texture_target_pairs =
3678 TextureViewUtilities::getIllegalTextureAndViewTargetCombinations();
3680 for (TextureViewUtilities::_incompatible_texture_target_pairs_const_iterator pair_iterator =
3681 incompatible_texture_target_pairs.begin();
3682 pair_iterator != incompatible_texture_target_pairs.end(); pair_iterator++)
3684 TextureViewUtilities::_internalformat_pair texture_target_pair = *pair_iterator;
3685 glw::GLenum original_texture_target = texture_target_pair.first;
3686 glw::GLenum view_texture_target = texture_target_pair.second;
3688 /* Generate texture IDs */
3689 gl.genTextures(1, &m_test_modified_to_id_1);
3690 gl.genTextures(1, &m_test_modified_to_id_2);
3691 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
3693 /* Configure reference texture object storage */
3694 gl.bindTexture(original_texture_target, m_test_modified_to_id_1);
3695 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3697 TextureViewUtilities::initTextureStorage(gl, true, /* create mutable parent texture */
3698 original_texture_target, reference_to_depth, reference_to_height,
3699 reference_to_width, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
3700 reference_n_levels, reference_n_cubemaps, reference_bo_id);
3702 /* Attempt to create the invalid view */
3703 gl.textureView(m_test_modified_to_id_2, /* texture */
3704 view_texture_target, m_test_modified_to_id_1, /* origtexture */
3705 reference_to_internalformat, 0, /* minlevel */
3706 reference_n_levels, 0, /* minlayer */
3709 error_code = gl.getError();
3710 if (error_code != GL_INVALID_OPERATION)
3712 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3714 " error generated when passing <origtexture> argument "
3715 " set to refer to a mutable texture object, whereas "
3716 "GL_INVALID_OPERATION was expected."
3717 << tcu::TestLog::EndMessage;
3719 TCU_FAIL("GL_INVALID_OPERATION not generated when passing an ID of a mutable "
3720 "texture object through <origtexture> argument.");
3723 /* Release the texture IDs */
3724 gl.deleteTextures(1, &m_test_modified_to_id_1);
3725 m_test_modified_to_id_1 = 0;
3727 gl.deleteTextures(1, &m_test_modified_to_id_2);
3728 m_test_modified_to_id_2 = 0;
3730 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
3731 } /* for (all incompatible texture target pairs) */
3733 /* g) GL_INVALID_OPERATION error should be generated whenever the
3734 * application tries to create a texture view, internal format
3735 * of which can be found in table 8.21 of OpenGL 4.4
3736 * specification, and the texture view's internal format is
3737 * incompatible with parent object's internal format. Both
3738 * textures and views should be used as parent objects for the
3739 * purpose of the test.
3741 * NOTE: All invalid texture view internal formats should be
3742 * checked for all applicable original object's internal
3745 glw::GLint context_major_version = 0;
3746 glw::GLint context_minor_version = 0;
3748 TextureViewUtilities::getMajorMinorVersionFromContextVersion(m_context.getRenderContext().getType(),
3749 &context_major_version, &context_minor_version);
3751 TextureViewUtilities::_incompatible_internalformat_pairs internalformat_pairs =
3752 TextureViewUtilities::getIllegalTextureAndViewInternalformatCombinations();
3754 for (TextureViewUtilities::_incompatible_internalformat_pairs::const_iterator pair_iterator =
3755 internalformat_pairs.begin();
3756 pair_iterator != internalformat_pairs.end(); pair_iterator++)
3758 glw::GLenum src_internalformat = pair_iterator->first;
3759 glw::GLenum view_internalformat = pair_iterator->second;
3761 /* Only run the test for internalformats supported by the tested OpenGL implementation */
3762 if (!TextureViewUtilities::isInternalformatSupported(src_internalformat, context_major_version,
3763 context_minor_version) ||
3764 !TextureViewUtilities::isInternalformatSupported(view_internalformat, context_major_version,
3765 context_minor_version))
3767 /* Next iteration, please */
3771 /* Generate texture IDs */
3772 gl.genTextures(1, &m_test_modified_to_id_1);
3773 gl.genTextures(1, &m_test_modified_to_id_2);
3774 gl.genTextures(1, &m_test_modified_to_id_3);
3775 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
3777 /* Configure reference texture object storage */
3778 gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1);
3779 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3781 TextureViewUtilities::initTextureStorage(
3782 gl, false, /* views require immutable parent texture objects */
3783 GL_TEXTURE_2D, 0, /* texture_depth */
3784 reference_to_height, reference_to_width, src_internalformat,
3785 GL_NONE, /* texture_format - not needed for immutable texture objects */
3786 GL_NONE, /* texture_type - not needed for immutable texture objects */
3787 reference_n_levels, 0, /* n_cubemaps_needed */
3790 /* Attempt to create an invalid view */
3791 gl.textureView(m_test_modified_to_id_2, /* texture */
3792 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */
3793 view_internalformat, 0, /* minlevel */
3794 reference_n_levels, 0, /* minlayer */
3797 error_code = gl.getError();
3798 if (error_code != GL_INVALID_OPERATION)
3800 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3802 " error generated when requesting a view that uses "
3803 " an internalformat that is incompatible with parent "
3804 " texture object's, whereas GL_INVALID_OPERATION was "
3806 << tcu::TestLog::EndMessage;
3808 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that "
3809 "uses an internalformat which is incompatible with parent texture's.");
3812 /* Create a valid view now */
3813 gl.textureView(m_test_modified_to_id_2, /* texture */
3814 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */
3815 src_internalformat, 0, /* minlevel */
3816 reference_n_levels, 0, /* minlayer */
3819 GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glTextureView() call failed");
3821 /* Attempt to create an invalid view, using the view we've just created
3823 gl.textureView(m_test_modified_to_id_3, /* texture */
3824 GL_TEXTURE_2D, m_test_modified_to_id_2, /* origtexture */
3825 view_internalformat, 0, /* minlevel */
3826 reference_n_levels, 0, /* minlayer */
3829 error_code = gl.getError();
3830 if (error_code != GL_INVALID_OPERATION)
3832 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3834 " error generated when requesting a view that uses "
3835 " an internalformat that is incompatible with parent "
3836 " view's, whereas GL_INVALID_OPERATION was expected."
3837 << tcu::TestLog::EndMessage;
3839 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view that "
3840 "uses an internalformat which is incompatible with parent view's.");
3843 /* Release the texture IDs */
3844 gl.deleteTextures(1, &m_test_modified_to_id_1);
3845 m_test_modified_to_id_1 = 0;
3847 gl.deleteTextures(1, &m_test_modified_to_id_2);
3848 m_test_modified_to_id_2 = 0;
3850 gl.deleteTextures(1, &m_test_modified_to_id_3);
3851 m_test_modified_to_id_3 = 0;
3853 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
3854 } /* for (all incompatible texture+view internalformat pairs) */
3856 /* h) GL_INVALID_OPERATION error should be generated whenever the
3857 * application tries to create a texture view using an internal
3858 * format that does not match the original texture's, and the
3859 * original texture's internalformat cannot be found in table
3860 * 8.21 of OpenGL 4.3 specification.
3862 * NOTE: All required base, sized and compressed texture internal
3863 * formats (as described in section 8.5.1 and table 8.14
3864 * of OpenGL 4.3 specification) that cannot be found in
3865 * table 8.21 should be considered for the purpose of this
3868 for (int n_gl_internalformat = 0; n_gl_internalformat < n_valid_gl_internalformats; ++n_gl_internalformat)
3870 glw::GLenum parent_texture_internalformat = valid_gl_internalformats[n_gl_internalformat];
3872 /* Only run the test for internalformats supported by the tested OpenGL implementation */
3873 if (!TextureViewUtilities::isInternalformatSupported(parent_texture_internalformat, context_major_version,
3874 context_minor_version))
3876 /* Iterate the loop */
3880 /* For the purpose of the test, only consider internalformats that
3881 * are not associated with any view class */
3882 if (TextureViewUtilities::getViewClassForInternalformat(parent_texture_internalformat) == VIEW_CLASS_UNDEFINED)
3884 /* Initialize parent texture object */
3885 gl.genTextures(1, &m_test_modified_to_id_1);
3886 gl.genTextures(1, &m_test_modified_to_id_2);
3887 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
3889 /* Configure reference texture object storage */
3890 gl.bindTexture(GL_TEXTURE_2D, m_test_modified_to_id_1);
3891 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
3893 TextureViewUtilities::initTextureStorage(
3894 gl, false, /* views require immutable parent texture objects */
3895 GL_TEXTURE_2D, 0, /* texture_depth */
3896 reference_to_height, reference_to_width, parent_texture_internalformat,
3897 GL_NONE, /* texture_format - not needed for immutable texture objects */
3898 GL_NONE, /* texture_type - not needed for immutable texture objects */
3899 reference_n_levels, 0, /* n_cubemaps_needed */
3902 /* Attempt to create the invalid view */
3903 gl.textureView(m_test_modified_to_id_2, /* texture */
3904 GL_TEXTURE_2D, m_test_modified_to_id_1, /* origtexture */
3905 (parent_texture_internalformat != GL_RGBA32F) ? GL_RGBA32F : GL_RGB32F, 0, /* minlevel */
3906 reference_n_levels, 0, /* minlayer */
3909 error_code = gl.getError();
3910 if (error_code != GL_INVALID_OPERATION)
3912 m_testCtx.getLog() << tcu::TestLog::Message << "["
3913 << TextureViewUtilities::getErrorCodeString(error_code)
3915 " error generated when requesting a view that uses "
3916 " an internalformat different than the one used by "
3917 "parent texture object: "
3919 << parent_texture_internalformat
3921 " and the parent texture's internalformat is not "
3922 "associated with any view class; GL_INVALID_OPERATION "
3924 << tcu::TestLog::EndMessage;
3926 TCU_FAIL("GL_INVALID_OPERATION not generated when requesting a texture view for "
3927 "a parent texture, internalformat of which is not associated with any "
3928 "view class, when the view's internalformat is different than the one "
3929 "used for parent texture.");
3932 /* Release the texture IDs */
3933 gl.deleteTextures(1, &m_test_modified_to_id_1);
3934 m_test_modified_to_id_1 = 0;
3936 gl.deleteTextures(1, &m_test_modified_to_id_2);
3937 m_test_modified_to_id_2 = 0;
3939 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call(s) failed");
3940 } /* if (parent texture internalformat is not associated with a view class) */
3941 } /* for (all valid GL internalformats) */
3943 /* i) GL_INVALID_VALUE error should be generated if <minlevel> is
3944 * larger than the greatest level of <origtexture>.
3946 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
3947 reference_n_levels, /* minlevel */
3952 error_code = gl.getError();
3953 if (error_code != GL_INVALID_VALUE)
3955 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3957 " error generated when passing <minlevel> argument "
3958 " larger than the greatest level of <origtexture>, whereas "
3959 "GL_INVALID_VALUE was expected."
3960 << tcu::TestLog::EndMessage;
3962 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlevel> "
3963 "larger than the greatest level defined for <origtexture>");
3966 /* j) GL_INVALID_VALUE error should be generated if <minlayer> is
3967 * larger than the greatest layer of <origtexture>.
3969 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_ARRAY, m_reference_immutable_to_2d_array_id,
3970 reference_to_internalformat, 0, /* minlevel */
3971 reference_n_levels, /* numlevels */
3972 reference_to_depth, /* minlayer */
3975 error_code = gl.getError();
3976 if (error_code != GL_INVALID_VALUE)
3978 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
3980 " error generated when passing <minlayer> argument "
3981 " larger than the greatest layer of <origtexture>, whereas "
3982 "GL_INVALID_VALUE was expected."
3983 << tcu::TestLog::EndMessage;
3985 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of <minlayer> "
3986 "larger than the greatest layer defined for <origtexture>");
3989 /* k) GL_INVALID_VALUE error should be generated if <target> is
3990 * GL_TEXTURE_CUBE_MAP and <numlayers> is not 6.
3992 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_cube_map_id,
3993 reference_to_internalformat, 0, /* minlevel */
3996 5); /* numlayers - invalid argument value */
3998 error_code = gl.getError();
3999 if (error_code != GL_INVALID_VALUE)
4001 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4003 " error generated when passing <numlayers> argument of value "
4004 "5 instead of 6 for GL_TEXTURE_CUBE_MAP texture target, whereas "
4005 "GL_INVALID_VALUE was expected."
4006 << tcu::TestLog::EndMessage;
4008 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 5 to <minlayer>"
4012 /* l) GL_INVALID_VALUE error should be generated if <target> is
4013 * GL_TEXTURE_CUBE_MAP_ARRAY and <numlayers> is not a multiple
4016 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_cube_map_array_id,
4017 reference_to_internalformat, 0, /* minlevel */
4020 1); /* numlayers - invalid argument value */
4022 error_code = gl.getError();
4023 if (error_code != GL_INVALID_VALUE)
4025 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4027 " error generated when passing <numlayers> argument of value "
4028 "1 instead of a multiple of 6 for GL_TEXTURE_CUBE_MAP_ARRAY "
4029 "texture target, whereas GL_INVALID_VALUE was expected."
4030 << tcu::TestLog::EndMessage;
4032 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 1 to <minlayer>"
4033 "argument for a GL_TEXTURE_CUBE_MAP_ARRAY texture target");
4036 /* m) GL_INVALID_VALUE error should be generated if <target> is
4037 * GL_TEXTURE_1D and <numlayers> is not 1;
4039 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_1D, m_reference_immutable_to_1d_id, reference_to_internalformat,
4043 2); /* numlayers - invalid argument value */
4045 error_code = gl.getError();
4046 if (error_code != GL_INVALID_VALUE)
4048 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4050 " error generated when passing <numlayers> argument of value "
4051 "2 instead of 1 for GL_TEXTURE_1D texture target, whereas "
4052 "GL_INVALID_VALUE was expected."
4053 << tcu::TestLog::EndMessage;
4055 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
4056 "argument for a GL_TEXTURE_1D texture target");
4059 /* n) GL_INVALID_VALUE error should be generated if <target> is
4060 * GL_TEXTURE_2D and <numlayers> is not 1;
4062 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D, m_reference_immutable_to_2d_id, reference_to_internalformat,
4066 2); /* numlayers - invalid argument value */
4068 error_code = gl.getError();
4069 if (error_code != GL_INVALID_VALUE)
4071 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4073 " error generated when passing <numlayers> argument of value "
4074 "2 instead of 1 for GL_TEXTURE_2D texture target, whereas "
4075 "GL_INVALID_VALUE was expected."
4076 << tcu::TestLog::EndMessage;
4078 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
4079 "argument for a GL_TEXTURE_2D texture target");
4082 /* o) GL_INVALID_VALUE error should be generated if <target> is
4083 * GL_TEXTURE_3D and <numlayers> is not 1;
4085 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_3D, m_reference_immutable_to_3d_id, reference_to_internalformat,
4089 2); /* numlayers - invalid argument value */
4091 error_code = gl.getError();
4092 if (error_code != GL_INVALID_VALUE)
4094 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4096 " error generated when passing <numlayers> argument of value "
4097 "2 instead of 1 for GL_TEXTURE_3D texture target, whereas "
4098 "GL_INVALID_VALUE was expected."
4099 << tcu::TestLog::EndMessage;
4101 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
4102 "argument for a GL_TEXTURE_3D texture target");
4105 /* p) GL_INVALID_VALUE error should be generated if <target> is
4106 * GL_TEXTURE_RECTANGLE and <numlayers> is not 1;
4108 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_RECTANGLE, m_reference_immutable_to_rectangle_id,
4109 reference_to_internalformat, 0, /* minlevel */
4112 2); /* numlayers - invalid argument value */
4114 error_code = gl.getError();
4115 if (error_code != GL_INVALID_VALUE)
4117 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4119 " error generated when passing <numlayers> argument of value "
4120 "2 instead of 1 for GL_TEXTURE_RECTANGLE texture target, whereas "
4121 "GL_INVALID_VALUE was expected."
4122 << tcu::TestLog::EndMessage;
4124 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
4125 "argument for a GL_TEXTURE_RECTANGLE texture target");
4128 /* q) GL_INVALID_VALUE error should be generated if <target> is
4129 * GL_TEXTURE_2D_MULTISAMPLE and <numlayers> is not 1;
4131 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_2D_MULTISAMPLE, m_reference_immutable_to_2d_multisample_id,
4132 reference_to_internalformat, 0, /* minlevel */
4135 2); /* numlayers - invalid argument value */
4137 error_code = gl.getError();
4138 if (error_code != GL_INVALID_VALUE)
4140 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4142 " error generated when passing <numlayers> argument of value "
4143 "2 instead of 1 for GL_TEXTURE_2D_MULTISAMPLE texture target, whereas "
4144 "GL_INVALID_VALUE was expected."
4145 << tcu::TestLog::EndMessage;
4147 TCU_FAIL("GL_INVALID_VALUE not generated when passing a value of 2 to <numlayers>"
4148 "argument for a GL_TEXTURE_2D_MULTISAMPLE texture target");
4151 /* r) GL_INVALID_OPERATION error should be generated if <target> is
4152 * GL_TEXTURE_CUBE_MAP and original texture's width does not
4153 * match original texture's height for all levels.
4155 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP, m_reference_immutable_to_2d_array_32_by_33_id,
4156 reference_to_internalformat, 0, /* minlevel */
4161 error_code = gl.getError();
4162 if (error_code != GL_INVALID_OPERATION)
4164 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4166 " error generated when using an immutable 2D array texture of 32x33x6 "
4167 "resolution to generate a GL_TEXTURE_CUBE_MAP view, whereas "
4168 "GL_INVALID_OPERATION was expected."
4169 << tcu::TestLog::EndMessage;
4171 TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of "
4172 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP view");
4175 /* s) GL_INVALID_OPERATION error should be generated if <target> is
4176 * GL_TEXTURE_CUBE_MAP_ARRAY and original texture's width does
4177 * not match original texture's height for all levels.
4179 gl.textureView(m_view_never_bound_to_id, GL_TEXTURE_CUBE_MAP_ARRAY, m_reference_immutable_to_2d_array_32_by_33_id,
4180 reference_to_internalformat, 0, /* minlevel */
4185 error_code = gl.getError();
4186 if (error_code != GL_INVALID_OPERATION)
4188 m_testCtx.getLog() << tcu::TestLog::Message << "[" << TextureViewUtilities::getErrorCodeString(error_code)
4190 " error generated when using an immutable 2D array texture of 32x33x6 "
4191 "resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view, whereas "
4192 "GL_INVALID_OPERATION was expected."
4193 << tcu::TestLog::EndMessage;
4195 TCU_FAIL("GL_INVALID_OPERATION not generated when using an immutable 2D array texture of "
4196 "32x33x6 resolution to generate a GL_TEXTURE_CUBE_MAP_ARRAY view");
4199 /* Test case passed */
4200 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4207 * @param context Rendering context.
4209 TextureViewTestViewSampling::TextureViewTestViewSampling(deqp::Context& context)
4210 : TestCase(context, "view_sampling", "Verify that sampling data from texture views, that use internal "
4211 "format which is compatible with the original texture's internal "
4212 "format, works correctly.")
4217 , m_po_lod_location(-1)
4218 , m_po_n_face_location(-1)
4219 , m_po_reference_colors_location(-1)
4220 , m_po_texture_location(-1)
4221 , m_po_z_float_location(-1)
4222 , m_po_z_int_location(-1)
4226 , m_per_sample_filler_fs_id(0)
4227 , m_per_sample_filler_gs_id(0)
4228 , m_per_sample_filler_po_id(0)
4229 , m_per_sample_filler_po_layer_id_location(-1)
4230 , m_per_sample_filler_po_reference_colors_location(-1)
4231 , m_per_sample_filler_vs_id(0)
4237 , m_max_color_texture_samples_gl_value(0)
4238 , m_iteration_parent_texture_depth(0)
4239 , m_iteration_parent_texture_height(0)
4240 , m_iteration_parent_texture_n_levels(0)
4241 , m_iteration_parent_texture_n_samples(0)
4242 , m_iteration_parent_texture_target(GL_NONE)
4243 , m_iteration_parent_texture_width(0)
4244 , m_iteration_view_texture_minlayer(0)
4245 , m_iteration_view_texture_numlayers(0)
4246 , m_iteration_view_texture_minlevel(0)
4247 , m_iteration_view_texture_numlevels(0)
4248 , m_iteration_view_texture_target(GL_NONE)
4249 , m_reference_texture_depth(4)
4250 , m_reference_texture_height(4)
4251 , m_reference_texture_n_mipmaps(3)
4252 , m_reference_texture_width(4)
4253 , m_reference_color_storage(DE_NULL)
4254 , m_result_data(DE_NULL)
4256 /* Left blank on purpose */
4259 /** De-initializes all GL objects created for the test. */
4260 void TextureViewTestViewSampling::deinit()
4262 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4264 deinitIterationSpecificProgramAndShaderObjects();
4265 deinitPerSampleFillerProgramAndShaderObjects();
4266 deinitTextureObjects();
4268 /* Make sure any buffers we may have allocated during the execution do not leak */
4269 if (m_result_data != DE_NULL)
4271 delete[] m_result_data;
4273 m_result_data = DE_NULL;
4276 /* Deinitialize other objects that are not re-created every iteration */
4279 gl.deleteBuffers(1, &m_bo_id);
4286 gl.deleteFramebuffers(1, &m_fbo_id);
4291 if (m_reference_color_storage != DE_NULL)
4293 delete m_reference_color_storage;
4295 m_reference_color_storage = DE_NULL;
4300 gl.deleteVertexArrays(1, &m_vao_id);
4305 /* Restore default GL state the test may have modified */
4306 gl.patchParameteri(GL_PATCH_VERTICES, 3);
4307 gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
4308 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
4311 /** De-initializes program and shader objects created for each iteration. **/
4312 void TextureViewTestViewSampling::deinitIterationSpecificProgramAndShaderObjects()
4314 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4318 gl.deleteShader(m_fs_id);
4325 gl.deleteShader(m_gs_id);
4332 gl.deleteProgram(m_po_id);
4339 gl.deleteShader(m_tc_id);
4346 gl.deleteShader(m_te_id);
4353 gl.deleteShader(m_vs_id);
4359 /** De-initializes shader and program objects providing the 'per-sample filling'
4362 void TextureViewTestViewSampling::deinitPerSampleFillerProgramAndShaderObjects()
4364 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4366 if (m_per_sample_filler_fs_id != 0)
4368 gl.deleteShader(m_per_sample_filler_fs_id);
4370 m_per_sample_filler_fs_id = 0;
4373 if (m_per_sample_filler_gs_id != 0)
4375 gl.deleteShader(m_per_sample_filler_gs_id);
4377 m_per_sample_filler_gs_id = 0;
4380 if (m_per_sample_filler_po_id != 0)
4382 gl.deleteProgram(m_per_sample_filler_po_id);
4384 m_per_sample_filler_po_id = 0;
4387 if (m_per_sample_filler_vs_id != 0)
4389 gl.deleteShader(m_per_sample_filler_vs_id);
4391 m_per_sample_filler_vs_id = 0;
4395 /** De-initializes texture objects used by the test */
4396 void TextureViewTestViewSampling::deinitTextureObjects()
4398 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4400 if (m_result_to_id != 0)
4402 gl.deleteTextures(1, &m_result_to_id);
4409 gl.deleteTextures(1, &m_to_id);
4414 if (m_view_to_id != 0)
4416 gl.deleteTextures(1, &m_view_to_id);
4422 /** Executes a single test iteration.
4424 * @return true if the iteration executed successfully, false otherwise.
4426 bool TextureViewTestViewSampling::executeTest()
4428 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4431 /* Bind the view to zero texture unit */
4432 gl.activeTexture(GL_TEXTURE0);
4433 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
4435 gl.bindTexture(m_iteration_view_texture_target, m_view_to_id);
4436 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
4438 /* Bind the buffer object to zero TF binding point */
4439 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
4440 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
4442 /* Activate the test program */
4443 gl.useProgram(m_po_id);
4444 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
4446 /* Update draw framebuffer configuration so that the test's fragment shader draws
4447 * to the result texture */
4448 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
4449 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
4451 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id, 0); /* level */
4452 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
4454 /* Allocate enough space to hold reference color data for all sample s*/
4455 float* reference_color_data = new float[m_iteration_parent_texture_n_samples * sizeof(float) * 4 /* rgba */];
4457 /* Iterate through the layer/face/mipmap hierarchy. For each iteration, we
4458 * potentially need to update relevant uniforms controlling the sampling process
4459 * the test program object performs.
4461 bool is_view_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP ||
4462 m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
4464 for (unsigned int n_current_layer = m_iteration_view_texture_minlayer;
4465 n_current_layer < (m_iteration_view_texture_minlayer + m_iteration_view_texture_numlayers) && result;
4468 unsigned int n_texture_face = 0;
4469 unsigned int n_texture_layer = 0;
4470 unsigned int n_view_face = 0;
4471 unsigned int n_view_layer = 0;
4475 n_texture_face = n_current_layer % 6; /* faces */
4476 n_texture_layer = n_current_layer / 6; /* faces */
4477 n_view_face = (n_current_layer - m_iteration_view_texture_minlayer) % 6; /* faces */
4478 n_view_layer = (n_current_layer - m_iteration_view_texture_minlayer) / 6; /* faces */
4482 /* Only cube-map and cube-map array textures consist of faces. */
4484 n_texture_layer = n_current_layer;
4486 n_view_layer = n_current_layer;
4489 if (m_po_z_float_location != -1)
4493 if (((false == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 1)) ||
4494 ((true == is_view_cm_cma) && (m_iteration_view_texture_numlayers > 6)))
4498 z = float(n_view_layer) / float(m_iteration_view_texture_numlayers / 6 - 1);
4502 if (m_iteration_view_texture_numlayers > 1)
4504 /* The program will be sampling a view so make sure that layer the shader accesses
4505 * is relative to how our view was configured */
4506 z = float(n_view_layer - m_iteration_view_texture_minlayer) /
4507 float(m_iteration_view_texture_numlayers - 1);
4511 /* z should stay at 0 */
4517 /* z should stay at 0.0 */
4520 gl.uniform1f(m_po_z_float_location, z);
4521 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
4524 if (m_po_z_int_location != -1)
4526 DE_ASSERT(!is_view_cm_cma);
4528 gl.uniform1i(m_po_z_int_location, n_current_layer - m_iteration_view_texture_minlayer);
4529 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
4532 if (m_po_n_face_location != -1)
4534 gl.uniform1i(m_po_n_face_location, n_view_face);
4535 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
4538 for (unsigned int n_mipmap = m_iteration_view_texture_minlevel;
4539 n_mipmap < (m_iteration_view_texture_minlevel + m_iteration_view_texture_numlevels) && result; n_mipmap++)
4541 if (m_po_lod_location != -1)
4543 /* The program will be sampling a view so make sure that LOD the shader accesses
4544 * is relative to how our view was configured.
4546 gl.uniform1f(m_po_lod_location, (float)(n_mipmap - m_iteration_view_texture_minlevel));
4547 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
4550 /* Update local reference color data storage */
4551 for (unsigned int n_sample = 0; n_sample < m_iteration_parent_texture_n_samples; ++n_sample)
4553 tcu::Vec4 reference_color = getReferenceColor(n_texture_layer, n_texture_face, n_mipmap, n_sample);
4555 reference_color_data[4 /* rgba */ * n_sample + 0] = reference_color.x();
4556 reference_color_data[4 /* rgba */ * n_sample + 1] = reference_color.y();
4557 reference_color_data[4 /* rgba */ * n_sample + 2] = reference_color.z();
4558 reference_color_data[4 /* rgba */ * n_sample + 3] = reference_color.w();
4561 /* Upload it to GPU */
4562 gl.uniform4fv(m_po_reference_colors_location, m_iteration_parent_texture_n_samples, reference_color_data);
4563 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
4565 /* Bind the texture view to sample from */
4566 gl.bindTexture(m_iteration_view_texture_target, m_view_to_id);
4567 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
4569 /* Draw a single patch. Given the rendering pipeline we've defined in the
4570 * test program object, this should give us a nice full-screen quad, as well
4571 * as 6*4 ints XFBed out, describing whether the view was sampled correctly.
4573 gl.beginTransformFeedback(GL_TRIANGLES);
4574 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
4576 gl.drawArrays(GL_PATCHES, 0 /* first */, 1 /* count */);
4577 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
4579 gl.endTransformFeedback();
4580 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
4582 /* In order to verify if the texel data was sampled correctly, we need to do two things:
4584 * 1) Verify buffer object contents;
4585 * 2) Make sure that all texels of current render-target are vec4(1).
4588 const int* bo_storage_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
4590 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
4591 if (bo_storage_ptr == NULL)
4593 TCU_FAIL("glMapBuffer() call succeeded but the pointer returned is NULL");
4596 /* The rendering pipeline should have written 6 vertices * 4 ints to the BO.
4597 * The integers are set to 1 if the sampled texels were found valid, 0 otherwise,
4598 * and are arranged in the following order:
4600 * 1) Result of sampling in vertex shader stage;
4601 * 2) Result of sampling in tessellation control shader stage;
4602 * 3) Result of sampling in tessellation evaluation shader stage;
4603 * 4) Result of sampling in geometry shader stage;
4605 for (unsigned int n_vertex = 0; n_vertex < 6 /* as per comment */ && result; ++n_vertex)
4607 const int* vertex_data_ptr = bo_storage_ptr + n_vertex * 4 /* as per comment */;
4608 int vs_result = vertex_data_ptr[0];
4609 int tc_result = vertex_data_ptr[1];
4610 int te_result = vertex_data_ptr[2];
4611 int gs_result = vertex_data_ptr[3];
4615 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in vertex shader stage."
4616 << tcu::TestLog::EndMessage;
4623 m_testCtx.getLog() << tcu::TestLog::Message
4624 << "Invalid data was sampled in tessellation control shader stage."
4625 << tcu::TestLog::EndMessage;
4632 m_testCtx.getLog() << tcu::TestLog::Message
4633 << "Invalid data was sampled in tessellation evaluation shader stage."
4634 << tcu::TestLog::EndMessage;
4641 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled in geometry shader stage."
4642 << tcu::TestLog::EndMessage;
4646 } /* for (all vertices) */
4649 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
4650 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
4652 /* Read texels rendered by the fragment shader. The texture attached uses
4653 * GL_RGBA8 internalformat.*/
4654 m_result_data = new unsigned char[m_reference_texture_width * m_reference_texture_height * 4 /* RGBA */];
4656 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
4657 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed for GL_TEXTURE_2D texture target.");
4659 gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, GL_UNSIGNED_BYTE, m_result_data);
4660 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed.");
4662 /* The test fails if any of the fragments is not equal to vec4(1) */
4663 bool fs_result = true;
4665 for (unsigned int y = 0; y < m_reference_texture_height && fs_result; ++y)
4667 const unsigned char* row_ptr = m_result_data + m_reference_texture_width * y * 4 /* RGBA */;
4669 for (unsigned int x = 0; x < m_reference_texture_width && fs_result; ++x)
4671 const unsigned char* pixel_ptr = row_ptr + x * 4 /* RGBA */;
4673 if (pixel_ptr[0] != 255 || pixel_ptr[1] != 255 || pixel_ptr[2] != 255 || pixel_ptr[3] != 255)
4675 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at (" << x << ", " << y
4677 "in fragment shader stage."
4678 << tcu::TestLog::EndMessage;
4682 } /* for (all columns) */
4683 } /* for (all rows) */
4690 /* Done - we can release the buffer at this point */
4691 delete[] m_result_data;
4692 m_result_data = DE_NULL;
4693 } /* for (all mip-maps) */
4694 } /* for (all texture layers) */
4696 /* Release the reference color data buffer */
4697 delete[] reference_color_data;
4698 reference_color_data = DE_NULL;
4704 /** Returns a different vec4 every time the function is called. Each component
4705 * is assigned a normalized value within <0, 1> range.
4707 * @return As per description.
4709 tcu::Vec4 TextureViewTestViewSampling::getRandomReferenceColor()
4711 static unsigned int seed = 195;
4714 result = tcu::Vec4(float((seed) % 255) / 255.0f, float((seed << 3) % 255) / 255.0f,
4715 float((seed << 4) % 255) / 255.0f, float((seed << 5) % 255) / 255.0f);
4722 /** Every test iteration is assigned a different set of so-called reference colors.
4723 * Depending on the texture target, each reference color corresponds to an unique color
4724 * used to build different layers/faces/mip-maps or even samples of tose.
4726 * Once the reference color storage is initialized, this function can be used to retrieve
4727 * details of a color allocated a specific sample of a layer/face mip-map.
4729 * This function will cause an assertion failure if an invalid layer/face/mipmap/sample is
4730 * requested, as well as if the reference color storage is not initialized at the time of the call.
4732 * @param n_layer Layer index to use for the query. A value of 0 should be used for non-arrayed
4734 * @param n_face Face index to use for the query. A value of 0 should be used for non-CM texture
4735 * targets. Otherwise:
4736 * * 0 corresponds to +X;
4737 * * 1 corresponds to -X;
4738 * * 2 corresponds to +Y;
4739 * * 3 corresponds to -Y;
4740 * * 4 corresponds to +Z;
4741 * * 5 corresponds to -Z.
4742 * @param n_mipmap Mip-map index to use for the query. A value of 0 should be used for non-mipmapped
4744 * @param n_sample Sample index to use for the query. A value of 0 should be used for single-sampled
4747 * @return Requested color data.
4749 tcu::Vec4 TextureViewTestViewSampling::getReferenceColor(unsigned int n_layer, unsigned int n_face,
4750 unsigned int n_mipmap, unsigned int n_sample)
4754 DE_ASSERT(m_reference_color_storage != DE_NULL);
4755 if (m_reference_color_storage != DE_NULL)
4757 bool is_parent_texture_cm_cma = (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP ||
4758 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
4759 bool is_view_texture_cm_cma = (m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP ||
4760 m_iteration_view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
4762 if (is_view_texture_cm_cma && !is_parent_texture_cm_cma)
4764 /* Parent texture is not using faces. Compute layer index, as
4765 * if the texture was actually a CM or a CMA */
4766 unsigned int temp = n_layer * 6 /* layer-faces per layer */ + n_face;
4771 else if (!is_view_texture_cm_cma && is_parent_texture_cm_cma)
4773 /* The other way around - assume the texture is a CM or CMA */
4774 n_face = n_layer % 6; /* faces per cube-map layer */
4775 n_layer = n_layer / 6; /* faces per cube-map layer */
4778 DE_ASSERT(n_face < m_reference_color_storage->n_faces);
4779 DE_ASSERT(n_layer < m_reference_color_storage->n_layers);
4780 DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps);
4781 DE_ASSERT(n_sample < m_reference_color_storage->n_samples);
4785 * layers -> faces -> mipmaps -> samples */
4786 const unsigned int index =
4787 n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps *
4788 m_reference_color_storage->n_samples) +
4789 n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) +
4790 n_mipmap * (m_reference_color_storage->n_samples) + n_sample;
4792 result = m_reference_color_storage->data[index];
4798 /* Retrieve max conformant sample count when GL_NV_internalformat_sample_query is supported */
4799 glw::GLint TextureViewTestViewSampling::getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
4801 (void)internalFormat;
4802 glw::GLint max_conformant_samples = 0;
4804 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4806 /* Return the max conformant sample count if extension is supported */
4807 if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query"))
4809 glw::GLint gl_sample_counts = 0;
4810 gl.getInternalformativ(target, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts);
4811 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname");
4813 /* Check and return the first conformant sample count */
4814 glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts];
4815 if (gl_supported_samples)
4817 gl.getInternalformativ(target, GL_RGBA8, GL_SAMPLES, gl_sample_counts, gl_supported_samples);
4819 for (glw::GLint i = 0; i < gl_sample_counts; i++)
4821 glw::GLint isConformant = 0;
4822 gl.getInternalformatSampleivNV(target, GL_RGBA8, gl_supported_samples[i], GL_CONFORMANT_NV, 1,
4824 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed");
4826 if (isConformant && gl_supported_samples[i] > max_conformant_samples)
4828 max_conformant_samples = gl_supported_samples[i];
4831 delete[] gl_supported_samples;
4836 /* Otherwise return GL_MAX_COLOR_TEXTURE_SAMPLES */
4837 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_conformant_samples);
4838 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
4841 return max_conformant_samples;
4844 /** Initializes iteration-specific program object used to sample the texture data. */
4845 void TextureViewTestViewSampling::initIterationSpecificProgramObject()
4847 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4849 /* Release shader/program objects that may have been initialized in previous
4852 deinitIterationSpecificProgramAndShaderObjects();
4854 /* Create program and shader objects */
4855 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
4856 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
4857 m_tc_id = gl.createShader(GL_TESS_CONTROL_SHADER);
4858 m_te_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
4859 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
4861 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
4863 m_po_id = gl.createProgram();
4864 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
4866 /* Prepare token replacement strings */
4867 std::stringstream n_samples_sstream;
4868 std::string sampler_declarations_string;
4869 std::string sample_fetch_string;
4870 std::string sample_fetch_fs_string;
4871 std::size_t token_location = std::string::npos;
4872 const char* token_n_samples = "N_SAMPLES";
4873 const char* token_sampler_declarations = "SAMPLER_DECLARATIONS";
4874 const char* token_sample_fetch = "SAMPLE_FETCH";
4876 n_samples_sstream << m_iteration_parent_texture_n_samples;
4878 switch (m_iteration_view_texture_target)
4882 sampler_declarations_string = "uniform sampler1D texture;";
4883 sample_fetch_string = "vec4 current_sample = textureLod(texture, 0.5, lod);\n";
4884 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, gs_fs_uv.x, lod);\n";
4889 case GL_TEXTURE_1D_ARRAY:
4891 sampler_declarations_string = "uniform sampler1DArray texture;\n"
4892 "uniform float z_float;\n";
4894 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec2(0.5, z_float), lod);\n";
4895 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec2(gs_fs_uv.x, z_float), lod);\n";
4902 sampler_declarations_string = "uniform sampler2D texture;";
4903 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec2(0.5), lod);\n";
4904 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, gs_fs_uv, lod);\n";
4909 case GL_TEXTURE_2D_ARRAY:
4911 sampler_declarations_string = "uniform float z_float;\n"
4912 "uniform sampler2DArray texture;";
4914 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n";
4915 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n";
4920 case GL_TEXTURE_2D_MULTISAMPLE:
4922 sampler_declarations_string = "uniform sampler2DMS texture;";
4923 sample_fetch_string = "ivec2 texture_size = textureSize(texture);\n"
4924 "vec4 current_sample = texelFetch (texture,\n"
4925 " ivec2(texture_size.xy / ivec2(2)),\n"
4928 sample_fetch_fs_string = "ivec2 texture_size = textureSize(texture);\n"
4929 "vec4 current_sample = texelFetch (texture,\n"
4930 " ivec2(gs_fs_uv * vec2(texture_size)),\n"
4936 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
4938 sampler_declarations_string = "uniform sampler2DMSArray texture;"
4939 "uniform int z_int;\n";
4941 sample_fetch_string = "ivec3 texture_size = textureSize(texture);\n"
4942 "vec4 current_sample = texelFetch (texture,\n"
4943 " ivec3(texture_size.xy / ivec2(2), z_int),\n"
4946 sample_fetch_fs_string =
4947 "ivec3 texture_size = textureSize(texture);\n"
4948 "vec4 current_sample = texelFetch (texture,\n"
4949 " ivec3(ivec2(gs_fs_uv * vec2(texture_size).xy), z_int),\n"
4957 sampler_declarations_string = "uniform sampler3D texture;"
4958 "uniform float z_float;";
4960 sample_fetch_string = "vec4 current_sample = textureLod(texture, vec3(vec2(0.5), z_float), lod);\n";
4961 sample_fetch_fs_string = "vec4 current_sample = textureLod(texture, vec3(gs_fs_uv, z_float), lod);\n";
4966 case GL_TEXTURE_CUBE_MAP:
4968 sampler_declarations_string = "uniform samplerCube texture;\n"
4969 "uniform int n_face;";
4971 sample_fetch_string = "vec4 current_sample;\n"
4975 // GL_TEXTURE_CUBE_MAP_POSITIVE_X
4976 " case 0: current_sample = textureLod(texture, vec3( 1, 0, 0), lod); break;\n"
4977 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
4978 " case 1: current_sample = textureLod(texture, vec3(-1, 0, 0), lod); break;\n"
4979 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
4980 " case 2: current_sample = textureLod(texture, vec3( 0, 1, 0), lod); break;\n"
4981 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
4982 " case 3: current_sample = textureLod(texture, vec3( 0, -1, 0), lod); break;\n"
4983 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
4984 " case 4: current_sample = textureLod(texture, vec3( 0, 0, 1), lod); break;\n"
4985 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
4986 " case 5: current_sample = textureLod(texture, vec3( 0, 0, -1), lod); break;\n"
4989 sample_fetch_fs_string =
4990 "vec4 current_sample;\n"
4994 // GL_TEXTURE_CUBE_MAP_POSITIVE_X
4995 " case 0: current_sample = textureLod(texture, normalize(vec3( 1, gs_fs_uv.xy)), lod); break;\n"
4996 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
4997 " case 1: current_sample = textureLod(texture, normalize(vec3(-1, gs_fs_uv.xy)), lod); break;\n"
4998 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
4999 " case 2: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, 1, gs_fs_uv.y)), lod); "
5001 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
5002 " case 3: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.x, -1, gs_fs_uv.y)), lod); "
5004 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
5005 " case 4: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy, 1)), lod); break;\n"
5006 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
5007 " case 5: current_sample = textureLod(texture, normalize(vec3( gs_fs_uv.xy, -1)), lod); break;\n"
5012 case GL_TEXTURE_CUBE_MAP_ARRAY:
5014 sampler_declarations_string = "uniform samplerCubeArray texture;\n"
5015 "uniform int n_face;\n"
5016 "uniform float z_float;\n";
5018 sample_fetch_string =
5019 "vec4 current_sample;\n"
5023 // GL_TEXTURE_CUBE_MAP_POSITIVE_X
5024 " case 0: current_sample = textureLod(texture, vec4( 1, 0, 0, z_float), lod); break;\n"
5025 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
5026 " case 1: current_sample = textureLod(texture, vec4(-1, 0, 0, z_float), lod); break;\n"
5027 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
5028 " case 2: current_sample = textureLod(texture, vec4( 0, 1, 0, z_float), lod); break;\n"
5029 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
5030 " case 3: current_sample = textureLod(texture, vec4( 0, -1, 0, z_float), lod); break;\n"
5031 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
5032 " case 4: current_sample = textureLod(texture, vec4( 0, 0, 1, z_float), lod); break;\n"
5033 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
5034 " case 5: current_sample = textureLod(texture, vec4( 0, 0, -1, z_float), lod); break;\n"
5037 sample_fetch_fs_string = "vec4 current_sample;\n"
5041 // GL_TEXTURE_CUBE_MAP_POSITIVE_X
5042 " case 0: current_sample = textureLod(texture, vec4(normalize(vec3( 1, "
5043 "gs_fs_uv.xy)), z_float), lod); break;\n"
5044 // GL_TEXTURE_CUBE_MAP_NEGATIVE_X
5045 " case 1: current_sample = textureLod(texture, vec4(normalize(vec3(-1, "
5046 "gs_fs_uv.xy)), z_float), lod); break;\n"
5047 // GL_TEXTURE_CUBE_MAP_POSITIVE_Y
5048 " case 2: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, 1, "
5049 " gs_fs_uv.y)), z_float), lod); break;\n"
5050 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
5051 " case 3: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.x, "
5052 "-1, gs_fs_uv.y)), z_float), lod); break;\n"
5053 // GL_TEXTURE_CUBE_MAP_POSITIVE_Z
5054 " case 4: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, "
5055 "1)), z_float), lod); break;\n"
5056 // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
5057 " case 5: current_sample = textureLod(texture, vec4(normalize(vec3( gs_fs_uv.xy, "
5058 "-1)), z_float), lod); break;\n"
5064 case GL_TEXTURE_RECTANGLE:
5066 sampler_declarations_string = "uniform sampler2DRect texture;";
5067 sample_fetch_string = "ivec2 texture_size = textureSize(texture);\n"
5068 "vec4 current_sample = texelFetch (texture, texture_size / ivec2(2));\n";
5070 sample_fetch_fs_string =
5071 "ivec2 texture_size = textureSize(texture);\n"
5072 "vec4 current_sample = texelFetch (texture, ivec2(gs_fs_uv.xy * vec2(texture_size)));\n";
5079 TCU_FAIL("Unrecognized texture target");
5081 } /* switch (m_iteration_view_texture_target) */
5083 /* Set vertex shader's body */
5084 const char* vs_body = "#version 400\n"
5086 "uniform float lod;\n"
5087 "uniform vec4 reference_colors[N_SAMPLES];\n"
5088 "SAMPLER_DECLARATIONS\n"
5090 "out int vs_tc_vs_sampling_result;\n"
5094 " const float epsilon = 1.0 / 255.0;\n"
5096 " vs_tc_vs_sampling_result = 1;\n"
5098 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
5102 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
5103 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
5104 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
5105 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
5107 " vs_tc_vs_sampling_result = int(current_sample.x * 256.0);\n"
5113 " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
5115 std::string vs_string = vs_body;
5117 while ((token_location = vs_string.find(token_n_samples)) != std::string::npos)
5119 vs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
5122 while ((token_location = vs_string.find(token_sampler_declarations)) != std::string::npos)
5124 vs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
5127 while ((token_location = vs_string.find(token_sample_fetch)) != std::string::npos)
5129 vs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
5132 /* Set tessellation control shader's body */
5133 const char* tc_body = "#version 400\n"
5135 "layout(vertices = 1) out;\n"
5137 "uniform float lod;\n"
5138 "uniform vec4 reference_colors[N_SAMPLES];\n"
5139 "SAMPLER_DECLARATIONS\n"
5141 "in int vs_tc_vs_sampling_result[];\n"
5142 "out int tc_te_vs_sampling_result[];\n"
5143 "out int tc_te_tc_sampling_result[];\n"
5147 " const float epsilon = 1.0 / 255.0;\n"
5149 " tc_te_vs_sampling_result[gl_InvocationID] = vs_tc_vs_sampling_result[gl_InvocationID];\n"
5150 " tc_te_tc_sampling_result[gl_InvocationID] = 1;\n"
5152 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
5156 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
5157 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
5158 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
5159 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
5161 " tc_te_tc_sampling_result[gl_InvocationID] = 0;\n"
5167 " gl_TessLevelInner[0] = 1.0;\n"
5168 " gl_TessLevelInner[1] = 1.0;\n"
5169 " gl_TessLevelOuter[0] = 1.0;\n"
5170 " gl_TessLevelOuter[1] = 1.0;\n"
5171 " gl_TessLevelOuter[2] = 1.0;\n"
5172 " gl_TessLevelOuter[3] = 1.0;\n"
5175 std::string tc_string = tc_body;
5177 while ((token_location = tc_string.find(token_n_samples)) != std::string::npos)
5179 tc_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
5182 while ((token_location = tc_string.find(token_sampler_declarations)) != std::string::npos)
5184 tc_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
5187 while ((token_location = tc_string.find(token_sample_fetch)) != std::string::npos)
5189 tc_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
5192 /* Set tessellation evaluation shader's body */
5193 const char* te_body = "#version 400\n"
5195 "layout(quads) in;\n"
5197 "in int tc_te_vs_sampling_result[];\n"
5198 "in int tc_te_tc_sampling_result[];\n"
5199 "out int te_gs_vs_sampling_result;\n"
5200 "out int te_gs_tc_sampling_result;\n"
5201 "out int te_gs_te_sampling_result;\n"
5202 "out vec2 te_gs_uv;\n"
5204 "uniform float lod;\n"
5205 "uniform vec4 reference_colors[N_SAMPLES];\n"
5206 "SAMPLER_DECLARATIONS\n"
5210 " te_gs_vs_sampling_result = tc_te_vs_sampling_result[0];\n"
5211 " te_gs_tc_sampling_result = tc_te_tc_sampling_result[0];\n"
5212 " te_gs_te_sampling_result = 1;\n"
5214 /* gl_TessCoord spans from 0 to 1 for XY. To generate a screen-space quad,
5215 * we need to project these components to <-1, 1>. */
5216 " gl_Position.xy = gl_TessCoord.xy * 2.0 - 1.0;\n"
5217 " gl_Position.zw = vec2(0, 1);\n"
5218 " te_gs_uv = vec2(gl_TessCoord.x, 1.0 - gl_TessCoord.y);\n"
5221 " const float epsilon = 1.0 / 255.0;\n"
5223 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
5227 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
5228 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
5229 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
5230 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
5232 " te_gs_te_sampling_result = 0;\n"
5240 std::string te_string = te_body;
5242 while ((token_location = te_string.find(token_n_samples)) != std::string::npos)
5244 te_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
5247 while ((token_location = te_string.find(token_sampler_declarations)) != std::string::npos)
5249 te_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
5252 while ((token_location = te_string.find(token_sample_fetch)) != std::string::npos)
5254 te_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
5257 /* Set geometry shader's body */
5258 const char* gs_body = "#version 400\n"
5260 "layout (triangles) in;\n"
5261 "layout (triangle_strip, max_vertices = 3) out;\n"
5263 "in int te_gs_vs_sampling_result[];\n"
5264 "in int te_gs_tc_sampling_result[];\n"
5265 "in int te_gs_te_sampling_result[];\n"
5266 "in vec2 te_gs_uv [];\n"
5267 "out int gs_fs_vs_sampling_result;\n"
5268 "out int gs_fs_tc_sampling_result;\n"
5269 "out int gs_fs_te_sampling_result;\n"
5270 "out int gs_fs_gs_sampling_result;\n"
5271 "out vec2 gs_fs_uv;\n"
5273 "uniform float lod;\n"
5274 "uniform vec4 reference_colors[N_SAMPLES];\n"
5275 "SAMPLER_DECLARATIONS\n"
5279 " const float epsilon = 1.0 / 255.0;\n"
5280 " int gs_sampling_result = 1;\n"
5281 " int tc_sampling_result = te_gs_tc_sampling_result[0] & "
5282 "te_gs_tc_sampling_result[1] & te_gs_tc_sampling_result[2];\n"
5283 " int te_sampling_result = te_gs_te_sampling_result[0] & "
5284 "te_gs_te_sampling_result[1] & te_gs_te_sampling_result[2];\n"
5285 " int vs_sampling_result = te_gs_vs_sampling_result[0] & "
5286 "te_gs_vs_sampling_result[1] & te_gs_vs_sampling_result[2];\n"
5288 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
5292 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
5293 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
5294 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
5295 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
5297 " gs_sampling_result = 0;\n"
5303 " gl_Position = gl_in[0].gl_Position;\n"
5304 " gs_fs_uv = te_gs_uv[0];\n"
5305 " gs_fs_gs_sampling_result = gs_sampling_result;\n"
5306 " gs_fs_tc_sampling_result = tc_sampling_result;\n"
5307 " gs_fs_te_sampling_result = te_sampling_result;\n"
5308 " gs_fs_vs_sampling_result = vs_sampling_result;\n"
5311 " gl_Position = gl_in[1].gl_Position;\n"
5312 " gs_fs_uv = te_gs_uv[1];\n"
5313 " gs_fs_gs_sampling_result = gs_sampling_result;\n"
5314 " gs_fs_tc_sampling_result = tc_sampling_result;\n"
5315 " gs_fs_te_sampling_result = te_sampling_result;\n"
5316 " gs_fs_vs_sampling_result = vs_sampling_result;\n"
5319 " gl_Position = gl_in[2].gl_Position;\n"
5320 " gs_fs_uv = te_gs_uv[2];\n"
5321 " gs_fs_gs_sampling_result = gs_sampling_result;\n"
5322 " gs_fs_tc_sampling_result = tc_sampling_result;\n"
5323 " gs_fs_te_sampling_result = te_sampling_result;\n"
5324 " gs_fs_vs_sampling_result = vs_sampling_result;\n"
5326 " EndPrimitive();\n"
5329 std::string gs_string = gs_body;
5331 while ((token_location = gs_string.find(token_n_samples)) != std::string::npos)
5333 gs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
5336 while ((token_location = gs_string.find(token_sampler_declarations)) != std::string::npos)
5338 gs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
5341 while ((token_location = gs_string.find(token_sample_fetch)) != std::string::npos)
5343 gs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_string);
5346 /* Set fragment shader's body */
5347 const char* fs_body = "#version 400\n"
5349 "in vec2 gs_fs_uv;\n"
5351 "uniform float lod;\n"
5352 "uniform vec4 reference_colors[N_SAMPLES];\n"
5353 "SAMPLER_DECLARATIONS\n"
5355 "out vec4 result;\n"
5359 " const float epsilon = 1.0 / 255.0;\n"
5361 " result = vec4(1.0);\n"
5363 " for (int n_sample = 0; n_sample < N_SAMPLES; ++n_sample)\n"
5367 " if (abs(current_sample.x - reference_colors[n_sample].x) > epsilon ||\n"
5368 " abs(current_sample.y - reference_colors[n_sample].y) > epsilon ||\n"
5369 " abs(current_sample.z - reference_colors[n_sample].z) > epsilon ||\n"
5370 " abs(current_sample.w - reference_colors[n_sample].w) > epsilon)\n"
5372 " result = vec4(0.0);\n"
5379 std::string fs_string = fs_body;
5381 while ((token_location = fs_string.find(token_n_samples)) != std::string::npos)
5383 fs_string.replace(token_location, strlen(token_n_samples), n_samples_sstream.str());
5386 while ((token_location = fs_string.find(token_sampler_declarations)) != std::string::npos)
5388 fs_string.replace(token_location, strlen(token_sampler_declarations), sampler_declarations_string);
5391 while ((token_location = fs_string.find(token_sample_fetch)) != std::string::npos)
5393 fs_string.replace(token_location, strlen(token_sample_fetch), sample_fetch_fs_string);
5396 /* Configure shader bodies */
5397 const char* fs_body_raw_ptr = fs_string.c_str();
5398 const char* gs_body_raw_ptr = gs_string.c_str();
5399 const char* tc_body_raw_ptr = tc_string.c_str();
5400 const char* te_body_raw_ptr = te_string.c_str();
5401 const char* vs_body_raw_ptr = vs_string.c_str();
5403 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body_raw_ptr, NULL /* length */);
5404 gl.shaderSource(m_gs_id, 1 /* count */, &gs_body_raw_ptr, NULL /* length */);
5405 gl.shaderSource(m_tc_id, 1 /* count */, &tc_body_raw_ptr, NULL /* length */);
5406 gl.shaderSource(m_te_id, 1 /* count */, &te_body_raw_ptr, NULL /* length */);
5407 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, NULL /* length */);
5408 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call(s) failed.");
5410 /* Compile the shaders */
5411 const glw::GLuint so_ids[] = { m_fs_id, m_gs_id, m_tc_id, m_te_id, m_vs_id };
5412 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
5414 const glw::GLchar* shader_sources[] = { fs_body_raw_ptr, gs_body_raw_ptr, tc_body_raw_ptr, te_body_raw_ptr,
5417 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
5419 glw::GLint compile_status = GL_FALSE;
5420 glw::GLint so_id = so_ids[n_so_id];
5422 gl.compileShader(so_id);
5423 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5425 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
5426 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
5428 if (compile_status != GL_TRUE)
5432 gl.getShaderInfoLog(so_id, 1024, NULL, temp);
5434 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation error log:\n"
5435 << temp << "\nShader source:\n"
5436 << shader_sources[n_so_id] << tcu::TestLog::EndMessage;
5438 TCU_FAIL("Shader compilation failed");
5441 /* Attach the shaders to the program object */
5442 gl.attachShader(m_po_id, so_id);
5443 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed");
5444 } /* for (all shader objects) */
5447 const char* varying_names[] = { "gs_fs_vs_sampling_result", "gs_fs_tc_sampling_result", "gs_fs_te_sampling_result",
5448 "gs_fs_gs_sampling_result" };
5449 const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
5451 gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
5452 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
5454 /* Link the program object */
5455 glw::GLint link_status = GL_FALSE;
5457 gl.linkProgram(m_po_id);
5458 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
5460 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
5461 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
5463 if (link_status != GL_TRUE)
5465 TCU_FAIL("Program linking failed.");
5468 /* Retrieve uniform locations. Depending on the iteration, a number of those will be
5471 m_po_lod_location = gl.getUniformLocation(m_po_id, "lod");
5472 m_po_n_face_location = gl.getUniformLocation(m_po_id, "n_face");
5473 m_po_reference_colors_location = gl.getUniformLocation(m_po_id, "reference_colors");
5474 m_po_texture_location = gl.getUniformLocation(m_po_id, "texture");
5475 m_po_z_float_location = gl.getUniformLocation(m_po_id, "z_float");
5476 m_po_z_int_location = gl.getUniformLocation(m_po_id, "z_int");
5478 if (m_po_reference_colors_location == -1)
5480 TCU_FAIL("reference_colors is considered an inactive uniform which is invalid.");
5484 /** Initializes contents of a texture, from which the view texture will be created. **/
5485 void TextureViewTestViewSampling::initParentTextureContents()
5487 static const glw::GLenum cm_texture_targets[] = {
5488 /* NOTE: This order must match the order used for sampling CM/CMA texture targets. */
5489 GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
5490 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
5492 static const unsigned int n_cm_texture_targets = sizeof(cm_texture_targets) / sizeof(cm_texture_targets[0]);
5493 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5495 /* Bind the parent texture */
5496 gl.bindTexture(m_iteration_parent_texture_target, m_to_id);
5497 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
5499 /* If we're dealing with a single-sampled texture target, then we can clear the
5500 * contents of each layer/face/slice using FBO. This will unfortunately not work
5501 * for arrayed textures, layers or layer-faces of which cannot be attached to a draw
5503 * If we need to update contents of a multisampled, potentially arrayed texture,
5504 * we'll need to use the filler program.
5506 bool is_arrayed_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY ||
5507 m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY ||
5508 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
5509 bool is_multisampled_texture_target = (m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
5510 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
5512 if (!is_arrayed_texture_target && !is_multisampled_texture_target)
5514 /* Good, no need to work with samples! */
5515 DE_ASSERT(m_iteration_parent_texture_depth >= 1);
5516 DE_ASSERT(m_iteration_parent_texture_n_levels >= 1);
5518 /* Cube-map texture target cannot be directly used for a glFramebufferTexture2D() call. Instead,
5519 * we need to split it into 6 cube-map texture targets. */
5520 unsigned int n_texture_targets = 1;
5521 glw::GLenum texture_targets[n_cm_texture_targets] = {
5522 m_iteration_parent_texture_target, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE,
5525 if (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP)
5527 DE_STATIC_ASSERT(sizeof(texture_targets) == sizeof(cm_texture_targets));
5528 memcpy(texture_targets, cm_texture_targets, sizeof(cm_texture_targets));
5530 n_texture_targets = n_cm_texture_targets;
5533 resetReferenceColorStorage(m_iteration_parent_texture_depth, /* n_layers */
5534 n_texture_targets, /* n_faces */
5535 m_iteration_parent_texture_n_levels, /* n_mipmaps */
5538 /* Iterate through all texture targets we need to update */
5539 for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
5541 const glw::GLenum texture_target = texture_targets[n_texture_target];
5543 /* Iterate through all layers of the texture. */
5544 for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer)
5546 /* ..and mip-maps, too. */
5547 const unsigned int n_mipmaps_for_layer = (texture_target == GL_TEXTURE_3D) ?
5548 (m_iteration_parent_texture_n_levels - n_layer) :
5549 (m_iteration_parent_texture_n_levels);
5551 for (unsigned int n_mipmap = 0; n_mipmap < n_mipmaps_for_layer; ++n_mipmap)
5553 /* Use appropriate glFramebufferTexture*() API, depending on the texture target of the
5556 switch (texture_target)
5560 gl.framebufferTexture1D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_1D, m_to_id,
5563 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D() call failed.");
5568 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5569 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5570 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5571 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5572 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5573 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5574 case GL_TEXTURE_RECTANGLE:
5576 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, m_to_id,
5579 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
5585 gl.framebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, m_to_id,
5588 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture3D() call failed.");
5594 TCU_FAIL("Unrecognized texture target");
5596 } /* switch (m_iteration_parent_texture_target) */
5598 /* Each layer/mipmap needs to be assigned an unique vec4. */
5599 tcu::Vec4 reference_color = getRandomReferenceColor();
5601 setReferenceColor(n_layer, n_texture_target, /* n_face */
5602 n_mipmap, 0, /* n_sample */
5605 /* We should be OK to clear the mip-map at this point */
5606 gl.clearColor(reference_color.x(), reference_color.y(), reference_color.z(), reference_color.w());
5607 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
5609 gl.clear(GL_COLOR_BUFFER_BIT);
5610 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
5611 } /* for (all mip-maps) */
5612 } /* for (all layers) */
5613 } /* for (all texture targets) */
5614 } /* if (!is_arrayed_texture_target && !is_multisampled_texture_target) */
5617 /* We need to handle an either multisampled or arrayed texture target or
5618 * a combination of the two.
5620 DE_ASSERT(m_iteration_parent_texture_target == GL_TEXTURE_1D_ARRAY ||
5621 m_iteration_parent_texture_target == GL_TEXTURE_2D_ARRAY ||
5622 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE ||
5623 m_iteration_parent_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
5624 m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
5626 DE_ASSERT(m_iteration_parent_texture_depth >= 1);
5627 DE_ASSERT(m_iteration_parent_texture_n_levels >= 1);
5629 const unsigned int n_faces =
5630 (m_iteration_parent_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 6 /* faces */ : 1;
5632 resetReferenceColorStorage(m_iteration_parent_texture_depth, /* n_layers */
5633 n_faces, m_iteration_parent_texture_n_levels, /* n_mipmaps */
5634 m_max_color_texture_samples_gl_value); /* n_samples */
5636 /* Set up storage for reference colors the fragment shader should use
5637 * when rendering to multisampled texture target */
5638 float* reference_colors = new float[4 /* rgba */ * m_max_color_texture_samples_gl_value];
5640 /* Activate the filler program */
5641 gl.useProgram(m_per_sample_filler_po_id);
5642 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
5644 /* Iterate through all layers of the texture. */
5645 for (unsigned int n_layer = 0; n_layer < m_iteration_parent_texture_depth; ++n_layer)
5648 for (unsigned int n_face = 0; n_face < n_faces; ++n_face)
5650 /* ..and mip-maps, too. */
5651 for (unsigned int n_mipmap = 0; n_mipmap < m_iteration_parent_texture_n_levels; ++n_mipmap)
5653 /* For all texture targets considered excl. GL_TEXTURE_2D_MULTISAMPLE, we need
5654 * to use glFramebufferTextur() to bind all layers to the color atatchment. For
5655 * 2DMS textures, we can use plain glFramebufferTexture2D().
5657 if (m_iteration_parent_texture_target != GL_TEXTURE_2D_MULTISAMPLE)
5659 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, n_mipmap);
5661 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
5666 DE_ASSERT(m_iteration_parent_texture_depth == 1);
5668 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5669 m_iteration_parent_texture_target, m_to_id, n_mipmap);
5671 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
5674 /* Generate reference colors for all samples */
5675 const unsigned int n_samples =
5676 (is_multisampled_texture_target) ? m_max_color_texture_samples_gl_value : 1;
5678 for (unsigned int n_sample = 0; n_sample < n_samples; ++n_sample)
5680 tcu::Vec4 reference_color = getRandomReferenceColor();
5682 reference_colors[4 /* rgba */ * n_sample + 0] = reference_color.x();
5683 reference_colors[4 /* rgba */ * n_sample + 1] = reference_color.y();
5684 reference_colors[4 /* rgba */ * n_sample + 2] = reference_color.z();
5685 reference_colors[4 /* rgba */ * n_sample + 3] = reference_color.w();
5687 setReferenceColor(n_layer, n_face, n_mipmap, n_sample, reference_color);
5688 } /* for (all samples) */
5690 /* Upload the reference sample colors */
5691 gl.uniform4fv(m_per_sample_filler_po_reference_colors_location, n_samples, reference_colors);
5692 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
5694 /* Update the layer ID the program should render to */
5695 const unsigned int layer_id = n_face * 6 /* faces */ + n_layer;
5697 gl.uniform1i(m_per_sample_filler_po_layer_id_location, layer_id);
5698 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
5700 /* Draw the full-screen quad. Geometry shader will draw the quad for us,
5701 * so all we need to do is to feed the rendering pipeline with a single
5704 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
5705 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
5706 } /* for (all mip-maps) */
5707 } /* for (all faces) */
5708 } /* for (all layers) */
5710 delete[] reference_colors;
5714 /** Initializes the 'per sample filler' program object, used to fill a multi-sample texture
5715 * with colors varying on a per-sample basis.
5717 void TextureViewTestViewSampling::initPerSampleFillerProgramObject()
5719 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5721 /* Sanity checks: GL_MAX_COLOR_TEXTURE_SAMPLES is not 0 */
5722 DE_ASSERT(m_max_color_texture_samples_gl_value != 0);
5724 /* Generate program and shader objects */
5725 m_per_sample_filler_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
5726 m_per_sample_filler_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
5727 m_per_sample_filler_vs_id = gl.createShader(GL_VERTEX_SHADER);
5728 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
5730 m_per_sample_filler_po_id = gl.createProgram();
5731 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
5733 /* Configure fragment shader's body */
5734 static const char* fs_body = "#version 400\n"
5736 "uniform vec4 reference_colors[N_MAX_SAMPLES];\n"
5738 "out vec4 result;\n"
5742 " result = reference_colors[gl_SampleID];\n"
5744 std::string fs_body_string = fs_body;
5745 const char* fs_body_string_raw_ptr = DE_NULL;
5746 std::stringstream n_max_samples_sstream;
5747 const char* n_max_samples_token = "N_MAX_SAMPLES";
5748 std::size_t token_location = std::string::npos;
5750 n_max_samples_sstream << m_max_color_texture_samples_gl_value;
5752 while ((token_location = fs_body_string.find(n_max_samples_token)) != std::string::npos)
5754 fs_body_string.replace(token_location, strlen(n_max_samples_token), n_max_samples_sstream.str());
5757 fs_body_string_raw_ptr = fs_body_string.c_str();
5759 gl.shaderSource(m_per_sample_filler_fs_id, 1 /* count */, &fs_body_string_raw_ptr, DE_NULL /* length */);
5760 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5762 /* Configure geometry shader's body */
5763 static const char* gs_body = "#version 400\n"
5765 "layout(points) in;\n"
5766 "layout(triangle_strip, max_vertices = 4) out;\n"
5768 "uniform int layer_id;\n"
5772 " gl_Layer = layer_id;\n"
5773 " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
5776 " gl_Layer = layer_id;\n"
5777 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
5780 " gl_Layer = layer_id;\n"
5781 " gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n"
5784 " gl_Layer = layer_id;\n"
5785 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
5788 " EndPrimitive();\n"
5792 gl.shaderSource(m_per_sample_filler_gs_id, 1 /* count */, &gs_body, DE_NULL /* length */);
5793 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5795 /* Configure vertex shader */
5796 static const char* vs_body = "#version 400\n"
5800 " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
5803 gl.shaderSource(m_per_sample_filler_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
5804 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
5806 /* Attach the shaders to the program object */
5807 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_fs_id);
5808 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_gs_id);
5809 gl.attachShader(m_per_sample_filler_po_id, m_per_sample_filler_vs_id);
5810 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
5812 /* Compile the shaders */
5813 const glw::GLuint so_ids[] = { m_per_sample_filler_fs_id, m_per_sample_filler_gs_id, m_per_sample_filler_vs_id };
5814 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
5816 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
5818 glw::GLint compile_status = GL_FALSE;
5819 glw::GLuint so_id = so_ids[n_so_id];
5821 gl.compileShader(so_id);
5822 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
5824 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
5825 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiV() call failed.");
5827 if (compile_status != GL_TRUE)
5829 TCU_FAIL("Shader compilation failed.");
5831 } /* for (all shader objects) */
5833 /* Link the program object */
5834 glw::GLint link_status = GL_FALSE;
5836 gl.linkProgram(m_per_sample_filler_po_id);
5837 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
5839 gl.getProgramiv(m_per_sample_filler_po_id, GL_LINK_STATUS, &link_status);
5840 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
5842 if (link_status != GL_TRUE)
5844 TCU_FAIL("Program linking failed.");
5847 /* Retrieve uniform locations */
5848 m_per_sample_filler_po_layer_id_location = gl.getUniformLocation(m_per_sample_filler_po_id, "layer_id");
5849 m_per_sample_filler_po_reference_colors_location =
5850 gl.getUniformLocation(m_per_sample_filler_po_id, "reference_colors[0]");
5852 if (m_per_sample_filler_po_layer_id_location == -1)
5854 TCU_FAIL("layer_id uniform is considered inactive which is invalid");
5857 if (m_per_sample_filler_po_reference_colors_location == -1)
5859 TCU_FAIL("reference_colors uniform is considered inactive which is invalid");
5863 /** Initializes GL objects needed to run the test (excluding iteration-specific objects) */
5864 void TextureViewTestViewSampling::initTest()
5866 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5868 /* Generate and configure BO storage to hold result XFB data of a single
5871 * Each draw call outputs 6 vertices. For each vertex, 4 ints will be XFBed out. */
5872 gl.genBuffers(1, &m_bo_id);
5873 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
5875 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
5876 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
5878 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 /* draw calls */ * (4 * sizeof(int)), /* as per comment */
5879 DE_NULL, GL_STATIC_DRAW);
5880 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
5882 /* Generate a FBO and bind it to both binding targets */
5883 gl.genFramebuffers(1, &m_fbo_id);
5884 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
5886 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
5887 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
5889 /* Generate and bind a VAO */
5890 gl.genVertexArrays(1, &m_vao_id);
5891 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
5893 gl.bindVertexArray(m_vao_id);
5894 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
5896 /* Generate and configure a texture object we will use to verify view sampling works correctly
5897 * from within a fragment shader.
5899 gl.genTextures(1, &m_result_to_id);
5900 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
5902 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
5903 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
5905 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_reference_texture_width, m_reference_texture_height);
5906 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
5908 /* Determine implementation-specific GL_MAX_COLOR_TEXTURE_SAMPLES value */
5909 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value);
5910 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
5912 /* Modify pixel storage settings so that we don't rely on the default aligment setting. */
5913 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
5914 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
5915 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed.");
5917 /* Modify GL_PATCH_VERTICES setting so that a single patch consists of only a single vertex
5918 * (instead of the default 3) */
5919 gl.patchParameteri(GL_PATCH_VERTICES, 1);
5920 GLU_EXPECT_NO_ERROR(gl.getError(), "glPatchParameteri() call failed.");
5923 /** Initializes and sets up a texture object storage, but does not fill it
5924 * with actual content. Implements separate code paths for handling parent
5927 * @param is_view_texture true if a view texture should be initialized,
5928 * false if te caller needs a parent texture. Note
5929 * that a parent texture must be initialized prior
5930 * to configuring a view texture.
5931 * @param texture_target Texture target to use for the parent texture.
5932 * @param view_texture_target Texture target to use for the view texture.
5934 void TextureViewTestViewSampling::initTextureObject(bool is_view_texture, glw::GLenum texture_target,
5935 glw::GLenum view_texture_target)
5937 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5938 unsigned int texture_depth = 0;
5939 glw::GLuint* to_id_ptr = (is_view_texture) ? &m_view_to_id : &m_to_id;
5941 /* Sanity check: make sure GL_TEXTURE_BUFFER texture target is not requested. This
5942 * would be against the test specification.
5944 DE_ASSERT(texture_target != GL_TEXTURE_BUFFER);
5945 DE_ASSERT(view_texture_target != GL_TEXTURE_BUFFER);
5947 /* If we're going to be creating a cube-map or cube-map array texture view in this iteration,
5948 * make sure the parent or view texture's depth is valid */
5949 if (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
5951 texture_depth = 13; /* 1 + 2 * (6 faces) */
5953 else if (view_texture_target == GL_TEXTURE_CUBE_MAP)
5955 texture_depth = 7; /* 1 + (6 faces) */
5959 texture_depth = m_reference_texture_depth;
5962 if (texture_target == GL_TEXTURE_CUBE_MAP_ARRAY)
5964 texture_depth = 6 /* faces */ * 3;
5967 /* Release the texture object, as we're using immutable texture objects and would
5968 * prefer the resources not to leak.
5970 if (*to_id_ptr != 0)
5972 gl.deleteTextures(1, to_id_ptr);
5974 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
5977 /* Generate a new texture object */
5978 gl.genTextures(1, to_id_ptr);
5979 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
5981 if (is_view_texture)
5983 /* Determine values of arguments we'll pass to glTextureView() call */
5984 unsigned int minlayer = 0;
5985 unsigned int minlevel = 0;
5986 unsigned int numlayers = 0;
5987 unsigned int numlevels = 2;
5989 const bool is_texture_arrayed_texture_target =
5990 (texture_target == GL_TEXTURE_1D_ARRAY || texture_target == GL_TEXTURE_2D_ARRAY ||
5991 texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
5992 const bool is_texture_cube_map_texture_target = (texture_target == GL_TEXTURE_CUBE_MAP);
5993 const bool is_texture_multisample_texture_target =
5994 (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
5995 const bool is_texture_rectangle_texture_target = (texture_target == GL_TEXTURE_RECTANGLE);
5996 const bool is_view_arrayed_texture_target =
5997 (view_texture_target == GL_TEXTURE_1D_ARRAY || view_texture_target == GL_TEXTURE_2D_ARRAY ||
5998 view_texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
5999 view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
6000 const bool is_view_cube_map_texture_target = (view_texture_target == GL_TEXTURE_CUBE_MAP);
6001 const bool is_view_cube_map_array_texture_target = (view_texture_target == GL_TEXTURE_CUBE_MAP_ARRAY);
6003 if (is_texture_multisample_texture_target || is_texture_rectangle_texture_target)
6013 if ((true == is_texture_arrayed_texture_target) ||
6014 ((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_texture_target)) ||
6015 ((false == is_texture_cube_map_texture_target) && (true == is_view_cube_map_array_texture_target)))
6024 if (!is_texture_cube_map_texture_target && is_view_cube_map_array_texture_target)
6028 else if (is_view_cube_map_texture_target || is_view_cube_map_array_texture_target)
6032 else if (is_view_arrayed_texture_target)
6034 if (is_texture_arrayed_texture_target || is_texture_cube_map_texture_target)
6048 /* Set up view texture */
6049 gl.textureView(*to_id_ptr, view_texture_target, m_to_id, GL_RGBA8, minlevel, numlevels, minlayer, numlayers);
6051 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed.");
6053 /* Store the argument values */
6054 m_iteration_view_texture_minlayer = minlayer;
6055 m_iteration_view_texture_minlevel = minlevel;
6056 m_iteration_view_texture_numlayers = numlayers;
6057 m_iteration_view_texture_numlevels = numlevels;
6058 m_iteration_view_texture_target = view_texture_target;
6060 m_testCtx.getLog() << tcu::TestLog::Message << "Created a view for texture target "
6061 << "[" << TextureViewUtilities::getTextureTargetString(view_texture_target) << "] "
6062 << "from a parent texture target "
6063 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6064 << "using arguments: "
6065 << "minlayer:[" << minlayer << "] "
6066 << "minlevel:[" << minlevel << "] "
6067 << "numlayers:[" << numlayers << "] "
6068 << "numlevels:[" << numlevels << "]." << tcu::TestLog::EndMessage;
6070 gl.bindTexture(view_texture_target, *to_id_ptr);
6071 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
6072 } /* if (is_view_texture) */
6075 /* Reset iteration-specific view settings */
6076 m_iteration_parent_texture_depth = 1;
6077 m_iteration_parent_texture_height = 1;
6078 m_iteration_parent_texture_n_levels = 1;
6079 m_iteration_parent_texture_n_samples = 1;
6080 m_iteration_parent_texture_width = 1;
6082 /* Initialize storage for the newly created texture object */
6083 gl.bindTexture(texture_target, *to_id_ptr);
6084 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
6086 /* Use max conformant sample count for multisample texture targets */
6087 if (texture_target == GL_TEXTURE_2D_MULTISAMPLE || texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
6089 m_max_color_texture_samples_gl_value = getMaxConformantSampleCount(texture_target, GL_RGBA8);
6093 /* Use GL_MAX_COLOR_TEXTURE_SAMPLES value for other targets */
6094 gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &m_max_color_texture_samples_gl_value);
6095 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_COLOR_TEXTURE_SAMPLES pname.");
6098 switch (texture_target)
6102 gl.texStorage1D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width);
6104 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage1D() call failed.");
6106 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
6107 m_iteration_parent_texture_width = m_reference_texture_width;
6109 m_testCtx.getLog() << tcu::TestLog::Message
6110 << "Created an immutable parent texture object for texture target "
6111 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6113 << "levels:[" << m_reference_texture_n_mipmaps << "] "
6114 << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage;
6118 case GL_TEXTURE_1D_ARRAY:
6120 gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
6123 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
6125 m_iteration_parent_texture_depth = texture_depth;
6126 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
6127 m_iteration_parent_texture_width = m_reference_texture_width;
6129 m_testCtx.getLog() << tcu::TestLog::Message
6130 << "Created an immutable parent texture object for texture target "
6131 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6133 << "depth:[" << texture_depth << "] "
6134 << "levels:[" << m_reference_texture_n_mipmaps << "] "
6135 << "width:[" << m_reference_texture_width << "]." << tcu::TestLog::EndMessage;
6140 case GL_TEXTURE_CUBE_MAP:
6143 gl.texStorage2D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
6144 m_reference_texture_height);
6146 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
6148 m_iteration_parent_texture_height = m_reference_texture_height;
6149 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
6150 m_iteration_parent_texture_width = m_reference_texture_width;
6152 m_testCtx.getLog() << tcu::TestLog::Message
6153 << "Created an immutable parent texture object for texture target "
6154 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6156 << "levels:[" << m_reference_texture_n_mipmaps << "] "
6157 << "width:[" << m_reference_texture_width << "] "
6158 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
6163 case GL_TEXTURE_RECTANGLE:
6165 gl.texStorage2D(texture_target, 1, /* rectangle textures do not use mip-maps */
6166 GL_RGBA8, m_reference_texture_width, m_reference_texture_height);
6168 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
6170 m_iteration_parent_texture_height = m_reference_texture_height;
6171 m_iteration_parent_texture_width = m_reference_texture_width;
6173 m_testCtx.getLog() << tcu::TestLog::Message
6174 << "Created an immutable parent texture object for texture target "
6175 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6178 << "width:[" << m_reference_texture_width << "] "
6179 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
6184 case GL_TEXTURE_2D_ARRAY:
6186 gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
6187 m_reference_texture_height, texture_depth);
6189 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
6191 m_iteration_parent_texture_depth = texture_depth;
6192 m_iteration_parent_texture_height = m_reference_texture_height;
6193 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
6194 m_iteration_parent_texture_width = m_reference_texture_width;
6196 m_testCtx.getLog() << tcu::TestLog::Message
6197 << "Created an immutable parent texture object for texture target "
6198 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6200 << "depth:[" << texture_depth << "] "
6201 << "levels:[" << m_reference_texture_n_mipmaps << "] "
6202 << "width:[" << m_reference_texture_width << "] "
6203 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
6208 case GL_TEXTURE_2D_MULTISAMPLE:
6210 gl.texStorage2DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8,
6211 m_reference_texture_width, m_reference_texture_height,
6212 GL_TRUE); /* fixedsamplelocations */
6214 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
6216 m_iteration_parent_texture_height = m_reference_texture_height;
6217 m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value;
6218 m_iteration_parent_texture_width = m_reference_texture_width;
6220 m_testCtx.getLog() << tcu::TestLog::Message
6221 << "Created an immutable parent texture object for texture target "
6222 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6224 << "samples:[" << m_max_color_texture_samples_gl_value << "] "
6225 << "width:[" << m_reference_texture_width << "] "
6226 << "height:[" << m_reference_texture_height << "]." << tcu::TestLog::EndMessage;
6231 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
6233 gl.texStorage3DMultisample(texture_target, m_max_color_texture_samples_gl_value, GL_RGBA8,
6234 m_reference_texture_width, m_reference_texture_height, texture_depth,
6235 GL_TRUE); /* fixed sample locations */
6237 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed.");
6239 m_iteration_parent_texture_depth = texture_depth;
6240 m_iteration_parent_texture_height = m_reference_texture_height;
6241 m_iteration_parent_texture_n_samples = m_max_color_texture_samples_gl_value;
6242 m_iteration_parent_texture_width = m_reference_texture_width;
6244 m_testCtx.getLog() << tcu::TestLog::Message
6245 << "Created an immutable parent texture object for texture target "
6246 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6248 << "samples:[" << m_max_color_texture_samples_gl_value << "] "
6249 << "width:[" << m_reference_texture_width << "] "
6250 << "height:[" << m_reference_texture_height << "] "
6251 << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage;
6257 case GL_TEXTURE_CUBE_MAP_ARRAY:
6259 gl.texStorage3D(texture_target, m_reference_texture_n_mipmaps, GL_RGBA8, m_reference_texture_width,
6260 m_reference_texture_height, texture_depth);
6262 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
6264 m_iteration_parent_texture_depth = texture_depth;
6265 m_iteration_parent_texture_height = m_reference_texture_height;
6266 m_iteration_parent_texture_n_levels = m_reference_texture_n_mipmaps;
6267 m_iteration_parent_texture_width = m_reference_texture_width;
6269 m_testCtx.getLog() << tcu::TestLog::Message
6270 << "Created an immutable parent texture object for texture target "
6271 << "[" << TextureViewUtilities::getTextureTargetString(texture_target) << "] "
6273 << "levels:[" << m_reference_texture_n_mipmaps << "] "
6274 << "width:[" << m_reference_texture_width << "] "
6275 << "height:[" << m_reference_texture_height << "] "
6276 << "depth:[" << texture_depth << "]." << tcu::TestLog::EndMessage;
6283 TCU_FAIL("Unrecognized texture target.");
6285 } /* switch (texture_target) */
6287 m_iteration_parent_texture_target = texture_target;
6290 /* Configure texture filtering */
6291 if (texture_target != GL_TEXTURE_2D_MULTISAMPLE && texture_target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY &&
6292 texture_target != GL_TEXTURE_RECTANGLE)
6294 gl.texParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6295 gl.texParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
6297 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
6301 /** Executes test iteration.
6303 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
6305 tcu::TestNode::IterateResult TextureViewTestViewSampling::iterate()
6307 bool has_failed = false;
6309 /* Make sure GL_ARB_texture_view is reported as supported before carrying on
6310 * with actual execution */
6311 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
6313 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
6315 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
6318 /* Initialize all objects required to run the test */
6321 /* Initialize per-sample filler program */
6322 initPerSampleFillerProgramObject();
6324 /* Iterate through all texture/view texture target combinations */
6325 TextureViewUtilities::_compatible_texture_target_pairs_const_iterator texture_target_iterator;
6326 TextureViewUtilities::_compatible_texture_target_pairs texture_target_pairs =
6327 TextureViewUtilities::getLegalTextureAndViewTargetCombinations();
6329 for (texture_target_iterator = texture_target_pairs.begin(); texture_target_iterator != texture_target_pairs.end();
6330 ++texture_target_iterator)
6332 const glw::GLenum parent_texture_target = texture_target_iterator->first;
6333 const glw::GLenum view_texture_target = texture_target_iterator->second;
6335 /* Initialize parent texture */
6336 initTextureObject(false /* is_view_texture */, parent_texture_target, view_texture_target);
6338 /* Initialize view */
6339 initTextureObject(true /* is_view_texture */, parent_texture_target, view_texture_target);
6341 /* Initialize contents of the parent texture */
6342 initParentTextureContents();
6344 /* Initialize iteration-specific test program object */
6345 initIterationSpecificProgramObject();
6347 /* Run the actual test */
6348 bool status = executeTest();
6354 m_testCtx.getLog() << tcu::TestLog::Message << "Test case failed." << tcu::TestLog::EndMessage;
6358 m_testCtx.getLog() << tcu::TestLog::Message << "Test case succeeded." << tcu::TestLog::EndMessage;
6364 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6368 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6374 /** De-allocates existing reference color storage (if one already exists) and
6375 * allocates a new one using user-provided properties.
6377 * @param n_layers Amount of layers to consider. Use a value of 1 for non-arrayed
6379 * @param n_faces Amount of faces to consider. Use a value of 1 for non-CM
6381 * @param n_mipmaps Amount of mip-maps to consider. Use a value of 1 for non-mipmapped
6383 * @param n_samples Amount of samples to consider. Use a value of 1 for single-sampled
6386 void TextureViewTestViewSampling::resetReferenceColorStorage(unsigned int n_layers, unsigned int n_faces,
6387 unsigned int n_mipmaps, unsigned int n_samples)
6390 DE_ASSERT(n_layers >= 1);
6391 DE_ASSERT(n_faces >= 1);
6392 DE_ASSERT(n_mipmaps >= 1);
6393 DE_ASSERT(n_samples >= 1);
6395 /* Allocate the descriptor if it's the first time the test will be
6396 * attempting to access it */
6397 if (m_reference_color_storage == DE_NULL)
6399 m_reference_color_storage = new _reference_color_storage(n_faces, n_layers, n_mipmaps, n_samples);
6403 /* The descriptor's already there so we only need to update the properties */
6404 m_reference_color_storage->n_faces = n_faces;
6405 m_reference_color_storage->n_layers = n_layers;
6406 m_reference_color_storage->n_mipmaps = n_mipmaps;
6407 m_reference_color_storage->n_samples = n_samples;
6410 /* If there's any data descriptor found allocated at this point,
6412 if (m_reference_color_storage->data != DE_NULL)
6414 delete[] m_reference_color_storage->data;
6416 m_reference_color_storage->data = DE_NULL;
6419 m_reference_color_storage->data = new tcu::Vec4[n_layers * n_faces * n_mipmaps * n_samples];
6422 /** Assigns user-specified reference color to a specific sample of a layer/face's mip-map.
6424 * This function throws an assertion failure if the requested layer/face/mip-map/sample index
6427 * @param n_layer Layer index to use for the association. Use a value of 0 for non-arrayed texture
6429 * @param n_face Face index to use for the association. Use a value of 0 for non-CM texture targets.
6430 * @param n_mipmap Mip-map index to use for the association. Use a value of 0 for non-mipmapped texture
6432 * @param n_sample Sample index to use for the association. Use a value of 0 for single-sampled texture
6434 * @param color Color to associate with the specified sample.
6436 void TextureViewTestViewSampling::setReferenceColor(unsigned int n_layer, unsigned int n_face, unsigned int n_mipmap,
6437 unsigned int n_sample, tcu::Vec4 color)
6439 DE_ASSERT(m_reference_color_storage != DE_NULL);
6440 if (m_reference_color_storage != DE_NULL)
6442 DE_ASSERT(n_face < m_reference_color_storage->n_faces);
6443 DE_ASSERT(n_layer < m_reference_color_storage->n_layers);
6444 DE_ASSERT(n_mipmap < m_reference_color_storage->n_mipmaps);
6445 DE_ASSERT(n_sample < m_reference_color_storage->n_samples);
6449 * layers -> faces -> mipmaps -> samples */
6450 const unsigned int index =
6451 n_layer * (m_reference_color_storage->n_faces * m_reference_color_storage->n_mipmaps *
6452 m_reference_color_storage->n_samples) +
6453 n_face * (m_reference_color_storage->n_mipmaps * m_reference_color_storage->n_samples) +
6454 n_mipmap * (m_reference_color_storage->n_samples) + n_sample;
6456 m_reference_color_storage->data[index] = color;
6462 * @param context Rendering context.
6464 TextureViewTestViewClasses::TextureViewTestViewClasses(deqp::Context& context)
6465 : TestCase(context, "view_classes", "Verifies view sampling works correctly. Tests all valid"
6466 " texture/view internalformat combinations.")
6474 , m_decompressed_mipmap_data(DE_NULL)
6475 , m_mipmap_data(DE_NULL)
6477 , m_has_test_failed(false)
6478 , m_texture_height(4)
6479 , m_texture_unit_for_parent_texture(GL_TEXTURE0)
6480 , m_texture_unit_for_view_texture(GL_TEXTURE1)
6481 , m_texture_width(4)
6482 , m_view_data_offset(0)
6484 /* Left blank on purpose */
6487 /** Deinitializes all buffers and GL objects that may have been created
6488 * during test execution. Also restores GL state that may have been modified.
6490 void TextureViewTestViewClasses::deinit()
6492 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6496 gl.deleteBuffers(1, &m_bo_id);
6501 if (m_decompressed_mipmap_data != DE_NULL)
6503 delete[] m_decompressed_mipmap_data;
6505 m_decompressed_mipmap_data = DE_NULL;
6508 if (m_mipmap_data != DE_NULL)
6510 delete[] m_mipmap_data;
6512 m_mipmap_data = DE_NULL;
6517 gl.deleteProgram(m_po_id);
6524 gl.deleteTextures(1, &m_to_id);
6529 if (m_to_temp_id != 0)
6531 gl.deleteTextures(1, &m_to_temp_id);
6538 gl.deleteVertexArrays(1, &m_vao_id);
6543 if (m_view_to_id != 0)
6545 gl.deleteTextures(1, &m_view_to_id);
6552 gl.deleteShader(m_vs_id);
6557 /* Bring back the default pixel storage settings that the test may have modified. */
6558 gl.pixelStorei(GL_PACK_ALIGNMENT, 4);
6559 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4);
6561 /* Restore rasterization */
6562 gl.enable(GL_RASTERIZER_DISCARD);
6565 /** Reads user-specified amount of components and stores it in user-provided location,
6566 * according to user-defined format (snorm, unorm, etc.) and component size.
6568 * This function assumes component sizes are aligned on by boundary (that is: size % 8
6569 * equals 0 for all components). An assertion failure will occur if this requirement is
6571 * This function throws TestError exception if any of the requested component sizes
6572 * or format is not supported.
6574 * @param data Raw data buffer to read the data from.
6575 * @param n_components Amount of components to read.
6576 * @param component_sizes 4 ints subsequently defining component size for R/G/B/A channels.
6578 * @param format Format to be used for data retrieval. This defines data format of
6579 * the underlying components (for instance: for UNORMs we need to
6580 * divide the read ubyte/ushort/uint data by maximum value allowed for
6581 * the type minus one)
6582 * @param result Location to store the read components. Must not be NULL. Must be
6583 * large enough to hold requested amount of components of user-specified
6587 void TextureViewTestViewClasses::getComponentDataForByteAlignedInternalformat(const unsigned char* data,
6588 const unsigned int n_components,
6589 const unsigned int* component_sizes,
6590 const _format format, void* result)
6592 float* result_float = (float*)result;
6593 signed int* result_sint = (signed int*)result;
6594 unsigned int* result_uint = (unsigned int*)result;
6596 /* Sanity checks: we assume the components are aligned on byte boundary. */
6597 DE_ASSERT((component_sizes[0] % 8) == 0 && (component_sizes[1] % 8) == 0 && (component_sizes[2] % 8) == 0 &&
6598 (component_sizes[3] % 8) == 0);
6600 for (unsigned int n_component = 0; n_component < n_components;
6601 data += (component_sizes[n_component] >> 3 /* 8 bits/byte */), ++n_component)
6607 switch (component_sizes[n_component])
6610 result_float[n_component] = deFloat16To32(*(const deFloat16*)data);
6613 result_float[n_component] = *(float*)data;
6617 TCU_FAIL("Unsupported component size");
6623 case FORMAT_SIGNED_INTEGER:
6625 switch (component_sizes[n_component])
6628 result_sint[n_component] = *(signed char*)data;
6631 result_sint[n_component] = *(signed short*)data;
6634 result_sint[n_component] = *(signed int*)data;
6638 TCU_FAIL("Unsupported component size");
6646 switch (component_sizes[n_component])
6649 result_float[n_component] = float(*(signed char*)data) / 127.0f;
6652 result_float[n_component] = float(*(signed short*)data) / 32767.0f;
6656 TCU_FAIL("Unsupported component size");
6659 if (result_float[n_component] < -1.0f)
6661 result_float[n_component] = -1.0f;
6669 switch (component_sizes[n_component])
6672 result_float[n_component] = float(*((unsigned char*)data)) / 255.0f;
6675 result_float[n_component] = float(*((unsigned short*)data)) / 65535.0f;
6679 TCU_FAIL("Unsupported component size");
6685 case FORMAT_UNSIGNED_INTEGER:
6687 switch (component_sizes[n_component])
6690 result_uint[n_component] = *(unsigned char*)data;
6693 result_uint[n_component] = *(unsigned short*)data;
6696 result_uint[n_component] = *(unsigned int*)data;
6700 TCU_FAIL("Unsupported component size");
6708 TCU_FAIL("Unrecognized mip-map format");
6710 } /* switch (view_format) */
6711 } /* for (all components) */
6714 /** Initializes buffer object storage of sufficient size to hold data that will be
6715 * XFBed out by the test's vertex shader, given user-specified parent texture &
6716 * view's internalformats.
6718 * Throws TestError exceptions if GL calls fail.
6720 * @param texture_internalformat Internalformat used by the parent texture object,
6721 * from which the view will be created.
6722 * @param view_internalformat Internalformat that will be used by the texture view.
6724 void TextureViewTestViewClasses::initBufferObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat)
6726 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6728 /* Calculate how much size we will need to read the XFBed data. Each sampled data
6729 * will either end up stored in a vecX, ivecX or uvecX (where X stands for amount
6730 * of components supported by considered internalformat), so we can assume it will
6731 * take a sizeof(float) = sizeof(int) = sizeof(unsigned int)
6733 const unsigned int parent_texture_n_components =
6734 TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat);
6735 const unsigned int view_texture_n_components =
6736 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
6738 /* Configure buffer object storage.
6740 * NOTE: We do not care about the data type of the stored data, since sizes of the
6741 * types we're interested in (floats, ints and uints) match.
6743 DE_ASSERT(sizeof(float) == sizeof(unsigned int) && sizeof(float) == sizeof(int));
6746 static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width +
6747 view_texture_n_components * sizeof(float) * m_texture_height * m_texture_width);
6749 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_size, DE_NULL, /* data */
6751 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
6753 /* For XFB, we'll be outputting data sampled from both the texture and the view.
6754 * Sampled texture data will go to the first half of the buffer, and the corresponding
6755 * view data will go to the one half.
6757 * Store the offset, from which the view's data will start so that we can correctly
6758 * configure buffer object bindings in initProgramObject()
6760 m_view_data_offset =
6761 static_cast<unsigned int>(parent_texture_n_components * sizeof(float) * m_texture_height * m_texture_width);
6764 /** Initializes a program object that should be used for the test, given
6765 * user-specified texture and view internalformats.
6767 * @param texture_internalformat Internalformat used by the parent texture object,
6768 * from which the view will be created.
6769 * @param view_internalformat Internalformat that will be used by the texture view.
6771 void TextureViewTestViewClasses::initProgramObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat)
6773 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6775 /* Determine which samplers we should be using for sampling both textures */
6776 const unsigned int texture_n_components =
6777 TextureViewUtilities::getAmountOfComponentsForInternalformat(texture_internalformat);
6778 const _sampler_type texture_sampler_type =
6779 TextureViewUtilities::getSamplerTypeForInternalformat(texture_internalformat);
6780 const char* texture_sampler_data_type_glsl =
6781 TextureViewUtilities::getGLSLDataTypeForSamplerType(texture_sampler_type, texture_n_components);
6782 const char* texture_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(texture_sampler_type);
6783 const char* texture_swizzle_glsl =
6784 (texture_n_components == 4) ? "xyzw" :
6785 (texture_n_components == 3) ? "xyz" : (texture_n_components == 2) ? "xy" : "x";
6786 const unsigned int view_n_components =
6787 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
6788 const _sampler_type view_sampler_type = TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat);
6789 const char* view_sampler_data_type_glsl =
6790 TextureViewUtilities::getGLSLDataTypeForSamplerType(view_sampler_type, view_n_components);
6791 const char* view_sampler_glsl = TextureViewUtilities::getGLSLTypeForSamplerType(view_sampler_type);
6792 const char* view_swizzle_glsl =
6793 (view_n_components == 4) ? "xyzw" : (view_n_components == 3) ? "xyz" : (view_n_components == 2) ? "xy" : "x";
6795 /* Form vertex shader body */
6796 const char* token_texture_data_type = "TEXTURE_DATA_TYPE";
6797 const char* token_texture_sampler = "TEXTURE_SAMPLER";
6798 const char* token_texture_swizzle = "TEXTURE_SWIZZLE";
6799 const char* token_view_data_type = "VIEW_DATA_TYPE";
6800 const char* token_view_sampler = "VIEW_SAMPLER";
6801 const char* token_view_swizzle = "VIEW_SWIZZLE";
6802 const char* vs_template_body = "#version 400\n"
6804 "uniform TEXTURE_SAMPLER texture;\n"
6805 "uniform VIEW_SAMPLER view;\n"
6807 "out TEXTURE_DATA_TYPE out_texture_data;\n"
6808 "out VIEW_DATA_TYPE out_view_data;\n"
6812 " ivec2 uv = ivec2(gl_VertexID % 4,\n"
6813 " gl_VertexID / 4);\n"
6815 " out_texture_data = texelFetch(texture, uv, 0).TEXTURE_SWIZZLE;\n"
6816 " out_view_data = texelFetch(view, uv, 0).VIEW_SWIZZLE;\n"
6819 std::size_t token_position = std::string::npos;
6820 std::string vs_body = vs_template_body;
6822 while ((token_position = vs_body.find(token_texture_data_type)) != std::string::npos)
6824 vs_body.replace(token_position, strlen(token_texture_data_type), texture_sampler_data_type_glsl);
6827 while ((token_position = vs_body.find(token_texture_sampler)) != std::string::npos)
6829 vs_body.replace(token_position, strlen(token_texture_sampler), texture_sampler_glsl);
6832 while ((token_position = vs_body.find(token_texture_swizzle)) != std::string::npos)
6834 vs_body.replace(token_position, strlen(token_texture_swizzle), texture_swizzle_glsl);
6837 while ((token_position = vs_body.find(token_view_data_type)) != std::string::npos)
6839 vs_body.replace(token_position, strlen(token_view_data_type), view_sampler_data_type_glsl);
6842 while ((token_position = vs_body.find(token_view_sampler)) != std::string::npos)
6844 vs_body.replace(token_position, strlen(token_view_sampler), view_sampler_glsl);
6847 while ((token_position = vs_body.find(token_view_swizzle)) != std::string::npos)
6849 vs_body.replace(token_position, strlen(token_view_swizzle), view_swizzle_glsl);
6852 /* Compile the shader */
6853 glw::GLint compile_status = GL_FALSE;
6854 const char* vs_body_raw_ptr = vs_body.c_str();
6856 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body_raw_ptr, DE_NULL /* length */);
6857 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
6859 gl.compileShader(m_vs_id);
6860 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
6862 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
6863 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
6865 if (compile_status != GL_TRUE)
6867 TCU_FAIL("Shader compilation failed");
6870 /* Configure test program object for XFB */
6871 const char* varying_names[] = { "out_texture_data", "out_view_data" };
6872 const unsigned int n_varying_names = sizeof(varying_names) / sizeof(varying_names[0]);
6874 gl.transformFeedbackVaryings(m_po_id, n_varying_names, varying_names, GL_SEPARATE_ATTRIBS);
6875 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
6877 /* Configure buffer object bindings for XFB */
6878 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, /* index for 'out_texture_data' */
6879 m_bo_id, 0, /* offset */
6880 m_view_data_offset); /* size */
6881 gl.bindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 1, /* index for 'out_view_data' */
6882 m_bo_id, m_view_data_offset, /* offset */
6883 m_bo_size - m_view_data_offset); /* size */
6885 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferRange() call(s) failed.");
6887 /* Link the program object */
6888 glw::GLint link_status = GL_FALSE;
6890 gl.linkProgram(m_po_id);
6891 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
6893 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
6894 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
6896 if (link_status != GL_TRUE)
6898 TCU_FAIL("Program linking failed.");
6901 /* Configure sampler uniforms */
6902 glw::GLint texture_uniform_location = gl.getUniformLocation(m_po_id, "texture");
6903 glw::GLint view_uniform_location = gl.getUniformLocation(m_po_id, "view");
6905 if (texture_uniform_location == -1)
6907 TCU_FAIL("'texture' uniform is considered inactive which is invalid");
6910 if (view_uniform_location == -1)
6912 TCU_FAIL("'view' uniform is considered inactive which is invalid");
6915 gl.useProgram(m_po_id);
6916 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
6918 gl.uniform1i(texture_uniform_location, m_texture_unit_for_parent_texture - GL_TEXTURE0);
6919 gl.uniform1i(view_uniform_location, m_texture_unit_for_view_texture - GL_TEXTURE0);
6920 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call(s) failed.");
6923 /** Creates GL objects required to run the test, as well as modifies GL
6924 * configuration (pixel pack/unpack settings, enables 'rasterizer discard' mode)
6925 * in order for the test to run properly.
6927 void TextureViewTestViewClasses::initTest()
6929 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6931 /* Generate objects that will be used by all test iterations.
6933 * Note that we're not generating texture objects here. This is owing to the fact
6934 * we'll be using immutable textures and it makes more sense to generate the objects
6935 * in initTexture() instead.
6937 gl.genBuffers(1, &m_bo_id);
6938 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
6940 m_po_id = gl.createProgram();
6941 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
6943 gl.genVertexArrays(1, &m_vao_id);
6944 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
6946 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
6947 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
6949 /* Attach the vertex shader to the program object */
6950 gl.attachShader(m_po_id, m_vs_id);
6951 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
6953 /* Configure general buffer object binding. Indiced bindings will be configured
6954 * in initProgramObject()
6956 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
6957 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
6959 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
6960 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
6963 gl.bindVertexArray(m_vao_id);
6964 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
6966 /* Modify pack & unpack alignment settings */
6967 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
6968 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
6969 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call(s) failed.");
6971 /* Disable rasterizatino */
6972 gl.enable(GL_RASTERIZER_DISCARD);
6973 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
6976 /** Generates and initializes storage of either the parent texture object or the
6977 * texture view, using user-specified internalformat.
6979 * @param should_init_parent_texture true to initialize parent texture object storage,
6980 * false to configure texture view.
6981 * @param internalformat Internalformat to use for the process.
6982 * @param viewformat Internalformat that will be used by "view" texture.
6985 void TextureViewTestViewClasses::initTextureObject(bool should_init_parent_texture, glw::GLenum texture_internalformat,
6986 glw::GLenum view_internalformat)
6988 glw::GLenum cached_view_internalformat = view_internalformat;
6989 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6990 glw::GLuint* to_id_ptr = (should_init_parent_texture) ? &m_to_id : &m_view_to_id;
6992 /* If the object we're about to initialize has already been created, delete it first. */
6993 if (*to_id_ptr != 0)
6995 gl.deleteTextures(1, to_id_ptr);
6996 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
7001 /* Generate a new texture object */
7002 gl.genTextures(1, to_id_ptr);
7004 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
7006 /* Initialize the object */
7007 if (should_init_parent_texture)
7009 gl.bindTexture(GL_TEXTURE_2D, *to_id_ptr);
7010 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7012 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
7013 texture_internalformat, m_texture_width, m_texture_height);
7015 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
7019 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, view_internalformat, 0, /* minlevel */
7024 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed.");
7026 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
7027 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7030 if (should_init_parent_texture)
7032 /* We need to fill the base mip-map with actual contents. Calculate how much
7033 * data we will need to fill a 4x4 mip-map, given the requested internalformat.
7035 bool is_internalformat_compressed = TextureViewUtilities::isInternalformatCompressed(texture_internalformat);
7036 glw::GLenum internalformat_to_use = GL_NONE;
7038 if (is_internalformat_compressed)
7040 /* In order to initialize texture objects defined with a compressed internalformat
7041 * using raw decompressed data, we need to override caller-specified internalformat
7042 * with an internalformat that will describe decompressed data. The data will then
7043 * be converted by GL to the compressed internalformat that was used for the previous
7044 * glTexStorage2D() call.
7046 _format format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat);
7048 if (format == FORMAT_FLOAT)
7050 internalformat_to_use = GL_RGBA32F;
7054 DE_ASSERT(format == FORMAT_UNORM || format == FORMAT_SNORM);
7056 internalformat_to_use = GL_RGBA8;
7059 view_internalformat = internalformat_to_use;
7063 internalformat_to_use = texture_internalformat;
7066 /* Allocate the buffer.
7068 * NOTE: This buffer is used in verifyResults(). When no longer needed, it will either
7069 * be deallocated there or in deinit().
7071 glw::GLenum format_to_use = TextureViewUtilities::getGLFormatOfInternalformat(internalformat_to_use);
7072 glw::GLenum type_to_use = TextureViewUtilities::getTypeCompatibleWithInternalformat(internalformat_to_use);
7073 const glw::GLenum view_type = TextureViewUtilities::getTypeCompatibleWithInternalformat(view_internalformat);
7075 /* For some internalformats, we need to use a special data type in order to avoid
7076 * implicit data conversion during glTexSubImage2D() call.
7078 switch (texture_internalformat)
7080 case GL_R11F_G11F_B10F:
7081 type_to_use = GL_UNSIGNED_INT_10F_11F_11F_REV;
7084 type_to_use = GL_UNSIGNED_INT_5_9_9_9_REV;
7087 type_to_use = GL_UNSIGNED_INT_2_10_10_10_REV;
7090 /* Fall-through for other internalformats! */
7091 } /* switch (texture_internalformat) */
7094 const unsigned int mipmap_raw_size = TextureViewUtilities::getTextureDataSize(
7095 internalformat_to_use, type_to_use, m_texture_width, m_texture_height);
7097 if (m_mipmap_data != NULL)
7099 delete[] m_mipmap_data;
7101 m_mipmap_data = NULL;
7104 m_mipmap_data = new unsigned char[mipmap_raw_size];
7106 /* Prepare data for texture */
7107 memset(m_mipmap_data, 0, mipmap_raw_size);
7113 glw::GLbyte* buffer = (glw::GLbyte*)m_mipmap_data;
7114 const glw::GLuint n_total_components = mipmap_raw_size / 1;
7116 for (glw::GLuint i = 0; i < n_total_components; ++i)
7118 buffer[i] = static_cast<glw::GLbyte>(i - 128);
7126 glw::GLshort* buffer = (glw::GLshort*)m_mipmap_data;
7127 const glw::GLuint n_total_components = mipmap_raw_size / 2;
7129 for (glw::GLuint i = 0; i < n_total_components; ++i)
7131 buffer[i] = static_cast<glw::GLshort>(i - 0xC000); // 0xC000 = (fp16) -2 makes this non de-norm
7139 glw::GLint* buffer = (glw::GLint*)m_mipmap_data;
7140 const glw::GLuint n_total_components = mipmap_raw_size / 4;
7142 for (glw::GLuint i = 0; i < n_total_components; ++i)
7144 buffer[i] = i - 128;
7150 case GL_UNSIGNED_BYTE:
7152 glw::GLubyte* buffer = (glw::GLubyte*)m_mipmap_data;
7153 const glw::GLuint n_total_components = mipmap_raw_size / 1;
7155 for (glw::GLuint i = 0; i < n_total_components; ++i)
7157 buffer[i] = static_cast<glw::GLubyte>(i);
7163 case GL_UNSIGNED_SHORT:
7165 glw::GLushort* buffer = (glw::GLushort*)m_mipmap_data;
7166 const glw::GLuint n_total_components = mipmap_raw_size / 2;
7168 for (glw::GLuint i = 0; i < n_total_components; ++i)
7170 buffer[i] = static_cast<glw::GLushort>(i);
7176 case GL_UNSIGNED_INT:
7178 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data;
7179 const glw::GLuint n_total_components = mipmap_raw_size / 4;
7181 for (glw::GLuint i = 0; i < n_total_components; ++i)
7189 case GL_UNSIGNED_INT_24_8:
7191 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data;
7192 const glw::GLuint n_total_components = mipmap_raw_size / 4;
7194 for (glw::GLuint i = 0; i < n_total_components; ++i)
7196 buffer[i] = (i << 8) | (0xaa);
7202 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
7204 glw::GLfloat* float_buffer = (glw::GLfloat*)m_mipmap_data;
7205 const glw::GLuint n_total_components = mipmap_raw_size / 8;
7206 glw::GLuint* uint_buffer = (glw::GLuint*)(m_mipmap_data + 4);
7208 for (glw::GLuint i = 0; i < n_total_components; ++i)
7210 float_buffer[i * 2] = (float)i - 128;
7211 uint_buffer[i * 2] = (i << 8) | (0xaa);
7219 tcu::Float16* buffer = (tcu::Float16*)m_mipmap_data;
7220 const glw::GLuint n_total_components = mipmap_raw_size / 2;
7222 for (glw::GLuint i = 0; i < n_total_components; ++i)
7224 float value = (float)i - 128;
7226 buffer[i] = (tcu::Float16)value;
7234 glw::GLfloat* float_buffer = (glw::GLfloat*)m_mipmap_data;
7235 const glw::GLuint n_total_components = mipmap_raw_size / 4;
7237 float offset = (cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) ? 0.0f : -128.0f;
7238 for (glw::GLuint i = 0; i < n_total_components; ++i)
7240 float_buffer[i] = (float)i + offset;
7246 case GL_UNSIGNED_INT_2_10_10_10_REV:
7248 glw::GLuint* buffer = (glw::GLuint*)m_mipmap_data;
7249 const glw::GLuint n_total_components = mipmap_raw_size / 4;
7251 for (glw::GLuint i = 0; i < n_total_components; ++i)
7253 buffer[i] = i | (i << 8) | (i << 16);
7261 TCU_FAIL("Unrecognized texture view type");
7263 } /* switch (view_type) */
7265 /* BPTC_FLOAT view class is a special case that needs an extra step. Signed and
7266 * unsigned internal formats use different encodings, so instead of passing
7267 * "regular" 32-bit floating-point data, we need to convert the values we initialized
7268 * above to an actual BPTC representation. Since the encodings differ, we should
7269 * compress these values using the internalformat that we will be later using for the
7272 unsigned int imageSize_to_use = 0;
7273 bool use_glCompressedTexSubImage2D_call = false;
7275 if ((cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
7276 cached_view_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) &&
7277 cached_view_internalformat != texture_internalformat)
7279 /* Create a temporary texture object we'll use to compress the floating-point data. */
7280 gl.genTextures(1, &m_to_temp_id);
7281 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
7283 gl.bindTexture(GL_TEXTURE_2D, m_to_temp_id);
7284 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7286 /* Initialize compressed storage */
7287 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
7288 cached_view_internalformat, m_texture_width, m_texture_height);
7289 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
7291 /* Submit floating-point decompressed data */
7292 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
7295 m_texture_width, m_texture_height, GL_RGB, GL_FLOAT, m_mipmap_data);
7296 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
7298 /* Extract the compressed version */
7299 gl.getCompressedTexImage(GL_TEXTURE_2D, 0, /* level */
7301 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage() call failed.");
7303 /* Delete the temporary texture object */
7304 gl.deleteTextures(1, &m_to_temp_id);
7305 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
7309 /* Revert to previous 2D texture binding */
7310 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
7311 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7313 /* Make sure upcoming glCompressedTexSubImage2D() call is made with sensible arguments */
7314 imageSize_to_use = (unsigned int)ceil((float)m_texture_width / 4.0f) *
7315 (unsigned int)ceil((float)m_texture_height / 4.0f) * 16; /* block size */
7316 use_glCompressedTexSubImage2D_call = true;
7319 /* Fill the mip-map with data */
7320 if (use_glCompressedTexSubImage2D_call)
7322 gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0, /* level */
7325 m_texture_width, m_texture_height, texture_internalformat, imageSize_to_use,
7327 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexSubImage2D() call failed.");
7331 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
7334 m_texture_width, m_texture_height, format_to_use, type_to_use, m_mipmap_data);
7336 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
7340 /* Make sure the texture object is complete */
7341 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7342 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7343 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7344 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
7345 GL_NEAREST); /* we're using texelFetch() so no mipmaps needed */
7346 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7347 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7349 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
7352 /** Executes test iteration.
7354 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
7356 tcu::TestNode::IterateResult TextureViewTestViewClasses::iterate()
7358 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7360 /* Only execute the test if GL_ARB_texture_view is supported */
7361 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
7363 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported, skipping.");
7366 /* Create all GL objects required to run the test */
7369 /* Iterate through all valid "texture internalformat + view internalformat" combinations */
7370 TextureViewUtilities::_compatible_internalformat_pairs_const_iterator internalformat_combination_iterator;
7371 TextureViewUtilities::_compatible_internalformat_pairs internalformat_combinations =
7372 TextureViewUtilities::getLegalTextureAndViewInternalformatCombinations();
7374 for (internalformat_combination_iterator = internalformat_combinations.begin();
7375 internalformat_combination_iterator != internalformat_combinations.end();
7376 internalformat_combination_iterator++)
7378 TextureViewUtilities::_internalformat_pair internalformat_pair = *internalformat_combination_iterator;
7379 glw::GLenum texture_internalformat = internalformat_pair.first;
7380 glw::GLenum view_internalformat = internalformat_pair.second;
7382 /* Initialize parent texture object storage */
7383 initTextureObject(true, /* should_init_parent_texture */
7384 texture_internalformat, view_internalformat);
7386 /* Create the texture view */
7387 initTextureObject(false, /* should_init_parent_texture */
7388 texture_internalformat, view_internalformat);
7390 /* Initialize buffer object storage so that it's large enough to
7391 * hold the result data.
7393 initBufferObject(texture_internalformat, view_internalformat);
7395 /* Create the program object we'll use for the test */
7396 initProgramObject(texture_internalformat, view_internalformat);
7398 /* Configure texture bindings */
7399 gl.activeTexture(m_texture_unit_for_parent_texture);
7400 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
7402 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
7403 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7405 gl.activeTexture(m_texture_unit_for_view_texture);
7406 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
7408 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
7409 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7411 /* Run the test program */
7412 gl.beginTransformFeedback(GL_POINTS);
7413 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
7415 gl.drawArrays(GL_POINTS, 0 /* first */, m_texture_width * m_texture_height);
7416 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
7418 gl.endTransformFeedback();
7419 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
7421 /* Retrieve the results */
7422 const unsigned char* result_bo_data_ptr =
7423 (const unsigned char*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
7424 const unsigned char* result_texture_data_ptr = result_bo_data_ptr;
7425 const unsigned char* result_view_data_ptr = result_bo_data_ptr + m_view_data_offset;
7427 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
7429 /* Verify the retrieved values are valid */
7430 verifyResultData(texture_internalformat, view_internalformat, result_texture_data_ptr, result_view_data_ptr);
7432 /* Unmap the buffer object */
7433 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
7434 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
7435 } /* for (all internalformat combinations) */
7437 if (m_has_test_failed)
7439 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7443 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7449 /** Verifies the data XFBed out by the test's vertex shader is valid.
7451 * @param texture_internalformat Internalformat that was used to define storage
7452 * of the parent texture object.
7453 * @param view_internalformat Internalformat that was used to define texture
7455 * @param texture_data_ptr Data, as XFBed out by the vertex shader, that was
7456 * built by texelFetch() calls operating on the parent
7458 * @param view_data_ptr Data, as XFBed out by the vertex shader, that was
7459 * built by texelFetch() calls operating on the texture
7463 void TextureViewTestViewClasses::verifyResultData(glw::GLenum texture_internalformat, glw::GLenum view_internalformat,
7464 const unsigned char* texture_data_ptr,
7465 const unsigned char* view_data_ptr)
7467 const char* texture_internalformat_string = TextureViewUtilities::getInternalformatString(texture_internalformat);
7468 const char* view_internalformat_string = TextureViewUtilities::getInternalformatString(view_internalformat);
7470 /* For quite a number of cases, we can do a plain memcmp() applied to sampled texture/view data.
7471 * If both buffers are a match, we're OK.
7473 bool has_failed = false;
7474 const unsigned char* mipmap_data = DE_NULL;
7476 if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0)
7478 /* Iterate over all texel components.
7480 * The approach we're taking here works as follows:
7482 * 1) Calculate what values should be sampled for each component using input mipmap
7484 * 2) Compare the reference values against the values returned when sampling the view.
7486 * Note that in step 2) we're dealing with data that is returned by float/int/uint samplers,
7487 * so we need to additionally process the data that we obtain by "casting" input data to
7488 * the view's internalformat before we can perform the comparison.
7490 * Finally, if the reference values are calculated for compressed data, we decompress it
7491 * to GL_R8/GL_RG8/GL_RGB8/GL_RGBA8 internalformat first, depending on how many components
7492 * the compressed internalformat supports.
7494 bool can_continue = true;
7495 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7497 /* Determine a few important properties first */
7498 const bool is_view_internalformat_compressed =
7499 TextureViewUtilities::isInternalformatCompressed(view_internalformat);
7500 unsigned int n_bits_per_view_texel = 0;
7502 const unsigned int n_view_components =
7503 TextureViewUtilities::getAmountOfComponentsForInternalformat(view_internalformat);
7504 _format texture_format = TextureViewUtilities::getFormatOfInternalformat(texture_internalformat);
7506 unsigned int view_component_sizes[4] = { 0 };
7507 _format view_format = TextureViewUtilities::getFormatOfInternalformat(view_internalformat);
7509 if (!is_view_internalformat_compressed)
7511 TextureViewUtilities::getComponentSizeForInternalformat(view_internalformat, view_component_sizes);
7513 n_bits_per_view_texel =
7514 view_component_sizes[0] + view_component_sizes[1] + view_component_sizes[2] + view_component_sizes[3];
7518 if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
7519 texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
7521 /* Each component of decompressed data will be retrieved as a 32-bit FP */
7522 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
7524 view_component_sizes[n_component] = 32 /* bits per byte */;
7527 n_bits_per_view_texel = 32 /* bits per byte */ * n_view_components;
7531 /* Each component of decompressed data is stored as either signed or unsigned
7533 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
7535 view_component_sizes[n_component] = 8 /* bits per byte */;
7538 n_bits_per_view_texel = 8 /* bits per byte */ * n_view_components;
7542 /* If we need to use compressed data as reference, we need to ask GL to decompress
7543 * the mipmap data using view-specific internalformat.
7545 mipmap_data = m_mipmap_data;
7547 if (is_view_internalformat_compressed)
7549 /* Deallocate the buffer if necessary just in case */
7550 if (m_decompressed_mipmap_data != DE_NULL)
7552 delete[] m_decompressed_mipmap_data;
7554 m_decompressed_mipmap_data = DE_NULL;
7557 m_decompressed_mipmap_data =
7558 new unsigned char[m_texture_width * m_texture_height * (n_bits_per_view_texel >> 3)];
7560 glw::GLuint reference_tex_id = m_to_id;
7561 if (texture_internalformat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT ||
7562 texture_internalformat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
7564 // Encodings of SIGNED and UNSIGNED BPTC compressed texture are not compatible
7565 // even though they are in the same view class. Since the "view" texture contains
7566 // the correct encoding for the results we use that as a reference instead of the
7567 // incompatible parent encoded.
7568 reference_tex_id = m_view_to_id;
7570 gl.bindTexture(GL_TEXTURE_2D, reference_tex_id);
7571 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
7573 gl.getTexImage(GL_TEXTURE_2D, 0, /* level */
7574 (n_view_components == 4) ?
7576 (n_view_components == 3) ? GL_RGB : (n_view_components == 2) ? GL_RG : GL_RED,
7577 (texture_format == FORMAT_SNORM) ?
7579 (texture_format == FORMAT_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE,
7580 m_decompressed_mipmap_data);
7582 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage() call failed.");
7584 mipmap_data = m_decompressed_mipmap_data;
7587 for (unsigned int n_texel = 0; n_texel < m_texture_height * m_texture_width && can_continue; ++n_texel)
7589 /* NOTE: Vertex shader stores the sampled contents of a view texture as a
7590 * vec4/ivec4/uvec4. This means that each comonent in view_data_ptr
7591 * always takes sizeof(float) = sizeof(int) = sizeof(uint) bytes.
7593 * NOTE: We cast input mip-map's data to view's internalformat, which is
7594 * why we're assuming each components takes n_bits_per_view_texel
7595 * bits instead of n_bits_per_mipmap_texel.
7597 const unsigned char* mipmap_texel_data =
7598 mipmap_data + (n_bits_per_view_texel >> 3 /* 8 bits/byte */) * n_texel;
7599 float reference_components_float[4] = { 0 };
7600 signed int reference_components_int[4] = { 0 };
7601 unsigned int reference_components_uint[4] = { 0 };
7602 float view_components_float[4] = { 0 };
7603 signed int view_components_int[4] = { 0 };
7604 unsigned int view_components_uint[4] = { 0 };
7605 _sampler_type view_sampler_type =
7606 TextureViewUtilities::getSamplerTypeForInternalformat(view_internalformat);
7607 const unsigned char* view_texel_data = view_data_ptr + sizeof(float) * n_view_components * n_texel;
7609 /* Retrieve data sampled from the view */
7610 for (unsigned int n_component = 0; n_component < n_view_components;
7611 view_texel_data += sizeof(float), /* as per comment */
7614 switch (view_sampler_type)
7616 case SAMPLER_TYPE_FLOAT:
7618 view_components_float[n_component] = *((float*)view_texel_data);
7623 case SAMPLER_TYPE_SIGNED_INTEGER:
7625 view_components_int[n_component] = *((signed int*)view_texel_data);
7630 case SAMPLER_TYPE_UNSIGNED_INTEGER:
7632 view_components_uint[n_component] = *((unsigned int*)view_texel_data);
7639 TCU_FAIL("Unrecognized sampler type");
7641 } /* switch (view_sampler_type) */
7642 } /* for (all components) */
7644 /* Compute reference data. Handle non-byte aligned internalformats manually. */
7645 if (view_internalformat == GL_R11F_G11F_B10F)
7647 const unsigned int* reference_data = (unsigned int*)mipmap_texel_data;
7648 const unsigned int red_component = (*reference_data) & ((1 << 11) - 1);
7649 const unsigned int green_component = (*reference_data >> 11) & ((1 << 11) - 1);
7650 const unsigned int blue_component = (*reference_data >> 22) & ((1 << 10) - 1);
7652 if (view_sampler_type == SAMPLER_TYPE_FLOAT)
7654 reference_components_float[0] = Float11(red_component).asFloat();
7655 reference_components_float[1] = Float11(green_component).asFloat();
7656 reference_components_float[2] = Float10(blue_component).asFloat();
7660 TCU_FAIL("Internal error: invalid sampler type requested");
7663 else if (view_internalformat == GL_RGB9_E5)
7665 /* Refactored version of tcuTexture.cpp::unpackRGB999E5() */
7666 const unsigned int* reference_data = (unsigned int*)mipmap_texel_data;
7667 const unsigned int exponent = (*reference_data >> 27) & ((1 << 5) - 1);
7668 const unsigned int red_component = (*reference_data) & ((1 << 9) - 1);
7669 const unsigned int green_component = (*reference_data >> 9) & ((1 << 9) - 1);
7670 const unsigned int blue_component = (*reference_data >> 18) & ((1 << 9) - 1);
7672 float shared_exponent =
7673 deFloatPow(2.0f, (float)((int)exponent - 15 /* exponent bias */ - 9 /* mantissa */));
7675 if (view_sampler_type == SAMPLER_TYPE_FLOAT)
7677 reference_components_float[0] = float(red_component) * shared_exponent;
7678 reference_components_float[1] = float(green_component) * shared_exponent;
7679 reference_components_float[2] = float(blue_component) * shared_exponent;
7683 TCU_FAIL("Internal error: invalid sampler type requested");
7686 else if (view_internalformat == GL_RGB10_A2)
7688 unsigned int* reference_data = (unsigned int*)mipmap_texel_data;
7689 const unsigned int mask_rgb = (1 << 10) - 1;
7690 const unsigned int mask_a = (1 << 2) - 1;
7692 if (view_sampler_type == SAMPLER_TYPE_FLOAT)
7694 reference_components_float[0] = float(((*reference_data)) & (mask_rgb)) / float(mask_rgb);
7695 reference_components_float[1] = float(((*reference_data) >> 10) & (mask_rgb)) / float(mask_rgb);
7696 reference_components_float[2] = float(((*reference_data) >> 20) & (mask_rgb)) / float(mask_rgb);
7697 reference_components_float[3] = float(((*reference_data) >> 30) & (mask_a)) / float(mask_a);
7701 TCU_FAIL("Internal error: invalid sampler type requested");
7704 else if (view_internalformat == GL_RGB10_A2UI)
7706 unsigned int* reference_data = (unsigned int*)mipmap_texel_data;
7707 const unsigned int mask_rgb = (1 << 10) - 1;
7708 const unsigned int mask_a = (1 << 2) - 1;
7710 if (view_sampler_type == SAMPLER_TYPE_UNSIGNED_INTEGER)
7712 reference_components_uint[0] = ((*reference_data)) & (mask_rgb);
7713 reference_components_uint[1] = ((*reference_data) >> 10) & (mask_rgb);
7714 reference_components_uint[2] = ((*reference_data) >> 20) & (mask_rgb);
7715 reference_components_uint[3] = ((*reference_data) >> 30) & (mask_a);
7719 TCU_FAIL("Internal error: invalid sampler type requested");
7722 else if (view_internalformat == GL_RG16F)
7724 unsigned short* reference_data = (unsigned short*)mipmap_texel_data;
7726 if (view_sampler_type == SAMPLER_TYPE_FLOAT)
7728 reference_components_float[0] = tcu::Float16(*(reference_data + 0)).asFloat();
7729 reference_components_float[1] = tcu::Float16(*(reference_data + 1)).asFloat();
7733 TCU_FAIL("Internal error: invalid sampler type requested");
7738 void* result_data = NULL;
7740 switch (view_sampler_type)
7742 case SAMPLER_TYPE_FLOAT:
7743 result_data = reference_components_float;
7745 case SAMPLER_TYPE_SIGNED_INTEGER:
7746 result_data = reference_components_int;
7748 case SAMPLER_TYPE_UNSIGNED_INTEGER:
7749 result_data = reference_components_uint;
7753 TCU_FAIL("Unrecognized sampler type");
7756 getComponentDataForByteAlignedInternalformat(mipmap_texel_data, n_view_components, view_component_sizes,
7757 view_format, result_data);
7760 for (unsigned int n_component = 0; n_component < n_view_components; ++n_component)
7762 /* If view texture operates on sRGB color space, we need to adjust our
7763 * reference value so that it is moved back into linear space.
7765 if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) &&
7766 !TextureViewUtilities::isInternalformatSRGB(texture_internalformat))
7768 DE_ASSERT(view_sampler_type == SAMPLER_TYPE_FLOAT);
7770 /* Convert as per (8.14) from GL4.4 spec. Exclude alpha channel. */
7771 if (n_component != 3)
7773 if (reference_components_float[n_component] <= 0.04045f)
7775 reference_components_float[n_component] /= 12.92f;
7779 reference_components_float[n_component] =
7780 deFloatPow((reference_components_float[n_component] + 0.055f) / 1.055f, 2.4f);
7782 } /* if (n_component != 3) */
7783 } /* if (TextureViewUtilities::isInternalformatSRGB(view_internalformat) ) */
7785 /* Compare the reference and view texture values */
7786 const float epsilon_float = 1.0f / float((1 << (view_component_sizes[n_component] - 1)) - 1);
7787 const signed int epsilon_int = 1;
7788 const unsigned int epsilon_uint = 1;
7790 switch (view_sampler_type)
7792 case SAMPLER_TYPE_FLOAT:
7794 if (de::abs(reference_components_float[n_component] - view_components_float[n_component]) >
7803 case SAMPLER_TYPE_SIGNED_INTEGER:
7805 signed int larger_value = 0;
7806 signed int smaller_value = 0;
7808 if (reference_components_int[n_component] > view_components_int[n_component])
7810 larger_value = reference_components_int[n_component];
7811 smaller_value = view_components_int[n_component];
7815 smaller_value = reference_components_int[n_component];
7816 larger_value = view_components_int[n_component];
7819 if ((larger_value - smaller_value) > epsilon_int)
7827 case SAMPLER_TYPE_UNSIGNED_INTEGER:
7829 unsigned int larger_value = 0;
7830 unsigned int smaller_value = 0;
7832 if (reference_components_uint[n_component] > view_components_uint[n_component])
7834 larger_value = reference_components_uint[n_component];
7835 smaller_value = view_components_uint[n_component];
7839 smaller_value = reference_components_uint[n_component];
7840 larger_value = view_components_uint[n_component];
7843 if ((larger_value - smaller_value) > epsilon_uint)
7852 TCU_FAIL("Unrecognized sampler type");
7853 } /* switch (view_sampler_type) */
7857 can_continue = false;
7859 switch (view_sampler_type)
7861 case SAMPLER_TYPE_FLOAT:
7863 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data sampled from a texture view "
7865 << view_internalformat_string << "]"
7866 " created from a texture object"
7868 << texture_internalformat_string << "]"
7871 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height)
7872 << "): expected:(" << reference_components_float[0] << ", "
7873 << reference_components_float[1] << ", " << reference_components_float[2]
7874 << ", " << reference_components_float[3] << ") found:("
7875 << view_components_float[0] << ", " << view_components_float[1] << ", "
7876 << view_components_float[2] << ", " << view_components_float[3] << ")."
7877 << tcu::TestLog::EndMessage;
7882 case SAMPLER_TYPE_SIGNED_INTEGER:
7885 << tcu::TestLog::Message << "Invalid data sampled from a signed integer texture view "
7887 << view_internalformat_string << "]"
7888 " created from a texture object"
7890 << texture_internalformat_string << "]"
7893 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:("
7894 << reference_components_int[0] << ", " << reference_components_int[1] << ", "
7895 << reference_components_int[2] << ", " << reference_components_int[3] << ") found:("
7896 << view_components_int[0] << ", " << view_components_int[1] << ", "
7897 << view_components_int[2] << ", " << view_components_int[3] << ")."
7898 << tcu::TestLog::EndMessage;
7903 case SAMPLER_TYPE_UNSIGNED_INTEGER:
7906 << tcu::TestLog::Message << "Invalid data sampled from an unsigned integer texture view "
7908 << view_internalformat_string << "]"
7909 " created from a texture object"
7911 << texture_internalformat_string << "]"
7914 << (n_texel % m_texture_width) << ", " << (n_texel / m_texture_height) << "): expected:("
7915 << reference_components_uint[0] << ", " << reference_components_uint[1] << ", "
7916 << reference_components_uint[2] << ", " << reference_components_uint[3] << ") found:("
7917 << view_components_uint[0] << ", " << view_components_uint[1] << ", "
7918 << view_components_uint[2] << ", " << view_components_uint[3] << ")."
7919 << tcu::TestLog::EndMessage;
7925 TCU_FAIL("Unrecognized sampler type");
7926 } /* switch (view_sampler_type) */
7929 } /* if (has_failed) */
7930 } /* for (all components) */
7931 } /* for (all texels) */
7932 } /* if (memcmp(texture_data_ptr, view_data_ptr, m_view_data_offset) != 0) */
7936 /* Log detailed information about the failure */
7937 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data read from a view of internalformat "
7938 << "[" << view_internalformat_string << "]"
7939 << " created from a texture of internalformat "
7940 << "[" << texture_internalformat_string << "]"
7941 << ". Byte streams follow:" << tcu::TestLog::EndMessage;
7943 /* Form texture and view data strings */
7944 std::stringstream mipmap_data_sstream;
7945 std::stringstream sampled_view_data_sstream;
7947 mipmap_data_sstream.fill('0');
7948 sampled_view_data_sstream.fill('0');
7950 mipmap_data_sstream.width(2);
7951 sampled_view_data_sstream.width(2);
7953 mipmap_data_sstream << "Mip-map data: [";
7954 sampled_view_data_sstream << "Sampled view data: [";
7956 for (unsigned int n = 0; n < m_view_data_offset; ++n)
7958 mipmap_data_sstream << "0x" << std::hex << (int)(mipmap_data[n]);
7959 sampled_view_data_sstream << "0x" << std::hex << (int)(view_data_ptr[n]);
7961 if (n != (m_view_data_offset - 1))
7963 mipmap_data_sstream << "|";
7964 sampled_view_data_sstream << "|";
7968 mipmap_data_sstream << "]";
7969 sampled_view_data_sstream << "]";
7973 sampled_view_data_sstream << "\n";
7974 mipmap_data_sstream << "\n";
7976 /* Log both strings */
7977 m_testCtx.getLog() << tcu::TestLog::Message << mipmap_data_sstream.str() << sampled_view_data_sstream.str()
7978 << tcu::TestLog::EndMessage;
7980 /* Do not fail the test at this point. Instead, raise a failure flag that will
7981 * cause the test to fail once all iterations execute */
7982 m_has_test_failed = true;
7986 m_testCtx.getLog() << tcu::TestLog::Message << "Correct data read from a view of internalformat "
7987 << "[" << view_internalformat_string << "]"
7988 << " created from a texture of internalformat "
7989 << "[" << texture_internalformat_string << "]" << tcu::TestLog::EndMessage;
7995 * @param context Rendering context.
7998 TextureViewTestCoherency::TextureViewTestCoherency(deqp::Context& context)
7999 : TestCase(context, "coherency", "Verifies view/parent texture coherency")
8000 , m_are_images_supported(false)
8003 , m_gradient_verification_po_id(0)
8004 , m_gradient_verification_po_sample_exact_uv_location(-1)
8005 , m_gradient_verification_po_lod_location(-1)
8006 , m_gradient_verification_po_texture_location(-1)
8007 , m_gradient_verification_vs_id(0)
8008 , m_gradient_image_write_image_size_location(-1)
8009 , m_gradient_image_write_po_id(0)
8010 , m_gradient_image_write_vs_id(0)
8011 , m_gradient_write_po_id(0)
8012 , m_gradient_write_fs_id(0)
8013 , m_gradient_write_vs_id(0)
8019 , m_verification_po_expected_color_location(-1)
8020 , m_verification_po_lod_location(-1)
8021 , m_verification_po_id(0)
8022 , m_verification_vs_id(0)
8023 , m_static_texture_height(1)
8024 , m_static_texture_width(1)
8025 , m_texture_height(64)
8026 , m_texture_n_components(4)
8027 , m_texture_n_levels(7)
8028 , m_texture_width(64)
8030 /* Initialize static color that will be used for some of the cases */
8031 m_static_color_byte[0] = 100;
8032 m_static_color_byte[1] = 0;
8033 m_static_color_byte[2] = 255;
8034 m_static_color_byte[3] = 200;
8036 m_static_color_float[0] = float(m_static_color_byte[0]) / 255.0f;
8037 m_static_color_float[1] = float(m_static_color_byte[1]) / 255.0f;
8038 m_static_color_float[2] = float(m_static_color_byte[2]) / 255.0f;
8039 m_static_color_float[3] = float(m_static_color_byte[3]) / 255.0f;
8042 /** Verifies that texture/view & view/texture coherency requirement is met
8043 * when glTexSubImage2D() or glBlitFramebuffer() API calls are used to modify
8044 * the contents of one of the mip-maps. The function does not use any memory
8045 * barriers as these are not required for the objects to stay synchronised.
8047 * Throws TestError exceptionif the GL implementation fails the check.
8049 * @param texture_type Defines whether it should be parent texture or
8050 * its view that the writing operation should be
8051 * performed against. The reading operation will
8052 * be issued against the sibling object.
8053 * @param should_use_glTexSubImage2D true if glTexSubImage2D() should be used for the
8054 * check, false to use glBlitFramebuffer().
8057 void TextureViewTestCoherency::checkAPICallCoherency(_texture_type texture_type, bool should_use_glTexSubImage2D)
8059 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8060 unsigned int write_to_height = 0;
8061 unsigned int write_to_width = 0;
8062 glw::GLuint write_to_id = 0;
8064 getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height);
8066 if (should_use_glTexSubImage2D)
8068 /* Update texture binding for texture unit 0, given the texture type the caller wants
8069 * us to test. We'll need the binding set appropriately for the subsequent
8070 * glTexSubImage2D() call.
8072 gl.activeTexture(GL_TEXTURE0);
8073 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
8075 gl.bindTexture(GL_TEXTURE_2D, write_to_id);
8076 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
8080 /* To perform a blit operation, we need to configure draw & read FBO, taking
8081 * the tested texture type into account. */
8082 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_draw_fbo_id);
8083 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id);
8084 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call(s) failed.");
8086 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */
8087 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_DRAW_FRAMEBUFFER target.");
8089 gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_static_to_id,
8091 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed for GL_READ_FRAMEBUFFER target.");
8094 /* Execute the API call */
8095 const unsigned int region_width = (write_to_width >> 1);
8096 const unsigned int region_height = (write_to_height >> 1);
8097 const unsigned int region_x = region_width - (region_width >> 1);
8098 const unsigned int region_y = region_height - (region_height >> 1);
8100 if (should_use_glTexSubImage2D)
8102 /* Call glTexSubImage2D() to replace a portion of the gradient with a static color */
8104 unsigned char* static_color_data_ptr = getStaticColorTextureData(region_width, region_height);
8106 gl.texSubImage2D(GL_TEXTURE_2D, 1, /* level */
8107 region_x, region_y, region_width, region_height, GL_RGBA, GL_UNSIGNED_BYTE,
8108 static_color_data_ptr);
8110 /* Good to release static color data buffer at this point */
8111 delete[] static_color_data_ptr;
8113 static_color_data_ptr = DE_NULL;
8115 /* Make sure the API call was successful */
8116 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
8121 gl.blitFramebuffer(0, /* srcX0 */
8123 m_static_texture_width, /* srcX1 */
8124 m_static_texture_height, /* srcY1 */
8125 region_x, region_y, region_x + region_width, region_y + region_height, GL_COLOR_BUFFER_BIT,
8127 GLU_EXPECT_NO_ERROR(gl.getError(), "glBlitFramebuffer() call failed.");
8130 /* Bind the sibling object so that we can make sure the data read from the
8131 * region can be correctly read from a shader without a memory barrier.
8133 * While we're here, also determine which LOD we should be sampling from in
8136 unsigned int read_lod = 0;
8137 glw::GLuint read_to_id = 0;
8139 getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod);
8141 gl.bindTexture(GL_TEXTURE_2D, read_to_id);
8142 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
8144 /* Update the test program uniforms before we carry on with actual
8147 gl.useProgram(m_verification_po_id);
8148 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
8150 DE_STATIC_ASSERT(sizeof(m_static_color_float) == sizeof(float) * 4);
8152 gl.uniform4fv(m_verification_po_expected_color_location, 1, /* count */
8153 m_static_color_float);
8154 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4fv() call failed.");
8156 gl.uniform1i(m_verification_po_lod_location, read_lod);
8157 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
8159 /* Make sure rasterization is disabled before we carry on */
8160 gl.enable(GL_RASTERIZER_DISCARD);
8161 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed.");
8163 /* Go ahead with the rendering. Make sure to capture the varyings */
8164 gl.beginTransformFeedback(GL_POINTS);
8165 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
8167 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
8168 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
8170 gl.endTransformFeedback();
8171 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
8173 /* Map the buffer object so we can validate the sampling result */
8174 const glw::GLint* data_ptr = (const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
8176 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
8177 DE_ASSERT(data_ptr != NULL);
8179 /* Verify the outcome of the sampling operation */
8182 TCU_FAIL("Invalid data was sampled in vertex shader");
8185 /* Unmap the buffer object */
8186 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
8187 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
8191 /* Disable GL_RASTERIZER_DISCARD mode */
8192 gl.disable(GL_RASTERIZER_DISCARD);
8193 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed.");
8196 /** Verifies texture/view & view/texture coherency is met when one of the objects
8197 * is used as a render-target. The function writes to user-specified texture type,
8198 * and then verifies the contents of the sibling object.
8200 * The function throws TestError exception if any of the checks fail.
8202 * @param texture_type Tells which of the two objects should be written to.
8203 * @param should_use_images true if images should be used for
8204 * @param barrier_type Type of the memory barrier that should be injected
8205 * after vertex shader stage with image writes is executed.
8206 * Must be BARRIER_TYPE_NONE if @param should_use_images
8208 * @param verification_mean Determines whether the verification should be performed
8209 * using a program object, or by CPU with the data
8210 * extracted from the sibling object using a glGetTexImage()
8214 void TextureViewTestCoherency::checkProgramWriteCoherency(_texture_type texture_type, bool should_use_images,
8215 _barrier_type barrier_type,
8216 _verification_mean verification_mean)
8218 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8220 if (!should_use_images)
8222 /* Sanity check: no barrier should be requested if images are not used */
8223 DE_ASSERT(barrier_type == BARRIER_TYPE_NONE);
8225 /* Sanity check: glGetTexImage*() call should only be used for verification
8226 * when images are used */
8227 DE_ASSERT(verification_mean == VERIFICATION_MEAN_PROGRAM);
8230 /* Determine GL id of an object we will be rendering the gradient to */
8231 glw::GLuint write_to_id = 0;
8232 unsigned int write_to_width = 0;
8233 unsigned int write_to_height = 0;
8235 getWritePropertiesForTextureType(texture_type, &write_to_id, &write_to_width, &write_to_height);
8237 /* Configure the render targets */
8238 if (should_use_images)
8240 gl.bindImageTexture(0, /* unit */
8241 write_to_id, 1, /* second level */
8242 GL_FALSE, /* layered */
8244 GL_WRITE_ONLY, GL_RGBA8);
8246 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
8250 /* We first need to fill either the texture or its sibling view with
8251 * gradient data. Set up draw framebuffer */
8252 gl.bindFramebuffer(GL_FRAMEBUFFER, m_draw_fbo_id);
8253 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed for GL_FRAMEBUFFER target");
8255 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, write_to_id, 1); /* level */
8256 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
8258 /* Configure the viewport accordingly */
8259 gl.viewport(0, /* x */
8261 write_to_width, write_to_height);
8262 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
8265 /* The gradient needs to be rendered differently, depending on whether
8266 * we're asked to use images or not */
8267 if (should_use_images)
8269 gl.useProgram(m_gradient_image_write_po_id);
8270 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
8272 gl.uniform2i(m_gradient_image_write_image_size_location, write_to_width, write_to_height);
8273 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform2i() call failed.");
8275 gl.enable(GL_RASTERIZER_DISCARD);
8276 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
8278 gl.drawArrays(GL_POINTS, 0 /* first */, write_to_width * write_to_height);
8279 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
8281 gl.disable(GL_RASTERIZER_DISCARD);
8282 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed.");
8284 /* If the caller requested any barriers, issue them at this point */
8285 switch (barrier_type)
8287 case BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT:
8289 gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
8291 GLU_EXPECT_NO_ERROR(gl.getError(),
8292 "glMemoryBarrier() call failed for GL_TEXTURE_FETCH_BARRIER_BIT barrier");
8297 case BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT:
8299 gl.memoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
8301 GLU_EXPECT_NO_ERROR(gl.getError(),
8302 "glMemoryBarrier() call failed for GL_TEXTURE_UPDATE_BARRIER_BIT barrier");
8309 TCU_FAIL("Unrecognized barrier type");
8311 } /* switch (barrier_type) */
8312 } /* if (should_use_images) */
8315 /* Render the gradient on a full-screen quad */
8316 gl.useProgram(m_gradient_write_po_id);
8317 GLU_EXPECT_NO_ERROR(gl.getError(), "gluseProgram() call failed.");
8319 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
8320 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
8323 /* Determine which texture and which mip-map level we will need to sample
8324 * in order to verify whether the former operations have been completed
8327 unsigned int read_lod = 0;
8328 glw::GLuint read_to_id = 0;
8330 getReadPropertiesForTextureType(texture_type, &read_to_id, &read_lod);
8332 /* Before we proceed with verification, update the texture binding so that
8333 * the verification program can sample from the right texture */
8334 gl.activeTexture(GL_TEXTURE0);
8335 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
8337 gl.bindTexture(GL_TEXTURE_2D, read_to_id);
8338 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
8340 if (verification_mean == VERIFICATION_MEAN_PROGRAM)
8342 /* Switch to a verification program. It uses a vertex shader to sample
8343 * all texels of the texture so issue as many invocations as necessary. */
8344 unsigned int n_invocations = write_to_width * write_to_height;
8346 gl.useProgram(m_gradient_verification_po_id);
8347 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
8349 gl.uniform1i(m_gradient_verification_po_texture_location, 0);
8350 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
8352 gl.uniform1i(m_gradient_verification_po_sample_exact_uv_location, should_use_images);
8353 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
8355 gl.uniform1f(m_gradient_verification_po_lod_location, (float)read_lod);
8356 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() call failed.");
8358 gl.enable(GL_RASTERIZER_DISCARD);
8359 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
8361 gl.beginTransformFeedback(GL_POINTS);
8362 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
8364 gl.drawArrays(GL_POINTS, 0 /* first */, n_invocations);
8365 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
8367 gl.endTransformFeedback();
8368 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
8370 gl.disable(GL_RASTERIZER_DISCARD);
8371 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_RASTERIZER_DISCARD) call failed.");
8373 /* Map the result buffer object storage into process space */
8374 const int* result_data_ptr = (const int*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
8376 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
8378 if (result_data_ptr == DE_NULL)
8380 TCU_FAIL("glMapBuffer() did not generate an error but returned a NULL pointer");
8383 /* Verify the XFBed data */
8384 for (unsigned int n_invocation = 0; n_invocation < n_invocations; ++n_invocation)
8386 if (result_data_ptr[n_invocation] != 1)
8388 unsigned int invocation_x = n_invocation % write_to_width;
8389 unsigned int invocation_y = n_invocation / write_to_width;
8391 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled at "
8392 << "(" << invocation_x << ", " << invocation_y << ") when sampling from "
8393 << ((texture_type == TEXTURE_TYPE_PARENT_TEXTURE) ? "a texture" : "a view")
8394 << tcu::TestLog::EndMessage;
8396 /* Make sure the buffer is unmapped before throwing the exception */
8397 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
8399 TCU_FAIL("Invalid data sampled");
8401 } /* for (all invocations) */
8403 /* Unmap the buffer storage */
8404 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
8405 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
8406 } /* if (verification_mean == VERIFICATION_MEAN_PROGRAM) */
8409 DE_ASSERT(verification_mean == VERIFICATION_MEAN_GLGETTEXIMAGE);
8411 /* Allocate space for the data */
8412 unsigned char* data_ptr = new unsigned char[write_to_width * write_to_height * m_texture_n_components];
8414 /* Retrieve the rendered data */
8415 gl.getTexImage(GL_TEXTURE_2D, read_lod, GL_RGBA, GL_UNSIGNED_BYTE, data_ptr);
8417 if (gl.getError() != GL_NO_ERROR)
8419 /* Release the buffer before we throw an exception */
8422 TCU_FAIL("glGetTexImage() call failed.");
8425 /* Verify the data is correct */
8426 const int epsilon = 1;
8427 bool is_data_correct = true;
8429 for (unsigned int y = 0; y < write_to_height; ++y)
8431 const unsigned char* row_ptr = data_ptr + y * m_texture_n_components * write_to_width;
8433 for (unsigned int x = 0; x < write_to_width; ++x)
8435 const unsigned char* texel_ptr = row_ptr + x * m_texture_n_components;
8436 const float end_rgba[] = { 0.0f, 0.1f, 1.0f, 1.0f };
8437 const float lerp_factor = float(x) / float(write_to_width);
8438 const float start_rgba[] = { 1.0f, 0.9f, 0.0f, 0.0f };
8439 const float expected_data_float[] = { start_rgba[0] * (1.0f - lerp_factor) + end_rgba[0] * lerp_factor,
8440 start_rgba[1] * (1.0f - lerp_factor) + end_rgba[1] * lerp_factor,
8441 start_rgba[2] * (1.0f - lerp_factor) + end_rgba[2] * lerp_factor,
8442 start_rgba[3] * (1.0f - lerp_factor) +
8443 end_rgba[3] * lerp_factor };
8444 const unsigned char expected_data_ubyte[] = { (unsigned char)(expected_data_float[0] * 255.0f),
8445 (unsigned char)(expected_data_float[1] * 255.0f),
8446 (unsigned char)(expected_data_float[2] * 255.0f),
8447 (unsigned char)(expected_data_float[3] * 255.0f) };
8449 if (de::abs((int)texel_ptr[0] - (int)expected_data_ubyte[0]) > epsilon ||
8450 de::abs((int)texel_ptr[1] - (int)expected_data_ubyte[1]) > epsilon ||
8451 de::abs((int)texel_ptr[2] - (int)expected_data_ubyte[2]) > epsilon ||
8452 de::abs((int)texel_ptr[3] - (int)expected_data_ubyte[3]) > epsilon)
8454 is_data_correct = false;
8459 } /* for (all rows) */
8461 /* Good to release the data buffer at this point */
8466 /* Fail the test if any of the rendered texels were found invalid */
8467 if (!is_data_correct)
8469 TCU_FAIL("Invalid data sampled");
8474 /** Deinitializes all GL objects that may have been created during
8477 void TextureViewTestCoherency::deinit()
8479 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8481 /* Release any GL objects the test may have created */
8484 gl.deleteBuffers(1, &m_bo_id);
8489 if (m_draw_fbo_id != 0)
8491 gl.deleteFramebuffers(1, &m_draw_fbo_id);
8496 if (m_gradient_image_write_po_id != 0)
8498 gl.deleteProgram(m_gradient_image_write_po_id);
8500 m_gradient_image_write_po_id = 0;
8503 if (m_gradient_image_write_vs_id != 0)
8505 gl.deleteShader(m_gradient_image_write_vs_id);
8507 m_gradient_image_write_vs_id = 0;
8510 if (m_gradient_verification_po_id != 0)
8512 gl.deleteProgram(m_gradient_verification_po_id);
8514 m_gradient_verification_po_id = 0;
8517 if (m_gradient_verification_vs_id != 0)
8519 gl.deleteShader(m_gradient_verification_vs_id);
8521 m_gradient_verification_vs_id = 0;
8524 if (m_gradient_write_fs_id != 0)
8526 gl.deleteShader(m_gradient_write_fs_id);
8528 m_gradient_write_fs_id = 0;
8531 if (m_gradient_write_po_id != 0)
8533 gl.deleteProgram(m_gradient_write_po_id);
8535 m_gradient_write_po_id = 0;
8538 if (m_gradient_write_vs_id != 0)
8540 gl.deleteShader(m_gradient_write_vs_id);
8542 m_gradient_write_vs_id = 0;
8545 if (m_read_fbo_id != 0)
8547 gl.deleteFramebuffers(1, &m_read_fbo_id);
8552 if (m_static_to_id != 0)
8554 gl.deleteTextures(1, &m_static_to_id);
8561 gl.deleteTextures(1, &m_to_id);
8568 gl.deleteVertexArrays(1, &m_vao_id);
8573 if (m_view_to_id != 0)
8575 gl.deleteTextures(1, &m_view_to_id);
8580 if (m_verification_po_id != 0)
8582 gl.deleteProgram(m_verification_po_id);
8584 m_verification_po_id = 0;
8587 if (m_verification_vs_id != 0)
8589 gl.deleteShader(m_verification_vs_id);
8591 m_verification_vs_id = 0;
8594 /* Disable GL_RASTERIZER_DISCARD mode */
8595 gl.disable(GL_RASTERIZER_DISCARD);
8598 /** Allocates a sufficiently large buffer for RGBA8 data and fills it with
8599 * a horizontal gradient (as described in the test specification)
8601 * It is user's responsibility to release the buffer when no longer needed.
8603 * @return Pointer to the buffer.
8605 unsigned char* TextureViewTestCoherency::getHorizontalGradientData() const
8607 const float end_rgba[] = { 1.0f, 0.9f, 0.0f, 0.0f };
8608 unsigned char* result = new unsigned char[m_texture_width * m_texture_height * m_texture_n_components];
8609 const float start_rgba[] = { 0.0f, 0.1f, 1.0f, 1.0f };
8610 const unsigned int texel_size = m_texture_n_components;
8612 for (unsigned int y = 0; y < m_texture_height; ++y)
8614 unsigned char* row_data_ptr = result + texel_size * m_texture_width * y;
8616 for (unsigned int x = 0; x < m_texture_width; ++x)
8618 const float lerp_factor = float(x) / float(m_texture_width);
8619 unsigned char* pixel_data_ptr = row_data_ptr + texel_size * x;
8621 for (unsigned int n_component = 0; n_component < 4 /* rgba */; ++n_component)
8623 pixel_data_ptr[n_component] = (unsigned char)((end_rgba[n_component] * lerp_factor +
8624 start_rgba[n_component] * (1.0f - lerp_factor)) *
8626 } /* for (all components) */
8627 } /* for (all columns) */
8628 } /* for (all rows) */
8633 /** Retrieves properties of a sibling object that should be read from during
8634 * some of the checks.
8636 * @param texture_type Type of the texture object that should be used for reading.
8637 * @param out_to_id Deref will be used to store texture object ID of the object.
8638 * @param out_read_lod Deref will be used to store LOD to be used for reading from
8642 void TextureViewTestCoherency::getReadPropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id,
8643 unsigned int* out_read_lod) const
8645 switch (texture_type)
8647 case TEXTURE_TYPE_PARENT_TEXTURE:
8649 *out_to_id = m_view_to_id;
8651 /* We've modified LOD1 of parent texture which corresponds
8652 * to LOD 0 from the view's PoV
8659 case TEXTURE_TYPE_TEXTURE_VIEW:
8661 *out_to_id = m_to_id;
8663 /* We've modified LOD1 of the view texture which corresponds
8664 * to LOD2 from parent texture's PoV.
8673 TCU_FAIL("Unrecognized read source");
8675 } /* switch (texture_type) */
8678 /** Allocates a sufficiently large buffer to hold RGBA8 data of user-specified resolution
8679 * and fills it with a static color (as described in the test specification)
8681 * It is caller's responsibility to release the returned buffer when it's no longer
8684 * @param width Width of the mip-map the buffer will be used as a data source for;
8685 * @param height Height of the mip-map the buffer will be used as a data source for;
8687 * @return Pointer to the buffer.
8689 unsigned char* TextureViewTestCoherency::getStaticColorTextureData(unsigned int width, unsigned int height) const
8691 /* Prepare the data buffer storing the data we want to replace the region of the
8694 unsigned char* result_ptr = new unsigned char[width * height * m_texture_n_components];
8696 for (unsigned int y = 0; y < height; ++y)
8698 unsigned char* row_data_ptr = result_ptr + y * width * m_texture_n_components;
8700 for (unsigned int x = 0; x < width; ++x)
8702 unsigned char* pixel_data_ptr = row_data_ptr + x * m_texture_n_components;
8704 memcpy(pixel_data_ptr, m_static_color_byte, sizeof(m_static_color_byte));
8705 } /* for (all columns) */
8706 } /* for (all rows) */
8711 /** Retrieves properties of a parent texture object that should be written to during
8712 * some of the checks.
8714 * @param texture_type Type of the texture object that should be used for writing.
8715 * @param out_to_id Deref will be used to store texture object ID of the object. Must not be NULL.
8716 * @param out_width Deref will be used to store width of the mip-map the test will
8717 * be writing to; Must not be NULL.
8718 * @param out_height Deref will be used to store height of the mip-map the test will
8719 * be writing to. Must not be NULL.
8722 void TextureViewTestCoherency::getWritePropertiesForTextureType(_texture_type texture_type, glw::GLuint* out_to_id,
8723 unsigned int* out_width, unsigned int* out_height) const
8725 DE_ASSERT(out_to_id != DE_NULL);
8726 DE_ASSERT(out_width != DE_NULL);
8727 DE_ASSERT(out_height != DE_NULL);
8729 /* All tests will be attempting to modify layer 1 of either the texture
8730 * or its sibling view. For views, the resolution is therefore going to
8731 * be 16x16 (because the base resolution is 32x32, as the view uses a mipmap
8732 * range of 1 to 2 inclusive); for parent texture, this will be 32x32 (as the base
8735 switch (texture_type)
8737 case TEXTURE_TYPE_PARENT_TEXTURE:
8739 *out_to_id = m_to_id;
8740 *out_width = m_texture_width >> 1;
8741 *out_height = m_texture_height >> 1;
8746 case TEXTURE_TYPE_TEXTURE_VIEW:
8748 *out_to_id = m_view_to_id;
8749 *out_width = m_texture_width >> 2;
8750 *out_height = m_texture_height >> 2;
8757 TCU_FAIL("Unrecognized texture type");
8759 } /* switch (texture_type) */
8762 /** Initializes buffer objects that will be used during the test.
8764 * Throws exceptions if the initialization fails at any point.
8766 void TextureViewTestCoherency::initBufferObjects()
8768 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8770 /* Generate and configure buffer object storage */
8771 gl.genBuffers(1, &m_bo_id);
8772 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
8774 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
8775 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
8777 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
8778 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
8780 /* Case 1) needs the BO to hold just a single int.
8781 * Case 3) needs one int per result texel.
8783 * Allocate enough space to handle all the cases.
8785 glw::GLint bo_size = static_cast<glw::GLint>((m_texture_height >> 1) * (m_texture_width >> 1) * sizeof(int));
8787 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */
8789 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferdata() call failed.");
8792 /** Initializes framebuffer objects that will be used during the test.
8794 * Throws exceptions if the initialization fails at any point.
8796 void TextureViewTestCoherency::initFBO()
8798 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8800 /* Generate framebuffer object(s) */
8801 gl.genFramebuffers(1, &m_draw_fbo_id);
8802 gl.genFramebuffers(1, &m_read_fbo_id);
8803 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
8806 /** Initializes program objects that will be used during the test.
8808 * This method will throw exceptions if either compilation or linking of
8809 * any of the processed shaders/programs fails.
8812 void TextureViewTestCoherency::initPrograms()
8814 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8816 /* The test uses images in vertex shader stage. Make sure this is actually supported by
8817 * the implementation */
8818 m_are_images_supported = m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_image_load_store");
8820 if (m_are_images_supported)
8822 glw::GLint gl_max_vertex_image_uniforms_value = 0;
8824 gl.getIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &gl_max_vertex_image_uniforms_value);
8825 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_VERTEX_IMAGE_UNIFORM pname");
8827 if (gl_max_vertex_image_uniforms_value < 1)
8829 m_testCtx.getLog() << tcu::TestLog::Message
8830 << "Image support will not be tested by view_parent_texture_coherency, as"
8831 "the implementation does not support image uniforms in vertex shader stage."
8832 << tcu::TestLog::EndMessage;
8834 /* We cannot execute the test on this platform */
8835 m_are_images_supported = false;
8837 } /* if (m_are_images_supported) */
8839 /* Create program objects */
8840 if (m_are_images_supported)
8842 m_gradient_image_write_po_id = gl.createProgram();
8845 m_gradient_verification_po_id = gl.createProgram();
8846 m_gradient_write_po_id = gl.createProgram();
8847 m_verification_po_id = gl.createProgram();
8848 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
8850 /* Create fragment shader objects */
8851 m_gradient_write_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
8852 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed for GL_FRAGMENT_SHADER type");
8854 /* Create vertex shader objects */
8855 if (m_are_images_supported)
8857 m_gradient_image_write_vs_id = gl.createShader(GL_VERTEX_SHADER);
8860 m_gradient_verification_vs_id = gl.createShader(GL_VERTEX_SHADER);
8861 m_gradient_write_vs_id = gl.createShader(GL_VERTEX_SHADER);
8862 m_verification_vs_id = gl.createShader(GL_VERTEX_SHADER);
8863 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed for GL_VERTEX_SHADER type.");
8865 /* Set gradient verification program's fragment shader body */
8866 const char* gradient_verification_vs_body =
8871 "uniform float lod;\n"
8872 "uniform bool sample_exact_uv;\n"
8873 "uniform sampler2D texture;\n"
8877 " const float epsilon = 1.0 / 255.0;\n"
8878 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n"
8879 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n"
8881 " ivec2 texture_size = textureSize(texture, int(lod) );\n"
8882 " vec2 uv = vec2( float(gl_VertexID % texture_size.x) / float(texture_size.x),\n"
8883 " 1.0 - float(gl_VertexID / texture_size.x) / float(texture_size.y) );\n"
8884 " vec4 expected_color;\n"
8885 " vec4 texture_color = textureLod(texture, uv, lod);\n"
8887 " if (sample_exact_uv)\n"
8889 " expected_color = mix(start_rgba, end_rgba, uv.x);\n"
8893 " expected_color = mix(start_rgba, end_rgba, uv.x + 0.5/float(texture_size.x) );\n"
8897 " if (abs(texture_color.x - expected_color.x) > epsilon ||\n"
8898 " abs(texture_color.y - expected_color.y) > epsilon ||\n"
8899 " abs(texture_color.z - expected_color.z) > epsilon ||\n"
8900 " abs(texture_color.w - expected_color.w) > epsilon)\n"
8902 " result = int( texture_color.y * 255.0);\n"
8910 gl.shaderSource(m_gradient_verification_vs_id, 1 /* count */, &gradient_verification_vs_body, NULL /* length */);
8911 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
8913 /* Set gradient write (for images) program's vertex shader body */
8914 if (m_are_images_supported)
8916 const char* gradient_write_image_vs_body =
8919 "#extension GL_ARB_shader_image_load_store : require\n"
8921 "layout(rgba8) uniform image2D image;\n"
8922 " uniform ivec2 image_size;\n"
8926 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n"
8927 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n"
8928 " ivec2 xy = ivec2(gl_VertexID % image_size.x, gl_VertexID / image_size.x);\n"
8929 " vec2 uv = vec2(float(xy.x) / float(image_size.x), 1.0 - float(xy.y) / "
8930 "float(image_size.y) );\n"
8931 " vec4 result = mix (start_rgba, end_rgba, uv.x);\n"
8933 " imageStore(image, xy, result);\n"
8936 gl.shaderSource(m_gradient_image_write_vs_id, 1 /* count */, &gradient_write_image_vs_body, NULL /* length */);
8937 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
8940 /* Set gradient write program's fragment shader body */
8941 const char* gradient_write_fs_body = "#version 400\n"
8945 "layout(location = 0) out vec4 result;\n"
8949 " const vec4 end_rgba = vec4(0.0, 0.1, 1.0, 1.0);\n"
8950 " const vec4 start_rgba = vec4(1.0, 0.9, 0.0, 0.0);\n"
8952 " result = mix(start_rgba, end_rgba, uv.x);\n"
8955 gl.shaderSource(m_gradient_write_fs_id, 1 /* count */, &gradient_write_fs_body, NULL /* length */);
8956 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
8958 /* Set gradient write program's vertex shader body */
8959 const char* gradient_write_vs_body =
8966 " switch (gl_VertexID)\n"
8968 " case 0: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n"
8969 " case 1: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n"
8970 " case 2: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n"
8971 " case 3: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n"
8975 gl.shaderSource(m_gradient_write_vs_id, 1 /* count */, &gradient_write_vs_body, NULL /* length */);
8976 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
8978 /* Set verification program's vertex shader body */
8979 const char* verification_vs_body = "#version 400\n"
8981 "uniform vec4 expected_color;\n"
8982 "uniform int lod;\n"
8983 "uniform sampler2D sampler;\n"
8989 " const float epsilon = 1.0 / 256.0;\n"
8991 " vec4 sampled_data = textureLod(sampler, vec2(0.5, 0.5), lod);\n"
8993 " if (abs(sampled_data.x - expected_color.x) > epsilon ||\n"
8994 " abs(sampled_data.y - expected_color.y) > epsilon ||\n"
8995 " abs(sampled_data.z - expected_color.z) > epsilon ||\n"
8996 " abs(sampled_data.w - expected_color.w) > epsilon)\n"
9006 gl.shaderSource(m_verification_vs_id, 1 /* count */, &verification_vs_body, NULL /* length */);
9007 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
9009 /* Compile the shaders */
9010 const glw::GLuint so_ids[] = { m_gradient_image_write_vs_id, m_gradient_verification_vs_id, m_gradient_write_fs_id,
9011 m_gradient_write_vs_id, m_verification_vs_id };
9012 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
9014 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
9016 glw::GLuint so_id = so_ids[n_so_id];
9020 gl.compileShader(so_id);
9021 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
9023 /* Verify the compilation ended successfully */
9024 glw::GLint compile_status = GL_FALSE;
9026 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
9027 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
9029 if (compile_status != GL_TRUE)
9031 TCU_FAIL("Shader compilation failed.");
9034 } /* for (all shader objects) */
9036 /* Attach the shaders to relevant programs */
9037 if (m_are_images_supported)
9039 gl.attachShader(m_gradient_image_write_po_id, m_gradient_image_write_vs_id);
9042 gl.attachShader(m_gradient_verification_po_id, m_gradient_verification_vs_id);
9043 gl.attachShader(m_gradient_write_po_id, m_gradient_write_fs_id);
9044 gl.attachShader(m_gradient_write_po_id, m_gradient_write_vs_id);
9045 gl.attachShader(m_verification_po_id, m_verification_vs_id);
9046 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
9049 const char* verification_varying_name = "result";
9050 const glw::GLuint xfb_po_ids[] = {
9051 m_gradient_verification_po_id, m_verification_po_id,
9053 const unsigned int n_xfb_po_ids = sizeof(xfb_po_ids) / sizeof(xfb_po_ids[0]);
9055 for (unsigned int n_xfb_po_id = 0; n_xfb_po_id < n_xfb_po_ids; ++n_xfb_po_id)
9057 glw::GLint po_id = xfb_po_ids[n_xfb_po_id];
9059 gl.transformFeedbackVaryings(po_id, 1 /* count */, &verification_varying_name, GL_INTERLEAVED_ATTRIBS);
9060 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
9063 /* Link the programs */
9064 const glw::GLuint po_ids[] = { m_gradient_image_write_po_id, m_gradient_verification_po_id, m_gradient_write_po_id,
9065 m_verification_po_id };
9066 const unsigned int n_po_ids = sizeof(po_ids) / sizeof(po_ids[0]);
9068 for (unsigned int n_po_id = 0; n_po_id < n_po_ids; ++n_po_id)
9070 glw::GLuint po_id = po_ids[n_po_id];
9074 gl.linkProgram(po_id);
9075 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
9077 /* Make sure the linking was successful. */
9078 glw::GLint link_status = GL_FALSE;
9080 gl.getProgramiv(po_id, GL_LINK_STATUS, &link_status);
9081 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
9083 if (link_status != GL_TRUE)
9085 TCU_FAIL("Program linking failed.");
9088 } /* for (all program objects) */
9090 /* Retrieve uniform locations for gradient write program (image case) */
9091 if (m_are_images_supported)
9093 m_gradient_image_write_image_size_location = gl.getUniformLocation(m_gradient_image_write_po_id, "image_size");
9095 if (m_gradient_image_write_image_size_location == -1)
9097 TCU_FAIL("image_size is considered an inactive uniform which is invalid.");
9101 /* Retrieve uniform locations for gradient verification program */
9102 m_gradient_verification_po_sample_exact_uv_location =
9103 gl.getUniformLocation(m_gradient_verification_po_id, "sample_exact_uv");
9104 m_gradient_verification_po_lod_location = gl.getUniformLocation(m_gradient_verification_po_id, "lod");
9105 m_gradient_verification_po_texture_location = gl.getUniformLocation(m_gradient_verification_po_id, "texture");
9107 if (m_gradient_verification_po_sample_exact_uv_location == -1)
9109 TCU_FAIL("sample_exact_uv is considered an inactive uniform which is invalid");
9112 if (m_gradient_verification_po_lod_location == -1)
9114 TCU_FAIL("lod is considered an inactive uniform which is invalid.");
9117 if (m_gradient_verification_po_texture_location == -1)
9119 TCU_FAIL("texture is considered an inactive uniform which is invalid.");
9122 /* Retrieve uniform locations for verification program */
9123 m_verification_po_expected_color_location = gl.getUniformLocation(m_verification_po_id, "expected_color");
9124 m_verification_po_lod_location = gl.getUniformLocation(m_verification_po_id, "lod");
9126 if (m_verification_po_expected_color_location == -1)
9128 TCU_FAIL("expected_color is considered an inactive uniform which is invalid.");
9131 if (m_verification_po_lod_location == -1)
9133 TCU_FAIL("lod is considered an inactive uniform which is invalid.");
9137 /** Initializes texture objects required to run the test.
9139 * Throws exceptions if the initialization fails at any point.
9141 void TextureViewTestCoherency::initTextures()
9143 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9145 /* Generate the texture objects */
9146 gl.genTextures(1, &m_static_to_id);
9147 gl.genTextures(1, &m_to_id);
9148 gl.genTextures(1, &m_view_to_id);
9149 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed.");
9151 /* Set up parent texture object */
9152 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
9153 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
9155 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
9156 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
9158 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9159 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9160 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9161 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
9162 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call(s) failed.");
9164 /* Set up the texture views we'll be using for the test */
9165 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 1, /* minlevel */
9169 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
9171 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
9172 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9173 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9174 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9175 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
9177 /* Set up storage for static color texture */
9178 gl.bindTexture(GL_TEXTURE_2D, m_static_to_id);
9179 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
9181 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
9182 GL_RGBA8, m_static_texture_width, m_static_texture_height);
9183 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
9185 /* Fill the texture objects with actual contents */
9186 initTextureContents();
9189 /** Fills all relevant mip-maps of all previously initialized texture objects with
9192 * Throws an exception if any of the issued GL API calls fail.
9194 void TextureViewTestCoherency::initTextureContents()
9196 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9198 /* Make sure parent texture object is bound before we start modifying
9200 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
9201 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
9203 /* Set up parent texture mip-maps */
9204 unsigned char* base_mipmap_data_ptr = getHorizontalGradientData();
9206 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
9209 m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, base_mipmap_data_ptr);
9211 delete[] base_mipmap_data_ptr;
9212 base_mipmap_data_ptr = NULL;
9214 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
9216 /* Generate all mip-maps */
9217 gl.generateMipmap(GL_TEXTURE_2D);
9218 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed.");
9220 /* Set up static color texture contents. We only need to fill the base mip-map
9221 * since the texture's resolution is 1x1.
9223 DE_ASSERT(m_static_texture_height == 1 && m_static_texture_width == 1);
9225 unsigned char* static_texture_data_ptr = getStaticColorTextureData(m_static_texture_width, m_static_texture_height);
9227 gl.bindTexture(GL_TEXTURE_2D, m_static_to_id);
9228 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
9230 gl.texSubImage2D(GL_TEXTURE_2D, 0, /* level */
9233 m_static_texture_width, m_static_texture_height, GL_RGBA, GL_UNSIGNED_BYTE,
9234 static_texture_data_ptr);
9236 /* Good to release the buffer at this point */
9237 delete[] static_texture_data_ptr;
9239 static_texture_data_ptr = DE_NULL;
9241 /* Was the API call successful? */
9242 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
9245 /** Initializes a vertex array object used for the draw calls issued during the test. */
9246 void TextureViewTestCoherency::initVAO()
9248 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9250 /* Generate and bind a vertex array object */
9251 gl.genVertexArrays(1, &m_vao_id);
9252 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
9254 gl.bindVertexArray(m_vao_id);
9255 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
9258 /** Executes test iteration.
9260 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
9262 tcu::TestNode::IterateResult TextureViewTestCoherency::iterate()
9264 /* Do not execute the test if GL_ARB_texture_view is not supported */
9265 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
9267 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported.");
9270 /* Initialize all GL objects required to run the test */
9271 initBufferObjects();
9277 /* Iterate over the set of texture types we are to test */
9278 const _texture_type texture_types[] = { TEXTURE_TYPE_PARENT_TEXTURE, TEXTURE_TYPE_TEXTURE_VIEW };
9279 const unsigned int n_texture_types = sizeof(texture_types) / sizeof(texture_types[0]);
9281 for (unsigned int n_texture_type = 0; n_texture_type < n_texture_types; ++n_texture_type)
9283 _texture_type texture_type = texture_types[n_texture_type];
9285 /* Verify parent texture/view coherency when using glTexSubImage2D() */
9286 checkAPICallCoherency(texture_type, true);
9288 /* Verify parent texture/view coherency when using glBlitFramebuffer() */
9289 checkAPICallCoherency(texture_type, false);
9291 /* Verify parent texture/view coherency when modifying contents of one
9292 * of the objects in a program, and then reading the sibling from another
9295 checkProgramWriteCoherency(texture_type, false, /* should_use_images */
9296 BARRIER_TYPE_NONE, VERIFICATION_MEAN_PROGRAM);
9298 if (m_are_images_supported)
9300 /* Verify a view bound to an image unit and written to using image uniforms
9301 * in vertex shader stage can later be sampled correctly, assuming
9302 * a GL_TEXTURE_FETCH_BARRIER_BIT barrier is inserted between the write
9303 * operations and sampling from another program object.
9305 checkProgramWriteCoherency(texture_type, true, /* should_use_images */
9306 BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT, VERIFICATION_MEAN_PROGRAM);
9308 /* Verify a view bound to an image unit and written to using image uniforms
9309 * in vertex shader stage can later be correctly retrieved using a glGetTexImage()
9310 * call, assuming a GL_TEXTURE_UPDATE_BARRIER_BIT barrier is inserted between the
9313 checkProgramWriteCoherency(texture_type, true, /* should_use_images */
9314 BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT, VERIFICATION_MEAN_GLGETTEXIMAGE);
9317 /* Reinitialize all texture contents */
9318 initTextureContents();
9319 } /* for (all read sources) */
9321 /* Test case passed */
9322 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9329 * @param context Rendering context.
9332 TextureViewTestBaseAndMaxLevels::TextureViewTestBaseAndMaxLevels(deqp::Context& context)
9333 : TestCase(context, "base_and_max_levels", "test_description")
9334 , m_texture_height(256)
9335 , m_texture_n_components(4)
9336 , m_texture_n_levels(6)
9337 , m_texture_width(256)
9338 , m_view_height(128)
9340 , m_layer_data_lod0(DE_NULL)
9341 , m_layer_data_lod1(DE_NULL)
9345 , m_po_lod_index_uniform_location(-1)
9346 , m_po_to_sampler_uniform_location(-1)
9353 /* Left blank on purpose */
9356 /* Deinitializes all GL objects that may have been created during test execution. */
9357 void TextureViewTestBaseAndMaxLevels::deinit()
9359 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9363 gl.deleteFramebuffers(1, &m_fbo_id);
9370 gl.deleteShader(m_fs_id);
9375 if (m_layer_data_lod0 != DE_NULL)
9377 delete[] m_layer_data_lod0;
9379 m_layer_data_lod0 = DE_NULL;
9382 if (m_layer_data_lod1 != DE_NULL)
9384 delete[] m_layer_data_lod1;
9386 m_layer_data_lod1 = DE_NULL;
9391 gl.deleteProgram(m_po_id);
9396 if (m_result_to_id != 0)
9398 gl.deleteTextures(1, &m_result_to_id);
9405 gl.deleteTextures(1, &m_to_id);
9412 gl.deleteVertexArrays(1, &m_vao_id);
9417 if (m_view_to_id != 0)
9419 gl.deleteTextures(1, &m_view_to_id);
9426 gl.deleteShader(m_vs_id);
9432 /* Initializes and configures a program object used later by the test. */
9433 void TextureViewTestBaseAndMaxLevels::initProgram()
9435 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9437 /* Generate shader object IDs */
9438 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
9439 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
9441 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed");
9443 /* Generate program object ID */
9444 m_po_id = gl.createProgram();
9446 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
9448 /* Set up vertex shader body */
9449 static const char* vs_body =
9456 " switch (gl_VertexID)\n"
9458 " case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); uv = vec2(0.0, 1.0); break;\n"
9459 " case 1: gl_Position = vec4(-1.0, -1.0, 0.0, 1.0); uv = vec2(0.0, 0.0); break;\n"
9460 " case 2: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); uv = vec2(1.0, 1.0); break;\n"
9461 " case 3: gl_Position = vec4( 1.0, -1.0, 0.0, 1.0); uv = vec2(1.0, 0.0); break;\n"
9465 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
9466 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for vertex shader case");
9468 /* Set up fragment shader body */
9469 static const char* fs_body = "#version 400\n"
9473 "uniform int lod_index;\n"
9474 "uniform sampler2D to_sampler;\n"
9476 "out vec4 result;\n"
9480 " result = textureLod(to_sampler, uv, float(lod_index) );\n"
9483 gl.shaderSource(m_fs_id, 1 /* count */, &fs_body, DE_NULL /* length */);
9484 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed for fragment shader case");
9486 /* Compile both shaders */
9487 const glw::GLuint so_ids[] = { m_fs_id, m_vs_id };
9488 const unsigned int n_so_ids = sizeof(so_ids) / sizeof(so_ids[0]);
9490 for (unsigned int n_so_id = 0; n_so_id < n_so_ids; ++n_so_id)
9492 glw::GLint so_id = so_ids[n_so_id];
9494 gl.compileShader(so_id);
9495 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
9497 /* Make sure the compilation has succeeded */
9498 glw::GLint compile_status = GL_FALSE;
9500 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
9501 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
9503 if (compile_status != GL_TRUE)
9505 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage;
9507 } /* for (all shader objects) */
9509 /* Attach the shaders to the program object */
9510 gl.attachShader(m_po_id, m_fs_id);
9511 gl.attachShader(m_po_id, m_vs_id);
9512 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed");
9514 /* Link the program object */
9515 gl.linkProgram(m_po_id);
9516 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call faikled");
9518 /* Verify the linking has succeeded */
9519 glw::GLint link_status = GL_FALSE;
9521 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
9522 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed for GL_LINK_STATUS pname");
9524 if (link_status != GL_TRUE)
9526 TCU_FAIL("Program linking failed");
9529 /* Retrieve uniform locations */
9530 m_po_lod_index_uniform_location = gl.getUniformLocation(m_po_id, "lod_index");
9531 m_po_to_sampler_uniform_location = gl.getUniformLocation(m_po_id, "to_sampler");
9533 if (m_po_lod_index_uniform_location == -1)
9535 TCU_FAIL("lod_index is considered an inactive uniform");
9538 if (m_po_to_sampler_uniform_location == -1)
9540 TCU_FAIL("to_sampler is considered an inactive uniform");
9544 /* Initializes all GL objects used by the test. */
9545 void TextureViewTestBaseAndMaxLevels::initTest()
9547 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9549 /* Initialize textures */
9552 /* Initialize framebuffer and configure its attachments */
9553 gl.genFramebuffers(1, &m_fbo_id);
9554 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed");
9556 /* Build the program we'll need for the test */
9559 /* Generate a vertex array object to execute the draw calls */
9560 gl.genVertexArrays(1, &m_vao_id);
9561 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
9563 gl.bindVertexArray(m_vao_id);
9564 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
9566 /* Finally, allocate space for buffers that will be filled with rendered data */
9567 m_layer_data_lod0 = new unsigned char[m_texture_width * m_texture_height * m_texture_n_components];
9568 m_layer_data_lod1 = new unsigned char[(m_texture_width >> 1) * (m_texture_height >> 1) * m_texture_n_components];
9570 if (m_layer_data_lod0 == DE_NULL || m_layer_data_lod1 == DE_NULL)
9572 TCU_FAIL("Out of memory");
9576 /** Initializes texture objects used by the test. */
9577 void TextureViewTestBaseAndMaxLevels::initTextures()
9579 /* Generate IDs first */
9580 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9582 gl.genTextures(1, &m_result_to_id);
9583 gl.genTextures(1, &m_to_id);
9584 gl.genTextures(1, &m_view_to_id);
9585 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
9587 /* Set up parent texture object's storage */
9588 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
9589 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
9591 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
9592 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
9594 /* Configure GL_TEXTURE_BASE_LEVEL parameter of the texture object as per test spec */
9595 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
9596 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname");
9598 /* Configure GL_TEXTURE_MAX_LEVEL parameter of the texture object as per test spec */
9599 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);
9600 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname");
9602 /* Set up mip-maps */
9603 for (unsigned int n_mipmap = 0; n_mipmap < m_texture_n_levels; ++n_mipmap)
9605 const float start_rgba[] = { /* As per test specification */
9606 float(n_mipmap + 0) / 10.0f, float(n_mipmap + 1) / 10.0f,
9607 float(n_mipmap + 2) / 10.0f, float(n_mipmap + 3) / 10.0f
9609 const float end_rgba[] = { float(10 - (n_mipmap + 0)) / 10.0f, float(10 - (n_mipmap + 1)) / 10.0f,
9610 float(10 - (n_mipmap + 2)) / 10.0f, float(10 - (n_mipmap + 3)) / 10.0f };
9612 /* Allocate space for the layer data */
9613 const unsigned int mipmap_height = m_texture_height >> n_mipmap;
9614 const unsigned int mipmap_width = m_texture_width >> n_mipmap;
9615 unsigned char* data = new unsigned char[mipmap_width * mipmap_height * m_texture_n_components];
9619 TCU_FAIL("Out of memory");
9622 /* Fill the buffer with layer data */
9623 const unsigned int pixel_size = 4 /* components */;
9625 for (unsigned int y = 0; y < mipmap_height; ++y)
9627 unsigned char* row_data_ptr = data + mipmap_width * y * pixel_size;
9629 for (unsigned int x = 0; x < mipmap_width; ++x)
9631 const float lerp_factor = float(x) / float(mipmap_width);
9632 unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size;
9634 for (unsigned int n_component = 0; n_component < m_texture_n_components; n_component++)
9636 pixel_data_ptr[n_component] = (unsigned char)((start_rgba[n_component] * lerp_factor +
9637 end_rgba[n_component] * (1.0f - lerp_factor)) *
9640 } /* for (all columns) */
9641 } /* for (all rows) */
9643 /* Upload the layer data */
9644 gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */
9646 mipmap_width, mipmap_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
9648 /* Release the data buffer */
9653 /* Make sure the API call finished successfully */
9654 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed");
9655 } /* for (all mip-maps) */
9657 /* Configure the texture view storage as per spec. */
9658 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_to_id, GL_RGBA8, 0, /* minlevel */
9662 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
9664 /* Configure the texture view's GL_TEXTURE_BASE_LEVEL parameter */
9665 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
9666 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
9668 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
9669 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_BASE_LEVEL pname");
9671 /* Configure the texture view's GL_TEXTURE_MAX_LEVEL parameter */
9672 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2);
9673 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() call failed for GL_TEXTURE_MAX_LEVEL pname");
9675 /* Set up result texture storage */
9676 gl.bindTexture(GL_TEXTURE_2D, m_result_to_id);
9677 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
9679 gl.texStorage2D(GL_TEXTURE_2D, 1, /* We will only attach the first level of the result texture to the FBO */
9680 GL_RGBA8, m_view_width, m_view_height);
9681 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
9684 /** Executes test iteration.
9686 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
9688 tcu::TestNode::IterateResult TextureViewTestBaseAndMaxLevels::iterate()
9690 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9692 /* Only execute if GL_ARB_texture_view extension is supported */
9693 const std::vector<std::string>& extensions = m_context.getContextInfo().getExtensions();
9695 if (std::find(extensions.begin(), extensions.end(), "GL_ARB_texture_view") == extensions.end())
9697 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
9700 /* Initialize all GL objects necessary to run the test */
9703 /* Activate test-wide program object */
9704 gl.useProgram(m_po_id);
9705 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
9707 /* Bind the data texture */
9708 gl.activeTexture(GL_TEXTURE0);
9709 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed");
9711 gl.bindTexture(GL_TEXTURE_2D, m_view_to_id);
9712 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
9714 /* We will now use the program to sample the view's LOD 0 and LOD 1 and store
9715 * it in two separate textures.
9717 for (unsigned int lod_level = 0; lod_level < 2; /* as per test spec */
9720 /* Set up FBO attachments */
9721 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
9722 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed");
9724 gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_result_to_id,
9726 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed");
9728 /* Update viewport configuration */
9729 gl.viewport(0, /* x */
9731 m_view_width >> lod_level, m_view_height >> lod_level);
9733 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed");
9735 /* Configure program object uniforms before we continue */
9736 gl.uniform1i(m_po_lod_index_uniform_location, lod_level);
9737 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
9739 /* Render a triangle strip. The program we're using will output a full-screen
9740 * quad with the sampled data */
9741 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
9742 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
9744 /* At the time of the draw call, we've modified the draw/read framebuffer binding
9745 * so that everything we render ends up in result texture. It's time to read it */
9746 glw::GLvoid* result_data_ptr = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1;
9748 gl.readPixels(0, /* x */
9750 m_view_width >> lod_level, m_view_height >> lod_level, GL_RGBA, GL_UNSIGNED_BYTE,
9753 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed");
9754 } /* for (both LODs) */
9756 /* Now that we have both pieces of data, we can proceed with actual verification */
9757 for (unsigned int lod_level = 0; lod_level < 2; ++lod_level)
9759 /* NOTE: This code is a modification of initialization routine
9760 * found in initTextures()
9762 const unsigned char epsilon = 1;
9763 const glw::GLvoid* layer_data_ptr = (lod_level == 0) ? m_layer_data_lod0 : m_layer_data_lod1;
9764 const unsigned int layer_height = m_view_height >> lod_level;
9765 const unsigned int layer_width = m_view_width >> lod_level;
9766 const unsigned int pixel_size = 4 /* components */;
9767 const unsigned int view_minimum_level = 1; /* THS SHOULD BE 1 */
9768 const float start_rgba[] = {
9769 /* As per test specification */
9770 float(lod_level + view_minimum_level + 0) / 10.0f, float(lod_level + view_minimum_level + 1) / 10.0f,
9771 float(lod_level + view_minimum_level + 2) / 10.0f, float(lod_level + view_minimum_level + 3) / 10.0f
9773 const float end_rgba[] = { float(10 - (lod_level + view_minimum_level + 0)) / 10.0f,
9774 float(10 - (lod_level + view_minimum_level + 1)) / 10.0f,
9775 float(10 - (lod_level + view_minimum_level + 2)) / 10.0f,
9776 float(10 - (lod_level + view_minimum_level + 3)) / 10.0f };
9778 for (unsigned int y = 0; y < layer_height; ++y)
9780 const unsigned char* row_data_ptr = (const unsigned char*)layer_data_ptr + layer_width * y * pixel_size;
9782 for (unsigned int x = 0; x < layer_width; ++x)
9784 const float lerp_factor = float(x) / float(layer_width);
9785 const unsigned char* pixel_data_ptr = row_data_ptr + x * pixel_size;
9787 const unsigned char expected_data[] = {
9788 (unsigned char)((start_rgba[0] * lerp_factor + end_rgba[0] * (1.0f - lerp_factor)) * 255.0f),
9789 (unsigned char)((start_rgba[1] * lerp_factor + end_rgba[1] * (1.0f - lerp_factor)) * 255.0f),
9790 (unsigned char)((start_rgba[2] * lerp_factor + end_rgba[2] * (1.0f - lerp_factor)) * 255.0f),
9791 (unsigned char)((start_rgba[3] * lerp_factor + end_rgba[3] * (1.0f - lerp_factor)) * 255.0f)
9794 if (de::abs(expected_data[0] - pixel_data_ptr[0]) > epsilon ||
9795 de::abs(expected_data[1] - pixel_data_ptr[1]) > epsilon ||
9796 de::abs(expected_data[2] - pixel_data_ptr[2]) > epsilon ||
9797 de::abs(expected_data[3] - pixel_data_ptr[3]) > epsilon)
9799 m_testCtx.getLog() << tcu::TestLog::Message << "Found an invalid texel at (" << x << ", " << y
9803 << expected_data[0] << ", " << expected_data[1] << ", " << expected_data[2]
9804 << ", " << expected_data[3] << ")"
9807 << pixel_data_ptr[0] << ", " << pixel_data_ptr[1] << ", " << pixel_data_ptr[2]
9808 << ", " << pixel_data_ptr[3] << ")" << tcu::TestLog::EndMessage;
9810 TCU_FAIL("Rendered data does not match expected pixel data");
9811 } /* if (pixel mismatch found) */
9812 } /* for (all columns) */
9813 } /* for (all rows) */
9814 } /* for (both LODs) */
9816 /* Test case passed */
9817 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9824 * @param context Rendering context.
9826 TextureViewTestReferenceCounting::TextureViewTestReferenceCounting(deqp::Context& context)
9827 : TestCase(context, "reference_counting",
9828 "Makes sure that sampling from views, for which the parent texture object "
9829 "has already been deleted, works correctly.")
9833 , m_po_expected_texel_uniform_location(-1)
9834 , m_po_lod_uniform_location(-1)
9837 , m_view_view_to_id(0)
9839 , m_texture_height(64)
9840 , m_texture_n_levels(7)
9841 , m_texture_width(64)
9843 /* Configure a vector storing unique colors that should be used
9844 * for filling subsequent mip-maps of parent texture */
9845 m_mipmap_colors.push_back(_norm_vec4(123, 34, 56, 78));
9846 m_mipmap_colors.push_back(_norm_vec4(234, 45, 67, 89));
9847 m_mipmap_colors.push_back(_norm_vec4(34, 56, 78, 90));
9848 m_mipmap_colors.push_back(_norm_vec4(45, 67, 89, 1));
9849 m_mipmap_colors.push_back(_norm_vec4(56, 78, 90, 123));
9850 m_mipmap_colors.push_back(_norm_vec4(67, 89, 1, 234));
9851 m_mipmap_colors.push_back(_norm_vec4(78, 90, 12, 34));
9853 DE_ASSERT(m_mipmap_colors.size() == m_texture_n_levels);
9856 /** Deinitializes all GL objects that may have been created during test
9859 void TextureViewTestReferenceCounting::deinit()
9861 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9865 gl.deleteBuffers(1, &m_bo_id);
9870 if (m_parent_to_id != 0)
9872 gl.deleteTextures(1, &m_parent_to_id);
9879 gl.deleteProgram(m_po_id);
9886 gl.deleteVertexArrays(1, &m_vao_id);
9891 if (m_view_to_id != 0)
9893 gl.deleteTextures(1, &m_view_to_id);
9898 if (m_view_view_to_id != 0)
9900 gl.deleteTextures(1, &m_view_view_to_id);
9902 m_view_view_to_id = 0;
9907 gl.deleteShader(m_vs_id);
9913 /* Initializes a program object to be used during the test. */
9914 void TextureViewTestReferenceCounting::initProgram()
9916 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9918 /* Create program & shader object IDs */
9919 m_po_id = gl.createProgram();
9920 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed");
9922 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
9923 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed");
9925 /* Set vertex shader body */
9926 const char* vs_body = "#version 400\n"
9928 "uniform vec4 expected_texel;\n"
9929 "uniform int lod;\n"
9930 "uniform sampler2D sampler;\n"
9932 "out int has_passed;\n"
9936 " vec4 data = textureLod(sampler, vec2(0.5, 0.5), lod);\n"
9937 " const float epsilon = 1.0 / 256.0;\n"
9939 " if (abs(data.r - expected_texel.r) > epsilon ||\n"
9940 " abs(data.g - expected_texel.g) > epsilon ||\n"
9941 " abs(data.b - expected_texel.b) > epsilon ||\n"
9942 " abs(data.a - expected_texel.a) > epsilon)\n"
9944 " has_passed = 0;\n"
9948 " has_passed = 1;\n"
9952 gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, NULL /* length */);
9953 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed");
9956 const char* varying_name = "has_passed";
9958 gl.transformFeedbackVaryings(m_po_id, 1 /* count */, &varying_name, GL_INTERLEAVED_ATTRIBS);
9959 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed");
9961 /* Attach the shader object to the program */
9962 gl.attachShader(m_po_id, m_vs_id);
9963 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed");
9965 /* Compile the shader */
9966 gl.compileShader(m_vs_id);
9967 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
9969 /* Make sure the compilation has succeeded */
9970 glw::GLint compile_status = GL_FALSE;
9972 gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
9973 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
9975 if (compile_status != GL_TRUE)
9977 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed" << tcu::TestLog::EndMessage;
9980 /* Link the program object */
9981 gl.linkProgram(m_po_id);
9982 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed");
9984 /* Make sure the program object has linked successfully */
9985 glw::GLint link_status = GL_FALSE;
9987 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
9988 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed");
9990 if (link_status != GL_TRUE)
9992 TCU_FAIL("Program linking failed");
9995 /* Retrieve uniform locations */
9996 m_po_expected_texel_uniform_location = gl.getUniformLocation(m_po_id, "expected_texel");
9997 m_po_lod_uniform_location = gl.getUniformLocation(m_po_id, "lod");
9999 if (m_po_expected_texel_uniform_location == -1)
10001 TCU_FAIL("expected_texel is considered an inactive uniform which is invalid");
10004 if (m_po_lod_uniform_location == -1)
10006 TCU_FAIL("lod is considered an inactive uniform which is invalid");
10010 /** Initializes all texture objects and all views used by the test. */
10011 void TextureViewTestReferenceCounting::initTextures()
10013 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10015 /* Generate texture IDs */
10016 gl.genTextures(1, &m_parent_to_id);
10017 gl.genTextures(1, &m_view_to_id);
10018 gl.genTextures(1, &m_view_view_to_id);
10019 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call(s) failed");
10021 /* Set up parent texture object A */
10022 gl.bindTexture(GL_TEXTURE_2D, m_parent_to_id);
10023 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed");
10025 gl.texStorage2D(GL_TEXTURE_2D, m_texture_n_levels, GL_RGBA8, m_texture_width, m_texture_height);
10026 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed");
10028 /* Set up view B */
10029 gl.textureView(m_view_to_id, GL_TEXTURE_2D, m_parent_to_id, GL_RGBA8, 0, /* minlevel */
10030 m_texture_n_levels, 0, /* minlayer */
10031 1); /* numlayers */
10032 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
10034 /* Set up view C */
10035 gl.textureView(m_view_view_to_id, GL_TEXTURE_2D, m_view_to_id, GL_RGBA8, 0, /* minlevel */
10036 m_texture_n_levels, 0, /* minlayer */
10037 1); /* numlayers */
10038 GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureView() call failed");
10040 /* Fill parent texture mip-maps with different static colors */
10041 unsigned char* texel_data = new unsigned char[m_texture_width * m_texture_height * 4 /* components */];
10043 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); n_mipmap++)
10045 const _norm_vec4& mipmap_color = m_mipmap_colors[n_mipmap];
10046 const unsigned int mipmap_height = m_texture_height >> n_mipmap;
10047 const unsigned int mipmap_width = m_texture_width >> n_mipmap;
10049 for (unsigned int n_texel = 0; n_texel < mipmap_height * mipmap_width; ++n_texel)
10051 unsigned char* texel_data_ptr = texel_data + n_texel * sizeof(mipmap_color.rgba);
10053 memcpy(texel_data_ptr, mipmap_color.rgba, sizeof(mipmap_color.rgba));
10054 } /* for (all relevant mip-map texels) */
10056 /* Upload new mip-map contents */
10057 gl.texSubImage2D(GL_TEXTURE_2D, n_mipmap, 0, /* xoffset */
10059 m_texture_width >> n_mipmap, m_texture_height >> n_mipmap, GL_RGBA, GL_UNSIGNED_BYTE,
10062 if (gl.getError() != GL_NO_ERROR)
10064 delete[] texel_data;
10067 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed");
10069 } /* for (all mip-maps) */
10071 delete[] texel_data;
10075 /* Initialize all GL objects necessary to run the test */
10076 void TextureViewTestReferenceCounting::initTest()
10078 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10080 /* Initialize all texture objects */
10083 /* Initialize test program object */
10086 /* Initialize XFB */
10089 /* Generate and bind a vertex array object, since we'll be doing a number of
10090 * draw calls later in the test */
10091 gl.genVertexArrays(1, &m_vao_id);
10092 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
10094 gl.bindVertexArray(m_vao_id);
10095 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
10098 /** Initializes a buffer object later used for Transform Feedback and binds
10099 * it to both general and indexed Transform Feedback binding points.
10101 void TextureViewTestReferenceCounting::initXFB()
10103 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10105 /* Sanity checks */
10106 DE_ASSERT(m_po_id != 0);
10108 /* Generate a buffer object we'll use for Transform Feedback */
10109 gl.genBuffers(1, &m_bo_id);
10110 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
10112 /* Set up buffer object storage. We need it to be large enough to hold
10113 * sizeof(glw::GLint) per mipmap level */
10114 const glw::GLint bo_size = (glw::GLint)(sizeof(glw::GLint) * m_mipmap_colors.size());
10116 gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_id);
10117 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
10119 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /* index */, m_bo_id);
10120 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
10122 gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bo_size, DE_NULL, /* data */
10124 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
10127 /** Executes test iteration.
10129 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
10131 tcu::TestNode::IterateResult TextureViewTestReferenceCounting::iterate()
10133 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
10135 /* Carry on only if GL_ARB_texture_view extension is supported */
10136 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_texture_view"))
10138 throw tcu::NotSupportedError("GL_ARB_texture_view is not supported");
10141 /* Initialize all GL objects used for the test */
10144 /* Make sure texture unit 0 is currently active */
10145 gl.activeTexture(GL_TEXTURE0);
10146 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture() call failed.");
10148 /* Activate the test program object */
10149 gl.useProgram(m_po_id);
10150 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
10152 /* Run the test in three iterations:
10154 * - Sample both the texture and all the views; once that's finished
10155 * successfully, delete the parent texture.
10156 * - Sample both views; once that's finished successfully, delete
10157 * the first of the views;
10158 * - Sample the only remaining view and make sure all mip-maps store
10161 for (unsigned int n_iteration = 0; n_iteration < 3; /* iterations in total */
10164 glw::GLuint to_ids_to_sample[3] = { 0, 0, 0 };
10166 /* Configure IDs of textures we need to validate for current iteration */
10167 switch (n_iteration)
10171 to_ids_to_sample[0] = m_parent_to_id;
10172 to_ids_to_sample[1] = m_view_to_id;
10173 to_ids_to_sample[2] = m_view_view_to_id;
10180 to_ids_to_sample[0] = m_view_to_id;
10181 to_ids_to_sample[1] = m_view_view_to_id;
10188 to_ids_to_sample[0] = m_view_view_to_id;
10194 TCU_FAIL("Invalid iteration index");
10195 } /* switch (n_iteration) */
10197 /* Iterate through all texture objects of our concern */
10198 for (unsigned int n_texture = 0; n_texture < sizeof(to_ids_to_sample) / sizeof(to_ids_to_sample[0]);
10201 glw::GLint to_id = to_ids_to_sample[n_texture];
10205 /* No texture object to sample from. */
10209 /* Bind the texture object of our interest to GL_TEXTURE_2D */
10210 gl.bindTexture(GL_TEXTURE_2D, to_id);
10211 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
10214 gl.beginTransformFeedback(GL_POINTS);
10215 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
10217 /* Iterate through all mip-maps of the texture we're currently sampling */
10218 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap)
10220 const _norm_vec4& expected_mipmap_color = m_mipmap_colors[n_mipmap];
10222 /* Update uniforms first */
10223 gl.uniform4f(m_po_expected_texel_uniform_location, (float)(expected_mipmap_color.rgba[0]) / 255.0f,
10224 (float)(expected_mipmap_color.rgba[1]) / 255.0f,
10225 (float)(expected_mipmap_color.rgba[2]) / 255.0f,
10226 (float)(expected_mipmap_color.rgba[3]) / 255.0f);
10227 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform4f() call failed.");
10229 gl.uniform1i(m_po_lod_uniform_location, n_mipmap);
10230 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
10232 /* Draw a single point. That'll feed the XFB buffer object with a single bool
10233 * indicating if the test passed for the mip-map, or not */
10234 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
10235 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
10236 } /* for (all mip-maps) */
10238 /* We're done - close XFB */
10239 gl.endTransformFeedback();
10240 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
10242 /* How did the sampling go? Map the buffer object containing the run
10243 * results into process space.
10245 const glw::GLint* run_results_ptr =
10246 (const glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
10248 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer() call failed.");
10250 if (run_results_ptr == NULL)
10252 TCU_FAIL("Pointer to mapped buffer object storage is NULL.");
10255 /* Make sure all mip-maps were sampled successfully */
10256 for (unsigned int n_mipmap = 0; n_mipmap < m_mipmap_colors.size(); ++n_mipmap)
10258 if (run_results_ptr[n_mipmap] != 1)
10260 /* Make sure the TF BO is unmapped before we throw the exception */
10261 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
10263 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid data was sampled for mip-map level ["
10264 << n_mipmap << "] and iteration [" << n_iteration << "]"
10265 << tcu::TestLog::EndMessage;
10267 TCU_FAIL("Mip-map sampling failed.");
10269 } /* for (all mip-maps) */
10271 /* Good to unmap the buffer object at this point */
10272 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
10273 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
10274 } /* for (all initialized texture objects) */
10276 /* Now that we're done with the iteration, we should delete iteration-specific texture
10279 switch (n_iteration)
10283 gl.deleteTextures(1, &m_parent_to_id);
10284 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
10286 m_parent_to_id = 0;
10292 gl.deleteTextures(1, &m_view_to_id);
10293 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
10301 gl.deleteTextures(1, &m_view_view_to_id);
10302 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() call failed.");
10304 m_view_view_to_id = 0;
10309 TCU_FAIL("Invalid iteration index");
10310 } /* switch (n_iteration) */
10311 } /* for (all iterations) */
10313 /* Test case passed */
10314 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
10321 * @param context Rendering context.
10323 TextureViewTests::TextureViewTests(deqp::Context& context)
10324 : TestCaseGroup(context, "texture_view", "Verifies \"texture view\" functionality")
10326 /* Left blank on purpose */
10329 /** Initializes a texture_storage_multisample test group.
10332 void TextureViewTests::init(void)
10334 addChild(new TextureViewTestGetTexParameter(m_context));
10335 addChild(new TextureViewTestErrors(m_context));
10336 addChild(new TextureViewTestViewSampling(m_context));
10337 addChild(new TextureViewTestViewClasses(m_context));
10338 addChild(new TextureViewTestCoherency(m_context));
10339 addChild(new TextureViewTestBaseAndMaxLevels(m_context));
10340 addChild(new TextureViewTestReferenceCounting(m_context));
10343 } /* glcts namespace */