xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cTextureViewTests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GL4CTEXTUREVIEWTESTS_HPP
2 #define _GL4CTEXTUREVIEWTESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2014-2016 The Khronos Group Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file
23  * \brief
24  */ /*-------------------------------------------------------------------*/
25 
26 /**
27  * \file  gl4cTextureViewTests.hpp
28  * \brief Declares test classes for "texture view" functionality.
29  */ /*-------------------------------------------------------------------*/
30 
31 #include "glcTestCase.hpp"
32 #include "glwDefs.hpp"
33 #include "glwEnums.hpp"
34 #include "tcuDefs.hpp"
35 #include "tcuVector.hpp"
36 
37 namespace gl4cts
38 {
39 namespace TextureView
40 {
41 
42 enum _format
43 {
44     FORMAT_FLOAT,
45     FORMAT_RGBE,
46     FORMAT_SIGNED_INTEGER,
47     FORMAT_SNORM,
48     FORMAT_UNORM,
49     FORMAT_UNSIGNED_INTEGER,
50 
51     FORMAT_UNDEFINED
52 };
53 
54 enum _sampler_type
55 {
56     SAMPLER_TYPE_FLOAT,
57     SAMPLER_TYPE_SIGNED_INTEGER,
58     SAMPLER_TYPE_UNSIGNED_INTEGER,
59 
60     SAMPLER_TYPE_UNDEFINED
61 };
62 
63 enum _view_class
64 {
65     VIEW_CLASS_FIRST,
66 
67     VIEW_CLASS_128_BITS = VIEW_CLASS_FIRST,
68     VIEW_CLASS_96_BITS,
69     VIEW_CLASS_64_BITS,
70     VIEW_CLASS_48_BITS,
71     VIEW_CLASS_32_BITS,
72     VIEW_CLASS_24_BITS,
73     VIEW_CLASS_16_BITS,
74     VIEW_CLASS_8_BITS,
75     VIEW_CLASS_RGTC1_RED,
76     VIEW_CLASS_RGTC2_RG,
77     VIEW_CLASS_BPTC_UNORM,
78     VIEW_CLASS_BPTC_FLOAT,
79 
80     /* Always last */
81     VIEW_CLASS_COUNT,
82     VIEW_CLASS_UNDEFINED = VIEW_CLASS_COUNT
83 };
84 
85 } // namespace TextureView
86 
87 /** Helper class that implements various methods used across all Texture View tests. */
88 class TextureViewUtilities
89 {
90 public:
91     /* Public type definitions */
92     typedef glw::GLenum _original_texture_internalformat;
93     typedef glw::GLenum _original_texture_target;
94     typedef glw::GLenum _view_texture_internalformat;
95     typedef glw::GLenum _view_texture_target;
96     typedef std::pair<_original_texture_internalformat, _view_texture_internalformat> _internalformat_pair;
97     typedef std::vector<glw::GLenum> _internalformats;
98     typedef _internalformats::const_iterator _internalformats_const_iterator;
99     typedef _internalformats::iterator _internalformats_iterator;
100     typedef std::pair<_original_texture_target, _view_texture_target> _texture_target_pair;
101     typedef std::vector<_internalformat_pair> _compatible_internalformat_pairs;
102     typedef _compatible_internalformat_pairs::const_iterator _compatible_internalformat_pairs_const_iterator;
103     typedef std::vector<_texture_target_pair> _compatible_texture_target_pairs;
104     typedef _compatible_texture_target_pairs::const_iterator _compatible_texture_target_pairs_const_iterator;
105     typedef std::vector<_internalformat_pair> _incompatible_internalformat_pairs;
106     typedef _incompatible_internalformat_pairs::const_iterator _incompatible_internalformat_pairs_const_iterator;
107     typedef _incompatible_internalformat_pairs::iterator _incompatible_internalformat_pairs_iterator;
108     typedef std::vector<_texture_target_pair> _incompatible_texture_target_pairs;
109     typedef _incompatible_texture_target_pairs::const_iterator _incompatible_texture_target_pairs_const_iterator;
110     typedef _incompatible_texture_target_pairs::iterator _incompatible_texture_target_pairs_iterator;
111 
112     /* Public methods */
113 
114     static unsigned int getAmountOfComponentsForInternalformat(const glw::GLenum internalformat);
115 
116     static unsigned int getBlockSizeForCompressedInternalformat(const glw::GLenum internalformat);
117 
118     static void getComponentSizeForInternalformat(const glw::GLenum internalformat, unsigned int *out_rgba_size);
119 
120     static void getComponentSizeForType(const glw::GLenum type, unsigned int *out_rgba_size);
121 
122     static const char *getErrorCodeString(const glw::GLint error_code);
123 
124     static TextureView::_format getFormatOfInternalformat(const glw::GLenum internalformat);
125 
126     static glw::GLenum getGLFormatOfInternalformat(const glw::GLenum internalformat);
127 
128     static const char *getGLSLDataTypeForSamplerType(const TextureView::_sampler_type sampler_type,
129                                                      const unsigned int n_components);
130 
131     static const char *getGLSLTypeForSamplerType(const TextureView::_sampler_type sampler_type);
132 
133     static _incompatible_internalformat_pairs getIllegalTextureAndViewInternalformatCombinations();
134 
135     static _incompatible_texture_target_pairs getIllegalTextureAndViewTargetCombinations();
136 
137     static _internalformats getInternalformatsFromViewClass(TextureView::_view_class view_class);
138 
139     static const char *getInternalformatString(const glw::GLenum internalformat);
140 
141     static _compatible_internalformat_pairs getLegalTextureAndViewInternalformatCombinations();
142 
143     static _compatible_texture_target_pairs getLegalTextureAndViewTargetCombinations();
144 
145     static void getMajorMinorVersionFromContextVersion(const glu::ContextType &context_type,
146                                                        glw::GLint *out_major_version, glw::GLint *out_minor_version);
147 
148     static TextureView::_sampler_type getSamplerTypeForInternalformat(const glw::GLenum internalformat);
149 
150     static unsigned int getTextureDataSize(const glw::GLenum internalformat, const glw::GLenum type,
151                                            const unsigned int width, const unsigned int height);
152 
153     static const char *getTextureTargetString(const glw::GLenum texture_target);
154 
155     static glw::GLenum getTypeCompatibleWithInternalformat(const glw::GLenum internalformat);
156 
157     static TextureView::_view_class getViewClassForInternalformat(const glw::GLenum internalformat);
158 
159     static void initTextureStorage(const glw::Functions &gl, bool init_mutable_to, glw::GLenum texture_target,
160                                    glw::GLint texture_depth, glw::GLint texture_height, glw::GLint texture_width,
161                                    glw::GLenum texture_internalformat, glw::GLenum texture_format,
162                                    glw::GLenum texture_type, unsigned int n_levels_needed,
163                                    unsigned int n_cubemaps_needed, glw::GLint bo_id);
164 
165     static bool isInternalformatCompatibleForTextureView(glw::GLenum original_internalformat,
166                                                          glw::GLenum view_internalformat);
167 
168     static bool isInternalformatCompressed(const glw::GLenum internalformat);
169 
170     static bool isInternalformatSRGB(const glw::GLenum internalformat);
171 
172     static bool isInternalformatSupported(glw::GLenum internalformat, const glw::GLint major_version,
173                                           const glw::GLint minor_version);
174 
175     static bool isLegalTextureTargetForTextureView(glw::GLenum original_texture_target,
176                                                    glw::GLenum view_texture_target);
177 };
178 
179 /**
180  *   1. Make sure glGetTexParameterfv() and glGetTexParameteriv() report
181  *      correct values for the following texture view-specific
182  *      properties:
183  *
184  *      * GL_TEXTURE_IMMUTABLE_LEVELS; (in texture view-specific context
185  *                                      only)
186  *      * GL_TEXTURE_VIEW_MIN_LAYER;
187  *      * GL_TEXTURE_VIEW_MIN_LEVEL;
188  *      * GL_TEXTURE_VIEW_NUM_LAYERS;
189  *      * GL_TEXTURE_VIEW_NUM_LEVELS;
190  *
191  *      These properties should be set to 0 (or GL_FALSE) by default.
192  *      For textures created with glTexStorage() and glTextureView()
193  *      functions, language from bullet (11) of GL_ARB_texture_view
194  *      extension specification applies, as well as "Texture Views"
195  *      section 8.18 of OpenGL 4.3 Core Profile specification.
196  *
197  *      The conformance test should check values of the aforementioned
198  *      properties for the following objects:
199  *
200  *      1) mutable texture objects generated with glTexImage*D() calls,
201  *         then bound to all supported texture targets (as described
202  *         under (*) ).
203  *      2) immutable texture objects generated with glTexStorage*D() calls
204  *         for all supported texture targets (as described under (*) ).
205  *      3) texture views using all texture targets (as described under
206  *         (*) ) compatible with parent texture object's texture target.
207  *         All texture targets should be considered for the parent object.
208  *      4) texture views created on top of texture views described in 3).
209  *
210  *      For texture view cases, the test should verify that:
211  *
212  *      1) GL_TEXTURE_VIEW_NUM_LAYERS and GL_TEXTURE_VIEW_NUM_LEVELS are
213  *         clamped as specified for cases where <numlayers> or <numlevels>
214  *         arguments used for glTextureView() calls exceed beyond the
215  *         original texture.
216  *      2) GL_TEXTURE_VIEW_MIN_LEVEL is set to <minlevel> + value of
217  *         GL_TEXTURE_VIEW_MIN_LEVEL from the original texture.
218  *      3) GL_TEXTURE_VIEW_MIN_LAYER is set to <minlayer> + value of
219  *         GL_TEXTURE_VIEW_MIN_LAYER from the original texture.
220  *      4) GL_TEXTURE_VIEW_NUM_LEVELS is set to the lesser of <numlevels>
221  *         and the value of original texture's GL_TEXTURE_VIEW_NUM_LEVELS
222  *         minus <minlevels>.
223  *      5) GL_TEXTURE_VIEW_NUM_LAYERS is set to the lesser of <numlayers>
224  *         and the value of original texture's GL_TEXTURE_VIEW_NUM_LAYERS
225  *         minus <minlayer>.
226  *
227  *      A single configuration of a texture object and a texture view
228  *      for each valid texture target should be considered for the
229  *      purpose of the test.
230  *
231  *      (*) Texture targets to use:
232  *
233  *      * GL_TEXTURE_1D;
234  *      * GL_TEXTURE_1D_ARRAY;
235  *      * GL_TEXTURE_2D;
236  *      * GL_TEXTURE_2D_ARRAY;
237  *      * GL_TEXTURE_2D_MULTISAMPLE;
238  *      * GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
239  *      * GL_TEXTURE_3D;
240  *      * GL_TEXTURE_CUBE_MAP;
241  *      * GL_TEXTURE_CUBE_MAP_ARRAY;
242  *      * GL_TEXTURE_RECTANGLE;
243  **/
244 class TextureViewTestGetTexParameter : public deqp::TestCase
245 {
246 public:
247     /* Public methods */
248     TextureViewTestGetTexParameter(deqp::Context &context);
249 
~TextureViewTestGetTexParameter()250     virtual ~TextureViewTestGetTexParameter()
251     {
252     }
253 
254     virtual void deinit();
255     virtual tcu::TestNode::IterateResult iterate();
256 
257 private:
258     /* Private type definitions */
259     enum _test_texture_type
260     {
261         TEST_TEXTURE_TYPE_NO_STORAGE_ALLOCATED,
262         TEST_TEXTURE_TYPE_IMMUTABLE_TEXTURE_OBJECT,
263         TEST_TEXTURE_TYPE_MUTABLE_TEXTURE_OBJECT,
264         TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_IMMUTABLE_TEXTURE_OBJECT,
265         TEST_TEXTURE_TYPE_TEXTURE_VIEW_CREATED_FROM_TEXTURE_VIEW,
266 
267         /* Always last */
268         TEST_TEXTURE_TYPE_UNDEFINED
269     };
270 
271     struct _test_run
272     {
273         glw::GLint expected_n_immutable_levels;
274         glw::GLint expected_n_min_layer;
275         glw::GLint expected_n_min_level;
276         glw::GLint expected_n_num_layers;
277         glw::GLint expected_n_num_levels;
278 
279         glw::GLuint parent_texture_object_id;
280         glw::GLuint texture_view_object_created_from_immutable_to_id;
281         glw::GLuint texture_view_object_created_from_view_to_id;
282 
283         glw::GLenum texture_target;
284         _test_texture_type texture_type;
285 
286         /* Constructor */
_test_rungl4cts::TextureViewTestGetTexParameter::_test_run287         _test_run()
288         {
289             expected_n_immutable_levels = 0;
290             expected_n_min_layer        = 0;
291             expected_n_min_level        = 0;
292             expected_n_num_layers       = 0;
293             expected_n_num_levels       = 0;
294 
295             parent_texture_object_id                         = 0;
296             texture_view_object_created_from_immutable_to_id = 0;
297             texture_view_object_created_from_view_to_id      = 0;
298 
299             texture_target = GL_NONE;
300             texture_type   = TEST_TEXTURE_TYPE_UNDEFINED;
301         }
302     };
303 
304     typedef std::vector<_test_run> _test_runs;
305     typedef _test_runs::const_iterator _test_runs_const_iterator;
306     typedef _test_runs::iterator _test_runs_iterator;
307 
308     /* Private methods */
309     void initTestRuns();
310 
311     /* Private fields */
312     _test_runs m_test_runs;
313 };
314 
315 /** Verify glTextureView() generates errors as described in the
316  *  specification:
317  *
318  *  a) GL_INVALID_VALUE should be generated if <texture> is 0.
319  *  b) GL_INVALID_OPERATION should be generated if <texture> is not
320  *     a valid name returned by glGenTextures().
321  *  c) GL_INVALID_OPERATION should be generated if <texture> has
322  *     already been bound and given a target.
323  *  d) GL_INVALID_VALUE should be generated if <origtexture> is not
324  *     the name of a texture object.
325  *  e) GL_INVALID_OPERATION error should be generated if <origtexture>
326  *     is a mutable texture object.
327  *  f) GL_INVALID_OPERATION error should be generated whenever the
328  *     application tries to generate a texture view for a target
329  *     that is incompatible with original texture's target. (as per
330  *     table 8.20 from OpenGL 4.4 specification)
331  *
332  *    NOTE: All invalid original+view texture target combinations
333  *          should be checked.
334  *
335  *  g) GL_INVALID_OPERATION error should be generated whenever the
336  *     application tries to create a texture view, internal format
337  *     of which can be found in table 8.21 of OpenGL 4.4
338  *     specification, and the texture view's internal format is
339  *     incompatible with parent object's internal format. Both
340  *     textures and views should be used as parent objects for the
341  *     purpose of the test.
342  *
343  *     NOTE: All invalid texture view internal formats should be
344  *           checked for all applicable original object's internal
345  *           formats.
346  *
347  *  h) GL_INVALID_OPERATION error should be generated whenever the
348  *     application tries to create a texture view using an internal
349  *     format that does not match the original texture's, and the
350  *     original texture's internalformat cannot be found in table
351  *     8.21 of OpenGL 4.4 specification.
352  *
353  *     NOTE: All required base, sized and compressed texture internal
354  *           formats (as described in section 8.5.1 and table 8.14
355  *           of OpenGL 4.4 specification) that cannot be found in
356  *           table 8.21 should be considered for the purpose of this
357  *           test.
358  *
359  *  i) GL_INVALID_VALUE error should be generated if <minlevel> is
360  *     larger than the greatest level of <origtexture>.
361  *  j) GL_INVALID_VALUE error should be generated if <minlayer> is
362  *     larger than the greatest layer of <origtexture>.
363  *  k) GL_INVALID_VALUE error should be generated if <target> is
364  *     GL_TEXTURE_CUBE_MAP and <numlayers> is not 6.
365  *  l) GL_INVALID_VALUE error should be generated if <target> is
366  *     GL_TEXTURE_CUBE_MAP_ARRAY and <numlayers> is not a multiple
367  *     of 6.
368  *  m) GL_INVALID_VALUE error should be generated if <target> is
369  *     GL_TEXTURE_1D and <numlayers> is not 1;
370  *  n) GL_INVALID_VALUE error should be generated if <target> is
371  *     GL_TEXTURE_2D and <numlayers> is not 1;
372  *  o) GL_INVALID_VALUE error should be generated if <target> is
373  *     GL_TEXTURE_3D and <numlayers> is not 1;
374  *  p) GL_INVALID_VALUE error should be generated if <target> is
375  *     GL_TEXTURE_RECTANGLE and <numlayers> is not 1;
376  *  q) GL_INVALID_VALUE error should be generated if <target> is
377  *     GL_TEXTURE_2D_MULTISAMPLE and <numlayers> is not 1;
378  *  r) GL_INVALID_OPERATION error should be generated if <target> is
379  *     GL_TEXTURE_CUBE_MAP and original texture's width does not
380  *     match original texture's height for all levels.
381  *  s) GL_INVALID_OPERATION error should be generated if <target> is
382  *     GL_TEXTURE_CUBE_MAP_ARRAY and original texture's width does
383  *     not match original texture's height for all levels.
384  *
385  *  NOTE: GL_INVALID_OPERATION error should also be generated for cases
386  *        when any of the original texture's dimension is larger
387  *        than the maximum supported corresponding dimension of the
388  *        new target, but that condition can be very tricky to test
389  *        in a portable manner. Hence, the conformance test will
390  *        not verify if the error is generated as specified.
391  *
392  **/
393 class TextureViewTestErrors : public deqp::TestCase
394 {
395 public:
396     /* Public methods */
397     TextureViewTestErrors(deqp::Context &context);
398 
~TextureViewTestErrors()399     virtual ~TextureViewTestErrors()
400     {
401     }
402 
403     virtual void deinit();
404 
405     virtual tcu::TestNode::IterateResult iterate();
406 
407 private:
408     /* Private fields */
409     glw::GLuint m_bo_id;
410     glw::GLuint m_reference_immutable_to_1d_id;
411     glw::GLuint m_reference_immutable_to_2d_id;
412     glw::GLuint m_reference_immutable_to_2d_array_id;
413     glw::GLuint m_reference_immutable_to_2d_array_32_by_33_id;
414     glw::GLuint m_reference_immutable_to_2d_multisample_id;
415     glw::GLuint m_reference_immutable_to_3d_id;
416     glw::GLuint m_reference_immutable_to_cube_map_id;
417     glw::GLuint m_reference_immutable_to_cube_map_array_id;
418     glw::GLuint m_reference_immutable_to_rectangle_id;
419     glw::GLuint m_reference_mutable_to_2d_id;
420     glw::GLuint m_test_modified_to_id_1;
421     glw::GLuint m_test_modified_to_id_2;
422     glw::GLuint m_test_modified_to_id_3;
423     glw::GLuint m_view_bound_to_id;
424     glw::GLuint m_view_never_bound_to_id;
425 };
426 
427 /** Verify that sampling data from texture views, that use internal
428  *  format which is compatible with the original texture's internal
429  *  format, works correctly.
430  *
431  *  For simplicity, both the parent object and its corresponding
432  *  view should use the same GL_RGBA8 internal format. Both texture
433  *  and view should be used as parent objects for the purpose of
434  *  the test.
435  *
436  *  The test should iterate over all texture targets enlisted in
437  *  table 8.20 from OpenGL 4.4 specification, excluding GL_TEXTURE_BUFFER.
438  *  For each such texture target, an immutable texture object that
439  *  will be used as original object should be created. The object
440  *  should be defined as follows:
441  *
442  *  a) For 1D texture targets, width of 4 should be used.
443  *  b) For 2D texture targets, width and height of 4 should be used.
444  *  c) For 3D texture targets, depth, width and height of 4 should
445  *     be used;
446  *  d) Cube-map texture objects should use a 4x4 face size;
447  *  e) Arrayed 1D/2D/cube-map texture objects should have a depth
448  *     of 4.
449  *  f) Each slice/face/layer-face mip-map should be filled with
450  *     a static color. If original texture is multi-sampled, subsequent
451  *     samples should be assigned a different color. Exact R/G/B/A
452  *     intensities are arbitrary but they must be unique across all
453  *     mip-maps and samples considered for a particular iteration.
454  *     Mip-maps should *not* be generated - instead, it is expected
455  *     the test will fill them manually with content using API (for
456  *     non-multisampled cases), or by means of a simple FS+VS
457  *     program (for multisampled render targets).
458  *
459  *  For each such original texture object, texture views should be
460  *  created for all compatible texture targets. These views should
461  *  be configured as below:
462  *
463  *  * minlayer:  1 (for arrayed/cube-map/cube-map arrayed views),
464  *               0 otherwise;
465  *  * numlayers: 12 (for cube-map arrayed views),
466  *               6 (for cube-map views)
467  *               2 (for arrayed views),
468  *               1 otherwise;
469  *
470  *  * minlevel:  1;
471  *  * numlevels: 2;
472  *
473  *  For testing purposes, the test should use the following rendering
474  *  stages (forming a program object):
475  *
476  *  - Vertex shader;
477  *  - Tessellation control;
478  *  - Tessellation evaluation;
479  *  - Geometry shader;         (should output a triangle strip forming
480  *                              a full-screen quad);
481  *  - Fragment shader;
482  *
483  *  In each stage (excluding fragment shader), as many samples as
484  *  available (for multisample views) OR a single texel should be
485  *  sampled at central (0.5, 0.5, ...) location using textureLod().
486  *  The data should then be compared with reference values and the
487  *  validation result should be passed to next stage using
488  *  an output variable. Subsequent stages should pass validation results
489  *  from all previous stages to following stages until geometry shader
490  *  stage is reached. The information should be captured by the test
491  *  using XFB and verified.
492  *  Fragment shader should output a green colour, if the sampling
493  *  operation returned a valid set of colors for (U, V) location,
494  *  corresponding to rasterized fragment location, red otherwise.
495  *
496  *  The test passes if the sampling operation worked correctly in
497  *  all stages for all texture's internal format+view's internal
498  *  format combinations.
499  *
500  **/
501 class TextureViewTestViewSampling : public deqp::TestCase
502 {
503 public:
504     /* Public methods */
505     TextureViewTestViewSampling(deqp::Context &context);
506 
507     virtual tcu::TestNode::IterateResult iterate();
508 
509 protected:
510     /* Protected methods */
511     virtual void deinit();
512 
513 private:
514     /* Private type declarations */
515     struct _reference_color_storage
516     {
517         tcu::Vec4 *data;
518 
519         unsigned int n_faces;
520         unsigned int n_layers;
521         unsigned int n_mipmaps;
522         unsigned int n_samples;
523 
524         /** Constructor.
525          *
526          *  @param in_n_faces   Amount of faces to initialize the storage for.
527          *                      Must not be 0.
528          *  @param in_n_layers  Amount of layers to initialize the storage for.
529          *                      Must not be 0.
530          *  @param in_n_mipmaps Amount of mip-maps to initialize the storage for.
531          *                      Must not be 0.
532          *  @param in_n_samples Amount of samples to initialize the storage for.
533          *                      Must not be 0.
534          **/
_reference_color_storagegl4cts::TextureViewTestViewSampling::_reference_color_storage535         explicit _reference_color_storage(const unsigned int in_n_faces, const unsigned int in_n_layers,
536                                           const unsigned int in_n_mipmaps, const unsigned int in_n_samples)
537         {
538             DE_ASSERT(in_n_faces != 0);
539             DE_ASSERT(in_n_layers != 0);
540             DE_ASSERT(in_n_mipmaps != 0);
541             DE_ASSERT(in_n_samples != 0);
542 
543             n_faces   = in_n_faces;
544             n_layers  = in_n_layers;
545             n_mipmaps = in_n_mipmaps;
546             n_samples = in_n_samples;
547 
548             data = new tcu::Vec4[in_n_faces * in_n_layers * in_n_mipmaps * in_n_samples];
549         }
550 
551         /** Destructor */
~_reference_color_storagegl4cts::TextureViewTestViewSampling::_reference_color_storage552         ~_reference_color_storage()
553         {
554             if (data != DE_NULL)
555             {
556                 delete[] data;
557 
558                 data = DE_NULL;
559             }
560         }
561     };
562 
563     /* Private methods */
564     void deinitIterationSpecificProgramAndShaderObjects();
565     void deinitPerSampleFillerProgramAndShaderObjects();
566     void deinitTextureObjects();
567     bool executeTest();
568     void initIterationSpecificProgramObject();
569     void initParentTextureContents();
570     void initPerSampleFillerProgramObject();
571     void initTest();
572 
573     void initTextureObject(bool is_view_texture, glw::GLenum texture_target, glw::GLenum view_texture_target);
574 
575     tcu::Vec4 getRandomReferenceColor();
576 
577     tcu::Vec4 getReferenceColor(unsigned int n_layer, unsigned int n_face, unsigned int n_mipmap,
578                                 unsigned int n_sample);
579 
580     glw::GLint getMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat);
581 
582     void resetReferenceColorStorage(unsigned int n_layers, unsigned int n_faces, unsigned int n_mipmaps,
583                                     unsigned int n_samples);
584 
585     void setReferenceColor(unsigned int n_layer, unsigned int n_face, unsigned int n_mipmap, unsigned int n_sample,
586                            tcu::Vec4 color);
587 
588     /* Private variables */
589     glw::GLuint m_bo_id;
590     glw::GLuint m_fs_id;
591     glw::GLuint m_gs_id;
592     glw::GLuint m_po_id;
593     glw::GLint m_po_lod_location;
594     glw::GLint m_po_n_face_location;
595     glw::GLint m_po_reference_colors_location;
596     glw::GLint m_po_texture_location;
597     glw::GLint m_po_z_float_location;
598     glw::GLint m_po_z_int_location;
599     glw::GLuint m_tc_id;
600     glw::GLuint m_te_id;
601     glw::GLuint m_vs_id;
602 
603     glw::GLuint m_per_sample_filler_fs_id;
604     glw::GLuint m_per_sample_filler_gs_id;
605     glw::GLuint m_per_sample_filler_po_id;
606     glw::GLint m_per_sample_filler_po_layer_id_location;
607     glw::GLint m_per_sample_filler_po_reference_colors_location;
608     glw::GLuint m_per_sample_filler_vs_id;
609 
610     glw::GLuint m_result_to_id;
611     glw::GLuint m_to_id;
612     glw::GLuint m_view_to_id;
613 
614     glw::GLuint m_fbo_id;
615     glw::GLuint m_vao_id;
616 
617     glw::GLint m_max_color_texture_samples_gl_value;
618 
619     glw::GLuint m_iteration_parent_texture_depth;
620     glw::GLuint m_iteration_parent_texture_height;
621     glw::GLuint m_iteration_parent_texture_n_levels;
622     glw::GLuint m_iteration_parent_texture_n_samples;
623     glw::GLenum m_iteration_parent_texture_target;
624     glw::GLuint m_iteration_parent_texture_width;
625     glw::GLuint m_iteration_view_texture_minlayer;
626     glw::GLuint m_iteration_view_texture_numlayers;
627     glw::GLuint m_iteration_view_texture_minlevel;
628     glw::GLuint m_iteration_view_texture_numlevels;
629     glw::GLenum m_iteration_view_texture_target;
630 
631     const glw::GLuint m_reference_texture_depth;
632     const glw::GLuint m_reference_texture_height;
633     const glw::GLuint m_reference_texture_n_mipmaps;
634     const glw::GLuint m_reference_texture_width;
635 
636     _reference_color_storage *m_reference_color_storage;
637     unsigned char *m_result_data;
638 };
639 
640 /** Verify view class functionality.
641  *
642  *  Consider all view classes presented in table 8.20 of OpenGL 4.4
643  *  Specification. For each view class, consider all internal format
644  *  combinations for the purpose of the test.
645  *
646  *  For each internal format, a texture object of specified internal
647  *  format and of 2x2 base mip-map resolution should be used.
648  *
649  *  For each internal format, a program object consisting of a vertex
650  *  shader stage should be used. The shader should sample all 4 texels
651  *  of the view and store retrieved data in output variables.
652  *  These values should then be XFBed to the test.
653  *
654  *  The test passes if all retrieved values for all pairs considered
655  *  are found to be valid.
656  *
657  **/
658 class TextureViewTestViewClasses : public deqp::TestCase
659 {
660 public:
661     /* Public methods */
662     TextureViewTestViewClasses(deqp::Context &context);
663 
664     virtual tcu::TestNode::IterateResult iterate();
665 
666 protected:
667     /* Protected methods */
668     virtual void deinit();
669 
670 private:
671     /* Private methods */
672     void getComponentDataForByteAlignedInternalformat(const unsigned char *data, const unsigned int n_components,
673                                                       const unsigned int *component_sizes,
674                                                       const TextureView::_format format, void *result);
675 
676     void initBufferObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat);
677 
678     void initProgramObject(glw::GLenum texture_internalformat, glw::GLenum view_internalformat);
679 
680     void initTest();
681 
682     void initTextureObject(bool should_init_parent_texture, glw::GLenum texture_internalformat,
683                            glw::GLenum view_internalformat);
684 
685     void verifyResultData(glw::GLenum texture_internalformat, glw::GLenum view_internalformat,
686                           const unsigned char *texture_data_ptr, const unsigned char *view_data_ptr);
687 
688     /* Private fields */
689     glw::GLuint m_bo_id;
690     glw::GLuint m_po_id;
691     glw::GLuint m_to_id;
692     glw::GLuint m_to_temp_id;
693     glw::GLuint m_vao_id;
694     glw::GLuint m_view_to_id;
695     glw::GLuint m_vs_id;
696 
697     unsigned char *m_decompressed_mipmap_data;
698     unsigned char *m_mipmap_data;
699 
700     unsigned int m_bo_size;
701     bool m_has_test_failed;
702     const unsigned int m_texture_height;
703     const glw::GLenum m_texture_unit_for_parent_texture;
704     const glw::GLenum m_texture_unit_for_view_texture;
705     const unsigned int m_texture_width;
706     unsigned int m_view_data_offset;
707 };
708 
709 /**
710  *  Verify view/parent texture coherency.
711  *
712  *  Consider an original 2D texture of 64x64 base mip-map resolution,
713  *  using GL_RGBA8 internal format, filled with horizontal linear
714  *  gradient from (0.0, 0.1, 1.0, 1.0) to (1.0, 0.9, 0.0, 0.0).
715  *  All subsequent mip-maps are to be generated by glGenerateMipmap().
716  *
717  *  A 2D texture view should be generated from this texture, using
718  *  mipmaps from levels 1 to 2 (inclusive).
719  *
720  *  The test should verify the following scenarios are handled
721  *  correctly by GL implementation:
722  *
723  *  1) glTexSubImage2D() should be used on the view to replace portion
724  *     of the gradient with a static color. A vertex shader should
725  *     then be used to sample the parent texture at central
726  *     location of that sub-region and verify it has been replaced
727  *     with the static color. Result of the comparison (true/false)
728  *     should be XFBed and verified by the test; *No* memory barrier
729  *     is to be used between the first two steps.
730  *  2) The view should be updated as in step 1), with glTexSubImage2D()
731  *     being replaced with glBlitFramebuffer(). A texture filled
732  *     with a static color should be used as a source for the blitting
733  *     operation.
734  *  3) A program object should be used to fill the view with
735  *     reversed (1.0, 0.9, 0.0, 0.0)->(0.0, 0.1, 1.0, 1.0) gradient.
736  *     Contents of the parent texture should then be validated with
737  *     another program object and the result should be verified by
738  *     XFBing the comparison outcome, similar to what has been
739  *     described for step 1). Again, *no* memory barrier is to be
740  *     used in-between.
741  *  4) The view should be bound to an image unit. The contents of
742  *     that view should then be completely replaced with the reversed
743  *     gradient by doing a sufficient amount of writes, assuming each vertex
744  *     shader invocation performs a single store operation in an
745  *     unique location. A GL_TEXTURE_FETCH_BARRIER_BIT memory
746  *     barrier should be issued. The contents of the parent texture
747  *     should then be verified, as described in step 1) and 3).
748  *  5) The view should be updated as in step 4). However, this time
749  *     a GL_TEXTURE_UPDATE_BARRIER_BIT memory barrier should be issued.
750  *     The contents of the parent texture should then be read with
751  *     a glGetTexImage() call and verified by the test.
752  *
753  *     (NOTE: cases 4) and 5) should only be executed on implementations
754  *            reporting GL_ARB_shader_image_load_store extension
755  *            support, owing to lack of glMemoryBarrier() support
756  *            in OpenGL 4.0)
757  *
758  *  6), 7), 8), 9) Execute tests 1), 2), 3), 4), 5), replacing "texture
759  *                 views" with "parent textures" and "parent textures"
760  *                 with "texture views".
761  */
762 class TextureViewTestCoherency : public deqp::TestCase
763 {
764 public:
765     /* Public methods */
766     TextureViewTestCoherency(deqp::Context &context);
767 
768     virtual void deinit();
769     virtual tcu::TestNode::IterateResult iterate();
770 
771 private:
772     /* Private type definitions */
773     enum _barrier_type
774     {
775         BARRIER_TYPE_NONE,
776         BARRIER_TYPE_TEXTURE_FETCH_BARRIER_BIT,
777         BARRIER_TYPE_TEXTURE_UPDATE_BUFFER_BIT
778     };
779 
780     enum _texture_type
781     {
782         TEXTURE_TYPE_PARENT_TEXTURE,
783         TEXTURE_TYPE_TEXTURE_VIEW,
784         TEXTURE_TYPE_IMAGE
785     };
786 
787     enum _verification_mean
788     {
789         VERIFICATION_MEAN_PROGRAM,
790         VERIFICATION_MEAN_GLGETTEXIMAGE
791     };
792 
793     /* Private methods */
794     void checkAPICallCoherency(_texture_type texture_type, bool should_use_glTexSubImage2D);
795 
796     void checkProgramWriteCoherency(_texture_type texture_type, bool should_use_images, _barrier_type barrier_type,
797                                     _verification_mean verification_mean);
798 
799     unsigned char *getHorizontalGradientData() const;
800 
801     void getReadPropertiesForTextureType(_texture_type texture_type, glw::GLuint *out_to_id,
802                                          unsigned int *out_read_lod) const;
803 
804     unsigned char *getStaticColorTextureData(unsigned int width, unsigned int height) const;
805 
806     void getWritePropertiesForTextureType(_texture_type texture_type, glw::GLuint *out_to_id, unsigned int *out_width,
807                                           unsigned int *out_height) const;
808 
809     void initBufferObjects();
810     void initFBO();
811     void initPrograms();
812     void initTextureContents();
813     void initTextures();
814     void initVAO();
815 
816     /* Private fields */
817     bool m_are_images_supported;
818     glw::GLuint m_bo_id;
819     glw::GLuint m_draw_fbo_id;
820     glw::GLuint m_gradient_verification_po_id;
821     glw::GLint m_gradient_verification_po_sample_exact_uv_location;
822     glw::GLint m_gradient_verification_po_lod_location;
823     glw::GLint m_gradient_verification_po_texture_location;
824     glw::GLuint m_gradient_verification_vs_id;
825     glw::GLint m_gradient_image_write_image_size_location;
826     glw::GLuint m_gradient_image_write_po_id;
827     glw::GLuint m_gradient_image_write_vs_id;
828     glw::GLuint m_gradient_write_po_id;
829     glw::GLuint m_gradient_write_fs_id;
830     glw::GLuint m_gradient_write_vs_id;
831     glw::GLuint m_read_fbo_id;
832     glw::GLuint m_static_to_id;
833     glw::GLuint m_to_id;
834     glw::GLuint m_vao_id;
835     glw::GLuint m_view_to_id;
836     glw::GLint m_verification_po_expected_color_location;
837     glw::GLint m_verification_po_lod_location;
838     glw::GLuint m_verification_po_id;
839     glw::GLuint m_verification_vs_id;
840 
841     unsigned char m_static_color_byte[4 /* rgba */];
842     float m_static_color_float[4 /* rgba */];
843 
844     const unsigned int m_static_texture_height;
845     const unsigned int m_static_texture_width;
846     const unsigned int m_texture_height;
847     const unsigned int m_texture_n_components;
848     const unsigned int m_texture_n_levels;
849     const unsigned int m_texture_width;
850 };
851 
852 /** Verify GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL are
853  *  interpreted relative to the view, not to the original data
854  *  store.
855  *
856  *  Consider original 2D texture of 64x64 base mip-map resolution,
857  *  using GL_RGBA8 internal format, filled with:
858  *
859  *  * horizontal linear gradient from (0.0, 0.1, 0,2, 0.3) to
860  *    (1.0, 0.9, 0.8, 0.7) at level 0;
861  *  * horizontal linear gradient from (0.1, 0.2, 0.3, 0.4) to
862  *    (0.9, 0.8, 0.7, 0.6) at level 1;
863  *  * horizontal linear gradient from (0.2, 0.3, 0.4, 0.5) to
864  *    (0.8, 0.7, 0.6, 0.5) at level 2;
865  *  * ..and so on.
866  *
867  *  GL_TEXTURE_BASE_LEVEL of the texture should be set at 2,
868  *  GL_TEXTURE_MAX_LEVEL of the texture should be set at 4.
869  *
870  *  A 2D texture view should be generated from this texture, using
871  *  mipmaps from 0 to 5 (inclusive).
872  *
873  *  GL_TEXTURE_BASE_LEVEL of the view should be set at 1,
874  *  GL_TEXTURE_MAX_LEVEL of the view should be set at 2.
875  *
876  *  The test should perform the following:
877  *
878  *  1) First, a FS+VS program should be executed twice. The vertex
879  *     shader should output 4 vertices forming a triangle-strip, forming
880  *     a quad spanning from (-1, -1, 0, 1) to (1, 1, 0, 1). Each
881  *     vertex should be assigned a corresponding UV location.
882  *     The fragment shader should sample input texture view with
883  *     textureLod() at fragment-specific UV using LOD 0 in the
884  *     first run, and LOD 1 in the second run.
885  *     The sampled vec4 should be written into a draw buffer, to which
886  *     a texture has been attached of exactly the same resolution
887  *     and internal format as the input texture view's mip-map being
888  *     processed at the time of invocation.
889  *
890  *     This pass should provide us with LOD 0 and LOD 1 texture data,
891  *     as configured with GL_TEXTURE_BASE_LEVEL and
892  *     GL_TEXTURE_MAX_LEVEL view parameters.
893  *
894  *  2) Having executed the aforementioned program, the test should
895  *     download the textures that step 1 has rendered to using
896  *     glGetTexImage() and verify correct mipmaps have been sampled
897  *     by textureLod().
898  *
899  *  Test passes if the retrieved texture data is valid.
900  **/
901 class TextureViewTestBaseAndMaxLevels : public deqp::TestCase
902 {
903 public:
904     /* Public methods */
905     TextureViewTestBaseAndMaxLevels(deqp::Context &context);
906 
907     virtual void deinit();
908     virtual tcu::TestNode::IterateResult iterate();
909 
910 private:
911     /* Private methods */
912     void initProgram();
913     void initTest();
914     void initTextures();
915 
916     /* Private fields */
917     const unsigned int m_texture_height;
918     const unsigned int m_texture_n_components;
919     const unsigned int m_texture_n_levels;
920     const unsigned int m_texture_width;
921     const unsigned int m_view_height;
922     const unsigned int m_view_width;
923 
924     unsigned char *m_layer_data_lod0;
925     unsigned char *m_layer_data_lod1;
926 
927     glw::GLuint m_fbo_id;
928     glw::GLuint m_fs_id;
929     glw::GLuint m_po_id;
930     glw::GLint m_po_lod_index_uniform_location;
931     glw::GLint m_po_to_sampler_uniform_location;
932     glw::GLuint m_result_to_id;
933     glw::GLuint m_to_id;
934     glw::GLuint m_vao_id;
935     glw::GLuint m_view_to_id;
936     glw::GLuint m_vs_id;
937 };
938 
939 /** Verify texture view reference counting is implemented correctly.
940  *
941  *  Parent texture object A should be an immutable 2D texture of
942  *  64x64 resolution and of GL_RGBA8 internalformat. Each mip-map
943  *  should be filled with a different static color.
944  *
945  *  View B should be created from texture A, and view C should be
946  *  instantiated from view B. The views should use the same texture
947  *  target and internalformat as texture A. <minlayer> and <minlevel>
948  *  values of 0 should be used for view generation. All available
949  *  texture layers and levels should be used for the views.
950  *
951  *  The test should:
952  *
953  *  a) Sample the texture and both views, make sure correct data can
954  *     be sampled in VS stage;
955  *  b) Delete texture A;
956  *  c) Sample both views, make sure correct data can be sampled in
957  *     VS stage;
958  *  d) Delete view B;
959  *  e) Sample view C, make sure correct data can be sampled in VS
960  *     stage;
961  *
962  *  A program object consisting only of vertex shader should be used
963  *  by the test. The shader should sample all mip-maps of the bound
964  *  texture at (0.5, 0.5) and compare the retrieved texels against
965  *  reference values. Comparison outcome should be XFBed back to
966  *  the test implementation.
967  *
968  *  Test passes if the sampling operation is reported to work
969  *  correctly for all steps.
970  *
971  **/
972 class TextureViewTestReferenceCounting : public deqp::TestCase
973 {
974 public:
975     /* Public methods */
976     TextureViewTestReferenceCounting(deqp::Context &context);
977 
978     virtual void deinit();
979     virtual tcu::TestNode::IterateResult iterate();
980 
981 private:
982     /* Private type definitions */
983     struct _norm_vec4
984     {
985         unsigned char rgba[4];
986 
987         /* Constructor
988          *
989          * @param r Red value to store for the component
990          * @param g Green value to store for the component
991          * @param b Blue value to store for the component
992          * @param a Alpha value to store for the component.
993          */
_norm_vec4gl4cts::TextureViewTestReferenceCounting::_norm_vec4994         explicit _norm_vec4(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
995         {
996             rgba[0] = r;
997             rgba[1] = g;
998             rgba[2] = b;
999             rgba[3] = a;
1000         }
1001     };
1002 
1003     /* Private methods */
1004     void initProgram();
1005     void initTest();
1006     void initTextures();
1007     void initXFB();
1008 
1009     /* Private variables */
1010     glw::GLuint m_bo_id;
1011     glw::GLuint m_parent_to_id;
1012     glw::GLuint m_po_id;
1013     glw::GLint m_po_expected_texel_uniform_location;
1014     glw::GLint m_po_lod_uniform_location;
1015     glw::GLuint m_vao_id;
1016     glw::GLuint m_view_to_id;
1017     glw::GLuint m_view_view_to_id;
1018     glw::GLuint m_vs_id;
1019 
1020     const glw::GLuint m_texture_height;
1021     const glw::GLuint m_texture_n_levels;
1022     const glw::GLuint m_texture_width;
1023 
1024     std::vector<_norm_vec4> m_mipmap_colors;
1025 };
1026 
1027 /** Group class for texture view conformance tests */
1028 class TextureViewTests : public deqp::TestCaseGroup
1029 {
1030 public:
1031     /* Public methods */
1032     TextureViewTests(deqp::Context &context);
~TextureViewTests()1033     virtual ~TextureViewTests()
1034     {
1035     }
1036 
1037     virtual void init(void);
1038 
1039 private:
1040     /* Private methods */
1041     TextureViewTests(const TextureViewTests &);
1042     TextureViewTests &operator=(const TextureViewTests &);
1043 };
1044 
1045 } // namespace gl4cts
1046 
1047 #endif // _GL4CTEXTUREVIEWTESTS_HPP
1048