xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  */ /*!
26  * \file  gl4cSparseTexture2Tests.cpp
27  * \brief Conformance tests for the GL_ARB_sparse_texture2 functionality.
28  */ /*-------------------------------------------------------------------*/
29 
30 #include "gl4cSparseTexture2Tests.hpp"
31 #include "deStringUtil.hpp"
32 #include "gl4cSparseTextureTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
38 
39 #include <cmath>
40 #include <stdio.h>
41 #include <string.h>
42 #include <vector>
43 
44 using namespace glw;
45 using namespace glu;
46 
47 namespace gl4cts
48 {
49 
50 const char *st2_compute_textureFill = "#version 430 core\n"
51                                       "\n"
52                                       "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
53                                       "\n"
54                                       "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n"
55                                       "\n"
56                                       "void main()\n"
57                                       "{\n"
58                                       "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
59                                       "    memoryBarrier();\n"
60                                       "    <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
61                                       "    imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
62                                       "}\n";
63 
64 const char *st2_compute_textureVerify = "#version 430 core\n"
65                                         "\n"
66                                         "#extension GL_ARB_sparse_texture2 : enable\n"
67                                         "\n"
68                                         "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
69                                         "\n"
70                                         "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n"
71                                         "layout (location = 2, <FORMAT>) readonly uniform <INPUT_TYPE> uni_in_image;\n"
72                                         "\n"
73                                         "void main()\n"
74                                         "{\n"
75                                         "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
76                                         "    memoryBarrier();\n"
77                                         "    highp <RETURN_TYPE> color,\n"
78                                         "                        expected,\n"
79                                         "                        epsilon;\n"
80                                         "    color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
81                                         "    expected = <RETURN_TYPE><RESULT_EXPECTED>;\n"
82                                         "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
83                                         "\n"
84                                         "    if (all(lessThanEqual(color, expected + epsilon)) &&\n"
85                                         "        all(greaterThanEqual(color, expected - epsilon)))\n"
86                                         "    {\n"
87                                         "        imageStore(uni_out_image, point, uvec4(255));\n"
88                                         "    }\n"
89                                         "    else {\n"
90                                         "        imageStore(uni_out_image, point, uvec4(0));\n"
91                                         "    }\n"
92                                         "}\n";
93 
94 const char *st2_compute_atomicVerify = "#version 430 core\n"
95                                        "\n"
96                                        "#extension GL_ARB_sparse_texture2 : enable\n"
97                                        "\n"
98                                        "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
99                                        "\n"
100                                        "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out_image;\n"
101                                        "layout (location = 2, <FORMAT>) uniform <INPUT_TYPE> uni_in_image;\n"
102                                        "\n"
103                                        "layout (location = 3) uniform int widthCommitted;\n"
104                                        "\n"
105                                        "void main()\n"
106                                        "{\n"
107                                        "    <POINT_TYPE> point,\n"
108                                        "                 offset;\n"
109                                        "    point = <POINT_TYPE>(<POINT_DEF>);\n"
110                                        "    offset = <POINT_TYPE>(0);\n"
111                                        "    offset.x = widthCommitted;\n"
112                                        "    memoryBarrier();\n"
113                                        "    if (point.x >= widthCommitted) {\n"
114                                        "        uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n"
115                                        "        <DATA_TYPE> value = 127;\n"
116                                        "        if (index == 0)\n"
117                                        "            value = imageAtomicExchange(uni_in_image, point<SAMPLE_DEF>,\n"
118                                        "                                        <DATA_TYPE>(0x0F));\n"
119                                        "        else if (index == 1)\n"
120                                        "            value = imageAtomicCompSwap(uni_in_image, point<SAMPLE_DEF>,\n"
121                                        "                                        <DATA_TYPE>(0), <DATA_TYPE>(0x0F));\n"
122                                        "        else if (index == 2)\n"
123                                        "            value = imageAtomicAdd(uni_in_image, point<SAMPLE_DEF>,\n"
124                                        "                                   <DATA_TYPE>(0x0F));\n"
125                                        "        else if (index == 3)\n"
126                                        "            value = imageAtomicAnd(uni_in_image, point<SAMPLE_DEF>,\n"
127                                        "                                   <DATA_TYPE>(0x0F));\n"
128                                        "        else if (index == 4)\n"
129                                        "            value = imageAtomicOr(uni_in_image, point<SAMPLE_DEF>,\n"
130                                        "                                  <DATA_TYPE>(0x0F));\n"
131                                        "        else if (index == 5)\n"
132                                        "            value = imageAtomicXor(uni_in_image, point<SAMPLE_DEF>,\n"
133                                        "                                   <DATA_TYPE>(0x0F));\n"
134                                        "        else if (index == 6)\n"
135                                        "            value = imageAtomicMin(uni_in_image, point<SAMPLE_DEF>,\n"
136                                        "                                   <DATA_TYPE>(0x0F));\n"
137                                        "        else if (index == 7)\n"
138                                        "            value = imageAtomicMax(uni_in_image, point<SAMPLE_DEF>,\n"
139                                        "                                   <DATA_TYPE>(0x0F));\n"
140                                        "\n"
141                                        "        <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
142                                        "\n"
143                                        "        if (value == 0)\n"
144                                        "            imageStore(uni_out_image, point - offset, uvec4(0));\n"
145                                        "        else\n"
146                                        "            imageStore(uni_out_image, point - offset, uvec4(value));\n"
147                                        "\n"
148                                        "        if (color.r == 0)\n"
149                                        "            imageStore(uni_out_image, point, uvec4(0));\n"
150                                        "        else\n"
151                                        "            imageStore(uni_out_image, point, uvec4(1));\n"
152                                        "    }\n"
153                                        "}\n";
154 
155 const char *st2_vertex_drawBuffer = "#version 430 core\n"
156                                     "\n"
157                                     "#extension GL_ARB_sparse_texture2 : enable\n"
158                                     "\n"
159                                     "in vec3 vertex;\n"
160                                     "in vec2 inTexCoord;\n"
161                                     "out vec2 texCoord;\n"
162                                     "\n"
163                                     "void main()\n"
164                                     "{\n"
165                                     "    texCoord = inTexCoord;\n"
166                                     "    gl_Position = vec4(vertex, 1);\n"
167                                     "}\n";
168 
169 const char *st2_fragment_drawBuffer = "#version 430 core\n"
170                                       "\n"
171                                       "#extension GL_ARB_sparse_texture2 : enable\n"
172                                       "\n"
173                                       "layout (location = 1) uniform sampler2D uni_sampler;\n"
174                                       "\n"
175                                       "in vec2 texCoord;\n"
176                                       "out vec4 fragColor;\n"
177                                       "\n"
178                                       "void main()\n"
179                                       "{\n"
180                                       "    fragColor = texture(uni_sampler, texCoord);\n"
181                                       "}\n";
182 
183 const char *st2_compute_extensionCheck = "#version 450 core\n"
184                                          "\n"
185                                          "#extension <EXTENSION> : require\n"
186                                          "\n"
187                                          "#ifndef <EXTENSION>\n"
188                                          "  #error <EXTENSION> not defined\n"
189                                          "#else\n"
190                                          "  #if (<EXTENSION> != 1)\n"
191                                          "    #error <EXTENSION> wrong value\n"
192                                          "  #endif\n"
193                                          "#endif // <EXTENSION>\n"
194                                          "\n"
195                                          "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
196                                          "\n"
197                                          "void main()\n"
198                                          "{\n"
199                                          "}\n";
200 
201 const char *st2_compute_lookupVerify = "#version 450 core\n"
202                                        "\n"
203                                        "#extension GL_ARB_sparse_texture2 : enable\n"
204                                        "#extension GL_ARB_sparse_texture_clamp : enable\n"
205                                        "\n"
206                                        "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
207                                        "\n"
208                                        "layout (location = 1, r8ui) writeonly uniform <OUTPUT_TYPE> uni_out;\n"
209                                        "layout (location = 2<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
210                                        "layout (location = 3) uniform int widthCommitted;\n"
211                                        "\n"
212                                        "void main()\n"
213                                        "{\n"
214                                        "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
215                                        "    <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n"
216                                        "    <ICOORD_TYPE> icoord = <ICOORD_TYPE>(<COORD_DEF>);\n"
217                                        "    <COORD_TYPE> coord = <COORD_TYPE>(<COORD_DEF>) / <COORD_TYPE>(texSize);\n"
218                                        "    <RETURN_TYPE> retValue,\n"
219                                        "                  expValue,\n"
220                                        "                  epsilon;\n"
221                                        "    retValue = <RETURN_TYPE>(0);\n"
222                                        "    expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
223                                        "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
224                                        "\n"
225                                        "<CUBE_MAP_COORD_DEF>\n"
226                                        "<OFFSET_ARRAY_DEF>\n"
227                                        "\n"
228                                        "    ivec2 corner1 = ivec2(1, 1);\n"
229                                        "    ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
230                                        "\n"
231                                        "    int code = <FUNCTION>(uni_in,\n"
232                                        "                          <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
233                                        "                          retValue<COMPONENT_DEF>);\n"
234                                        "    memoryBarrier();\n"
235                                        "\n"
236                                        "    imageStore(uni_out, point, uvec4(255));\n"
237                                        "\n"
238                                        "    if (point.x > corner1.x && point.y > corner1.y &&\n"
239                                        "        point.x < corner2.x && point.y < corner2.y &&\n"
240                                        "        point.x < widthCommitted - 1)\n"
241                                        "    {\n"
242                                        "        if (!sparseTexelsResidentARB(code) ||\n"
243                                        "            any(greaterThan(retValue, expValue + epsilon)) ||\n"
244                                        "            any(lessThan(retValue, expValue - epsilon)))\n"
245                                        "        {\n"
246                                        "            imageStore(uni_out, point, uvec4(0));\n"
247                                        "        }\n"
248                                        "    }\n"
249                                        "\n"
250                                        "    if (point.x > corner1.x && point.y > corner1.y &&\n"
251                                        "        point.x < corner2.x && point.y < corner2.y &&\n"
252                                        "        point.x >= widthCommitted + 1)\n"
253                                        "    {\n"
254                                        "        if (sparseTexelsResidentARB(code))\n"
255                                        "        {\n"
256                                        "            imageStore(uni_out, point, uvec4(0));\n"
257                                        "        }\n"
258                                        "    }\n"
259                                        "}\n";
260 
261 /** Replace all occurance of <token> with <text> in <string>
262  *
263  * @param token           Token string
264  * @param text            String that will be used as replacement for <token>
265  * @param string          String to work on
266  **/
replaceToken(const GLchar * token,const GLchar * text,std::string & string)267 void replaceToken(const GLchar *token, const GLchar *text, std::string &string)
268 {
269     const size_t text_length  = strlen(text);
270     const size_t token_length = strlen(token);
271 
272     size_t token_position;
273     while ((token_position = string.find(token, 0)) != std::string::npos)
274     {
275         string.replace(token_position, token_length, text, text_length);
276     }
277 }
278 
279 /** Constructor.
280  *
281  *  @param context     Rendering context
282  */
ShaderExtensionTestCase(deqp::Context & context,const std::string extension)283 ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context &context, const std::string extension)
284     : TestCase(context, "ShaderExtension", "Verifies if extension is available for GLSL")
285     , mExtension(extension)
286 {
287     /* Left blank intentionally */
288 }
289 
290 /** Executes test iteration.
291  *
292  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
293  */
iterate()294 tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate()
295 {
296     if (!m_context.getContextInfo().isExtensionSupported(mExtension.c_str()))
297     {
298         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
299         return STOP;
300     }
301 
302     const Functions &gl = m_context.getRenderContext().getFunctions();
303 
304     std::string shader = st2_compute_extensionCheck;
305     replaceToken("<EXTENSION>", mExtension.c_str(), shader);
306 
307     ProgramSources sources;
308     sources << ComputeSource(shader);
309     ShaderProgram program(gl, sources);
310 
311     if (!program.isOk())
312     {
313         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
314         m_testCtx.getLog() << tcu::TestLog::Message << "Checking shader preprocessor directives failed. Source:\n"
315                            << shader.c_str() << "InfoLog:\n"
316                            << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
317                            << tcu::TestLog::EndMessage;
318         return STOP;
319     }
320 
321     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
322     return STOP;
323 }
324 
325 /** Constructor.
326  *
327  *  @param context     Rendering context
328  */
StandardPageSizesTestCase(deqp::Context & context)329 StandardPageSizesTestCase::StandardPageSizesTestCase(deqp::Context &context)
330     : TestCase(context, "StandardPageSizesTestCase",
331                "Verifies if values returned by GetInternalFormativ query matches Standard Virtual Page Sizes")
332 {
333     /* Left blank intentionally */
334 }
335 
336 /** Stub init method */
init()337 void StandardPageSizesTestCase::init()
338 {
339     mSupportedTargets.push_back(GL_TEXTURE_1D);
340     mSupportedTargets.push_back(GL_TEXTURE_1D_ARRAY);
341     mSupportedTargets.push_back(GL_TEXTURE_2D);
342     mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
343     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
344     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
345     mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
346     mSupportedTargets.push_back(GL_TEXTURE_BUFFER);
347     mSupportedTargets.push_back(GL_RENDERBUFFER);
348 
349     mStandardVirtualPageSizesTable[GL_R8]             = PageSizeStruct(256, 256, 1);
350     mStandardVirtualPageSizesTable[GL_R8_SNORM]       = PageSizeStruct(256, 256, 1);
351     mStandardVirtualPageSizesTable[GL_R8I]            = PageSizeStruct(256, 256, 1);
352     mStandardVirtualPageSizesTable[GL_R8UI]           = PageSizeStruct(256, 256, 1);
353     mStandardVirtualPageSizesTable[GL_R16]            = PageSizeStruct(256, 128, 1);
354     mStandardVirtualPageSizesTable[GL_R16_SNORM]      = PageSizeStruct(256, 128, 1);
355     mStandardVirtualPageSizesTable[GL_RG8]            = PageSizeStruct(256, 128, 1);
356     mStandardVirtualPageSizesTable[GL_RG8_SNORM]      = PageSizeStruct(256, 128, 1);
357     mStandardVirtualPageSizesTable[GL_RGB565]         = PageSizeStruct(256, 128, 1);
358     mStandardVirtualPageSizesTable[GL_R16F]           = PageSizeStruct(256, 128, 1);
359     mStandardVirtualPageSizesTable[GL_R16I]           = PageSizeStruct(256, 128, 1);
360     mStandardVirtualPageSizesTable[GL_R16UI]          = PageSizeStruct(256, 128, 1);
361     mStandardVirtualPageSizesTable[GL_RG8I]           = PageSizeStruct(256, 128, 1);
362     mStandardVirtualPageSizesTable[GL_RG8UI]          = PageSizeStruct(256, 128, 1);
363     mStandardVirtualPageSizesTable[GL_RG16]           = PageSizeStruct(128, 128, 1);
364     mStandardVirtualPageSizesTable[GL_RG16_SNORM]     = PageSizeStruct(128, 128, 1);
365     mStandardVirtualPageSizesTable[GL_RGBA8]          = PageSizeStruct(128, 128, 1);
366     mStandardVirtualPageSizesTable[GL_RGBA8_SNORM]    = PageSizeStruct(128, 128, 1);
367     mStandardVirtualPageSizesTable[GL_RGB10_A2]       = PageSizeStruct(128, 128, 1);
368     mStandardVirtualPageSizesTable[GL_RGB10_A2UI]     = PageSizeStruct(128, 128, 1);
369     mStandardVirtualPageSizesTable[GL_RG16F]          = PageSizeStruct(128, 128, 1);
370     mStandardVirtualPageSizesTable[GL_R32F]           = PageSizeStruct(128, 128, 1);
371     mStandardVirtualPageSizesTable[GL_R11F_G11F_B10F] = PageSizeStruct(128, 128, 1);
372     mStandardVirtualPageSizesTable[GL_RGB9_E5]        = PageSizeStruct(128, 128, 1);
373     mStandardVirtualPageSizesTable[GL_R32I]           = PageSizeStruct(128, 128, 1);
374     mStandardVirtualPageSizesTable[GL_R32UI]          = PageSizeStruct(128, 128, 1);
375     mStandardVirtualPageSizesTable[GL_RG16I]          = PageSizeStruct(128, 128, 1);
376     mStandardVirtualPageSizesTable[GL_RG16UI]         = PageSizeStruct(128, 128, 1);
377     mStandardVirtualPageSizesTable[GL_RGBA8I]         = PageSizeStruct(128, 128, 1);
378     mStandardVirtualPageSizesTable[GL_RGBA8UI]        = PageSizeStruct(128, 128, 1);
379     mStandardVirtualPageSizesTable[GL_RGBA16]         = PageSizeStruct(128, 64, 1);
380     mStandardVirtualPageSizesTable[GL_RGBA16_SNORM]   = PageSizeStruct(128, 64, 1);
381     mStandardVirtualPageSizesTable[GL_RGBA16F]        = PageSizeStruct(128, 64, 1);
382     mStandardVirtualPageSizesTable[GL_RG32F]          = PageSizeStruct(128, 64, 1);
383     mStandardVirtualPageSizesTable[GL_RG32I]          = PageSizeStruct(128, 64, 1);
384     mStandardVirtualPageSizesTable[GL_RG32UI]         = PageSizeStruct(128, 64, 1);
385     mStandardVirtualPageSizesTable[GL_RGBA16I]        = PageSizeStruct(128, 64, 1);
386     mStandardVirtualPageSizesTable[GL_RGBA16UI]       = PageSizeStruct(128, 64, 1);
387     mStandardVirtualPageSizesTable[GL_RGBA32F]        = PageSizeStruct(64, 64, 1);
388     mStandardVirtualPageSizesTable[GL_RGBA32I]        = PageSizeStruct(64, 64, 1);
389     mStandardVirtualPageSizesTable[GL_RGBA32UI]       = PageSizeStruct(64, 64, 1);
390 }
391 
392 /** Executes test iteration.
393  *
394  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
395  */
iterate()396 tcu::TestNode::IterateResult StandardPageSizesTestCase::iterate()
397 {
398     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
399     {
400         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
401         return STOP;
402     }
403 
404     const Functions &gl = m_context.getRenderContext().getFunctions();
405 
406     m_testCtx.getLog() << tcu::TestLog::Message << "Testing getInternalformativ" << tcu::TestLog::EndMessage;
407 
408     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
409          ++iter)
410     {
411         const GLint &target = *iter;
412 
413         for (std::map<glw::GLint, PageSizeStruct>::const_iterator formIter = mStandardVirtualPageSizesTable.begin();
414              formIter != mStandardVirtualPageSizesTable.end(); ++formIter)
415         {
416             const PageSizePair &format = *formIter;
417             const PageSizeStruct &page = format.second;
418 
419             if (target == GL_TEXTURE_BUFFER)
420             {
421                 /* filter out invalid texture buffer formats according to ARB_texture_buffer_object */
422                 switch (format.first)
423                 {
424                 case GL_RGB10_A2:
425                 case GL_RGB10_A2UI:
426                 case GL_R11F_G11F_B10F:
427                 case GL_RGB9_E5:
428                 case GL_RGB565:
429                 case GL_R8_SNORM:
430                 case GL_RG8_SNORM:
431                 case GL_RGBA8_SNORM:
432                 case GL_R16_SNORM:
433                 case GL_RG16_SNORM:
434                 case GL_RGBA16_SNORM:
435                     continue;
436                 default:
437                     break;
438                 }
439             }
440 
441             GLint pageSizeX;
442             GLint pageSizeY;
443             GLint pageSizeZ;
444             SparseTextureUtils::getTexturePageSizes(gl, target, format.first, pageSizeX, pageSizeY, pageSizeZ);
445 
446             if (pageSizeX != page.xSize || pageSizeY != page.ySize || pageSizeZ != page.zSize)
447             {
448                 m_testCtx.getLog() << tcu::TestLog::Message << "Standard Virtual Page Size mismatch, target: " << target
449                                    << ", format: " << format.first << ", returned: " << pageSizeX << "/" << pageSizeY
450                                    << "/" << pageSizeZ << ", expected: " << page.xSize << "/" << page.ySize << "/"
451                                    << page.zSize << tcu::TestLog::EndMessage;
452 
453                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
454                 return STOP;
455             }
456         }
457     }
458 
459     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
460 
461     return STOP;
462 }
463 
464 /** Constructor.
465  *
466  *  @param context     Rendering context
467  */
SparseTexture2AllocationTestCase(deqp::Context & context)468 SparseTexture2AllocationTestCase::SparseTexture2AllocationTestCase(deqp::Context &context)
469     : SparseTextureAllocationTestCase(context, "SparseTexture2Allocation",
470                                       "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture2")
471 {
472     /* Left blank intentionally */
473 }
474 
475 /** Initializes the test group contents. */
init()476 void SparseTexture2AllocationTestCase::init()
477 {
478     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
479     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
480 
481     mFullArrayTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
482 
483     mSupportedInternalFormats.push_back(GL_R8);
484     mSupportedInternalFormats.push_back(GL_R8_SNORM);
485     mSupportedInternalFormats.push_back(GL_R16);
486     mSupportedInternalFormats.push_back(GL_R16_SNORM);
487     mSupportedInternalFormats.push_back(GL_RG8);
488     mSupportedInternalFormats.push_back(GL_RG8_SNORM);
489     mSupportedInternalFormats.push_back(GL_RG16);
490     mSupportedInternalFormats.push_back(GL_RG16_SNORM);
491     mSupportedInternalFormats.push_back(GL_RGB565);
492     mSupportedInternalFormats.push_back(GL_RGBA8);
493     mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
494     mSupportedInternalFormats.push_back(GL_RGB10_A2);
495     mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
496     mSupportedInternalFormats.push_back(GL_RGBA16);
497     mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
498     mSupportedInternalFormats.push_back(GL_R16F);
499     mSupportedInternalFormats.push_back(GL_RG16F);
500     mSupportedInternalFormats.push_back(GL_RGBA16F);
501     mSupportedInternalFormats.push_back(GL_R32F);
502     mSupportedInternalFormats.push_back(GL_RG32F);
503     mSupportedInternalFormats.push_back(GL_RGBA32F);
504     mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
505     // RGB9_E5 isn't color renderable, and thus isn't valid for multisample
506     // textures.
507     //mSupportedInternalFormats.push_back(GL_RGB9_E5);
508     mSupportedInternalFormats.push_back(GL_R8I);
509     mSupportedInternalFormats.push_back(GL_R8UI);
510     mSupportedInternalFormats.push_back(GL_R16I);
511     mSupportedInternalFormats.push_back(GL_R16UI);
512     mSupportedInternalFormats.push_back(GL_R32I);
513     mSupportedInternalFormats.push_back(GL_R32UI);
514     mSupportedInternalFormats.push_back(GL_RG8I);
515     mSupportedInternalFormats.push_back(GL_RG8UI);
516     mSupportedInternalFormats.push_back(GL_RG16I);
517     mSupportedInternalFormats.push_back(GL_RG16UI);
518     mSupportedInternalFormats.push_back(GL_RG32I);
519     mSupportedInternalFormats.push_back(GL_RG32UI);
520     mSupportedInternalFormats.push_back(GL_RGBA8I);
521     mSupportedInternalFormats.push_back(GL_RGBA8UI);
522     mSupportedInternalFormats.push_back(GL_RGBA16I);
523     mSupportedInternalFormats.push_back(GL_RGBA16UI);
524     mSupportedInternalFormats.push_back(GL_RGBA32I);
525 }
526 
527 /** Executes test iteration.
528  *
529  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
530  */
iterate()531 tcu::TestNode::IterateResult SparseTexture2AllocationTestCase::iterate()
532 {
533     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
534     {
535         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
536         return STOP;
537     }
538 
539     return SparseTextureAllocationTestCase::iterate();
540 }
541 
542 /** Constructor.
543  *
544  *  @param context     Rendering context
545  *  @param name        Test name
546  *  @param description Test description
547  */
SparseTexture2CommitmentTestCase(deqp::Context & context,const char * name,const char * description)548 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context &context, const char *name,
549                                                                    const char *description)
550     : SparseTextureCommitmentTestCase(context, name, description)
551 {
552     /* Left blank intentionally */
553 }
554 
555 /** Constructor.
556  *
557  *  @param context     Rendering context
558  */
SparseTexture2CommitmentTestCase(deqp::Context & context)559 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context &context)
560     : SparseTextureCommitmentTestCase(
561           context, "SparseTexture2Commitment",
562           "Verifies glTexPageCommitmentARB functionality added by ARB_sparse_texture2 extension")
563 {
564     /* Left blank intentionally */
565 }
566 
567 /** Initializes the test group contents. */
init()568 void SparseTexture2CommitmentTestCase::init()
569 {
570     SparseTextureCommitmentTestCase::init();
571 
572     //Verify all targets once again and multisample targets as it was added in ARB_sparse_texture2 extension
573     mSupportedTargets.clear();
574     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
575     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
576 }
577 
578 /** Executes test iteration.
579  *
580  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
581  */
iterate()582 tcu::TestNode::IterateResult SparseTexture2CommitmentTestCase::iterate()
583 {
584     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
585     {
586         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
587         return STOP;
588     }
589 
590     return SparseTextureCommitmentTestCase::iterate();
591 }
592 
593 /** Create set of token strings fit to texture verifying shader
594  *
595  * @param target     Target for which texture is binded
596  * @param format     Texture internal format
597  * @param sample     Texture sample number
598 
599  * @return target    Structure of token strings
600  */
createShaderTokens(GLint target,GLint verifyTarget,GLint format,GLint sample,const std::string outputBase,const std::string inputBase)601 SparseTexture2CommitmentTestCase::TokenStrings SparseTexture2CommitmentTestCase::createShaderTokens(
602     GLint target, GLint verifyTarget, GLint format, GLint sample, const std::string outputBase,
603     const std::string inputBase)
604 {
605     TokenStrings s;
606     std::string prefix;
607 
608     if (format == GL_R8)
609     {
610         s.format         = "r8";
611         s.resultExpected = "(1, 0, 0, 1)";
612         s.resultDefault  = "(0, 0, 0, 1)";
613     }
614     else if (format == GL_R8_SNORM)
615     {
616         s.format         = "r8_snorm";
617         s.resultExpected = "(1, 0, 0, 1)";
618         s.resultDefault  = "(0, 0, 0, 1)";
619     }
620     else if (format == GL_R16)
621     {
622         s.format         = "r16";
623         s.resultExpected = "(1, 0, 0, 1)";
624         s.resultDefault  = "(0, 0, 0, 1)";
625     }
626     else if (format == GL_R16_SNORM)
627     {
628         s.format         = "r16_snorm";
629         s.resultExpected = "(1, 0, 0, 1)";
630         s.resultDefault  = "(0, 0, 0, 1)";
631     }
632     else if (format == GL_RG8)
633     {
634         s.format         = "rg8";
635         s.resultExpected = "(1, 1, 0, 1)";
636         s.resultDefault  = "(0, 0, 0, 1)";
637     }
638     else if (format == GL_RG8_SNORM)
639     {
640         s.format         = "rg8_snorm";
641         s.resultExpected = "(1, 1, 0, 1)";
642         s.resultDefault  = "(0, 0, 0, 1)";
643     }
644     else if (format == GL_RG16)
645     {
646         s.format         = "rg16";
647         s.resultExpected = "(1, 1, 0, 1)";
648         s.resultDefault  = "(0, 0, 0, 1)";
649     }
650     else if (format == GL_RG16_SNORM)
651     {
652         s.format         = "rg16_snorm";
653         s.resultExpected = "(1, 1, 0, 1)";
654         s.resultDefault  = "(0, 0, 0, 1)";
655     }
656     else if (format == GL_RGBA8)
657     {
658         s.format         = "rgba8";
659         s.resultExpected = "(1, 1, 1, 1)";
660         s.resultDefault  = "(0, 0, 0, 0)";
661     }
662     else if (format == GL_RGBA8_SNORM)
663     {
664         s.format         = "rgba8_snorm";
665         s.resultExpected = "(1, 1, 1, 1)";
666         s.resultDefault  = "(0, 0, 0, 0)";
667     }
668     else if (format == GL_RGB10_A2)
669     {
670         s.format         = "rgb10_a2";
671         s.resultExpected = "(1, 1, 1, 1)";
672         s.resultDefault  = "(0, 0, 0, 0)";
673     }
674     else if (format == GL_RGB10_A2UI)
675     {
676         s.format         = "rgb10_a2ui";
677         s.resultExpected = "(1, 1, 1, 1)";
678         s.resultDefault  = "(0, 0, 0, 0)";
679         prefix           = "u";
680     }
681     else if (format == GL_RGBA16)
682     {
683         s.format         = "rgba16";
684         s.resultExpected = "(1, 1, 1, 1)";
685         s.resultDefault  = "(0, 0, 0, 0)";
686     }
687     else if (format == GL_RGBA16_SNORM)
688     {
689         s.format         = "rgba16_snorm";
690         s.resultExpected = "(1, 1, 1, 1)";
691         s.resultDefault  = "(0, 0, 0, 0)";
692     }
693     else if (format == GL_R16F)
694     {
695         s.format         = "r16f";
696         s.resultExpected = "(1, 0, 0, 1)";
697         s.resultDefault  = "(0, 0, 0, 1)";
698     }
699     else if (format == GL_RG16F)
700     {
701         s.format         = "rg16f";
702         s.resultExpected = "(1, 1, 0, 1)";
703         s.resultDefault  = "(0, 0, 0, 1)";
704     }
705     else if (format == GL_RGBA16F)
706     {
707         s.format         = "rgba16f";
708         s.resultExpected = "(1, 1, 1, 1)";
709         s.resultDefault  = "(0, 0, 0, 0)";
710     }
711     else if (format == GL_R32F)
712     {
713         s.format         = "r32f";
714         s.resultExpected = "(1, 0, 0, 1)";
715         s.resultDefault  = "(0, 0, 0, 1)";
716     }
717     else if (format == GL_RG32F)
718     {
719         s.format         = "rg32f";
720         s.resultExpected = "(1, 1, 0, 1)";
721         s.resultDefault  = "(0, 0, 0, 1)";
722     }
723     else if (format == GL_RGBA32F)
724     {
725         s.format         = "rgba32f";
726         s.resultExpected = "(1, 1, 1, 1)";
727         s.resultDefault  = "(0, 0, 0, 0)";
728     }
729     else if (format == GL_R11F_G11F_B10F)
730     {
731         s.format         = "r11f_g11f_b10f";
732         s.resultExpected = "(1, 1, 1, 1)";
733         s.resultDefault  = "(0, 0, 0, 1)";
734     }
735     else if (format == GL_R8I)
736     {
737         s.format         = "r8i";
738         s.resultExpected = "(1, 0, 0, 1)";
739         s.resultDefault  = "(0, 0, 0, 1)";
740         prefix           = "i";
741     }
742     else if (format == GL_R8UI)
743     {
744         s.format         = "r8ui";
745         s.resultExpected = "(1, 0, 0, 1)";
746         s.resultDefault  = "(0, 0, 0, 1)";
747         prefix           = "u";
748     }
749     else if (format == GL_R16I)
750     {
751         s.format         = "r16i";
752         s.resultExpected = "(1, 0, 0, 1)";
753         s.resultDefault  = "(0, 0, 0, 1)";
754         prefix           = "i";
755     }
756     else if (format == GL_R16UI)
757     {
758         s.format         = "r16ui";
759         s.resultExpected = "(1, 0, 0, 1)";
760         s.resultDefault  = "(0, 0, 0, 1)";
761         prefix           = "u";
762     }
763     else if (format == GL_R32I)
764     {
765         s.format         = "r32i";
766         s.resultExpected = "(1, 0, 0, 1)";
767         s.resultDefault  = "(0, 0, 0, 1)";
768         prefix           = "i";
769     }
770     else if (format == GL_R32UI)
771     {
772         s.format         = "r32ui";
773         s.resultExpected = "(1, 0, 0, 1)";
774         s.resultDefault  = "(0, 0, 0, 1)";
775         prefix           = "u";
776     }
777     else if (format == GL_RG8I)
778     {
779         s.format         = "rg8i";
780         s.resultExpected = "(1, 1, 0, 1)";
781         s.resultDefault  = "(0, 0, 0, 1)";
782         prefix           = "i";
783     }
784     else if (format == GL_RG8UI)
785     {
786         s.format         = "rg8ui";
787         s.resultExpected = "(1, 1, 0, 1)";
788         s.resultDefault  = "(0, 0, 0, 1)";
789         prefix           = "u";
790     }
791     else if (format == GL_RG16I)
792     {
793         s.format         = "rg16i";
794         s.resultExpected = "(1, 1, 0, 1)";
795         s.resultDefault  = "(0, 0, 0, 1)";
796         prefix           = "i";
797     }
798     else if (format == GL_RG16UI)
799     {
800         s.format         = "rg16ui";
801         s.resultExpected = "(1, 1, 0, 1)";
802         s.resultDefault  = "(0, 0, 0, 1)";
803         prefix           = "u";
804     }
805     else if (format == GL_RG32I)
806     {
807         s.format         = "rg32i";
808         s.resultExpected = "(1, 1, 0, 1)";
809         s.resultDefault  = "(0, 0, 0, 1)";
810         prefix           = "i";
811     }
812     else if (format == GL_RG32UI)
813     {
814         s.format         = "rg32ui";
815         s.resultExpected = "(1, 1, 0, 1)";
816         s.resultDefault  = "(0, 0, 0, 1)";
817         prefix           = "u";
818     }
819     else if (format == GL_RGBA8I)
820     {
821         s.format         = "rgba8i";
822         s.resultExpected = "(1, 1, 1, 1)";
823         s.resultDefault  = "(0, 0, 0, 0)";
824         prefix           = "i";
825     }
826     else if (format == GL_RGBA8UI)
827     {
828         s.format         = "rgba8ui";
829         s.resultExpected = "(1, 1, 1, 1)";
830         s.resultDefault  = "(0, 0, 0, 0)";
831         prefix           = "u";
832     }
833     else if (format == GL_RGBA16I)
834     {
835         s.format         = "rgba16i";
836         s.resultExpected = "(1, 1, 1, 1)";
837         s.resultDefault  = "(0, 0, 0, 0)";
838         prefix           = "i";
839     }
840     else if (format == GL_RGBA16UI)
841     {
842         s.format         = "rgba16ui";
843         s.resultExpected = "(1, 1, 1, 1)";
844         s.resultDefault  = "(0, 0, 0, 0)";
845         prefix           = "u";
846     }
847     else if (format == GL_RGBA32I)
848     {
849         s.format         = "rgba32i";
850         s.resultExpected = "(1, 1, 1, 1)";
851         s.resultDefault  = "(0, 0, 0, 0)";
852         prefix           = "i";
853     }
854     else if (format == GL_DEPTH_COMPONENT16)
855     {
856         s.format         = "r16";
857         s.resultExpected = "(1, 0, 0, 0)";
858         s.resultDefault  = "(0, 0, 0, 0)";
859     }
860 
861     s.returnType = prefix + "vec4";
862     s.outputType = "u" + outputBase + "2D";
863     s.inputType  = prefix + inputBase + "2D";
864     s.pointType  = "ivec2";
865     s.pointDef   = "gl_WorkGroupID.x, gl_WorkGroupID.y";
866 
867     if (s.returnType == "vec4")
868         s.epsilon = "0.008";
869     else
870         s.epsilon = "0";
871 
872     if (target == GL_TEXTURE_1D)
873     {
874         s.inputType = prefix + inputBase + "1D";
875         s.pointType = "int";
876         s.pointDef  = "gl_WorkGroupID.x";
877     }
878     else if (target == GL_TEXTURE_1D_ARRAY)
879     {
880         s.inputType = prefix + inputBase + "1DArray";
881         s.pointType = "ivec2";
882         s.pointDef  = "gl_WorkGroupID.x, gl_WorkGroupID.z";
883     }
884     else if (target == GL_TEXTURE_2D_ARRAY)
885     {
886         s.inputType = prefix + inputBase + "2DArray";
887         s.pointType = "ivec3";
888         s.pointDef  = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
889     }
890     else if (target == GL_TEXTURE_3D)
891     {
892         s.outputType = "u" + outputBase + "2DArray";
893         s.inputType  = prefix + inputBase + "3D";
894         s.pointType  = "ivec3";
895         s.pointDef   = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
896     }
897     else if (target == GL_TEXTURE_CUBE_MAP)
898     {
899         s.inputType = prefix + inputBase + "Cube";
900         s.pointType = "ivec3";
901         s.pointDef  = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6";
902     }
903     else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
904     {
905         s.inputType = prefix + inputBase + "CubeArray";
906         s.pointType = "ivec3";
907         s.pointDef  = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
908     }
909     else if (target == GL_TEXTURE_RECTANGLE)
910     {
911         s.inputType = prefix + inputBase + "2DRect";
912     }
913     else if (target == GL_TEXTURE_2D_MULTISAMPLE)
914     {
915         s.inputType = prefix + inputBase + "2DMS";
916         s.sampleDef = ", " + de::toString(sample);
917     }
918     else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
919     {
920         s.inputType = prefix + inputBase + "2DMSArray";
921         s.pointType = "ivec3";
922         s.pointDef  = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
923         s.sampleDef = ", " + de::toString(sample);
924     }
925     if (verifyTarget == GL_TEXTURE_2D)
926     {
927         s.outputType = "u" + outputBase + "2D";
928     }
929     else
930     {
931         s.outputType = "u" + outputBase + "2DArray";
932     }
933 
934     return s;
935 }
936 
937 /** Check if specific combination of target and format is allowed
938  *
939  * @param target       Target for which texture is binded
940  * @param format       Texture internal format
941  *
942  * @return Returns true if target/format combination is allowed, false otherwise.
943  */
caseAllowed(GLint target,GLint format)944 bool SparseTexture2CommitmentTestCase::caseAllowed(GLint target, GLint format)
945 {
946     // Multisample textures are filling with data and verifying using compute shader.
947     // As shaders do not support some texture formats it is necessary to exclude them.
948     if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) &&
949         (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
950     {
951         return false;
952     }
953 
954     return true;
955 }
956 
957 /** Allocating sparse texture memory using texStorage* function
958  *
959  * @param gl           GL API functions
960  * @param target       Target for which texture is binded
961  * @param format       Texture internal format
962  * @param texture      Texture object
963  * @param levels       Texture mipmaps level
964  *
965  * @return Returns true if no error occurred, otherwise throws an exception.
966  */
sparseAllocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)967 bool SparseTexture2CommitmentTestCase::sparseAllocateTexture(const Functions &gl, GLint target, GLint format,
968                                                              GLuint &texture, GLint levels)
969 {
970     mLog << "Sparse Allocate [levels: " << levels << "] - ";
971 
972     prepareTexture(gl, target, format, texture);
973 
974     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
975     GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");
976 
977     //GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
978     if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
979         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
980     {
981         mState.levels = levels;
982     }
983     else
984         mState.levels = 1;
985 
986     if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
987     {
988         mState.samples = 1;
989     }
990     else
991         mState.samples = 2;
992 
993     Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
994                      mState.depth);
995     GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
996 
997     return true;
998 }
999 
1000 /** Allocating texture memory using texStorage* function
1001  *
1002  * @param gl           GL API functions
1003  * @param target       Target for which texture is binded
1004  * @param format       Texture internal format
1005  * @param texture      Texture object
1006  * @param levels       Texture mipmaps level
1007  *
1008  * @return Returns true if no error occurred, otherwise throws an exception.
1009  */
allocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)1010 bool SparseTexture2CommitmentTestCase::allocateTexture(const Functions &gl, GLint target, GLint format, GLuint &texture,
1011                                                        GLint levels)
1012 {
1013     mLog << "Allocate [levels: " << levels << "] - ";
1014 
1015     prepareTexture(gl, target, format, texture);
1016 
1017     // GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
1018     if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
1019         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1020     {
1021         mState.levels = levels;
1022     }
1023     else
1024         mState.levels = 1;
1025 
1026     // GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can use multiple samples
1027     if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1028     {
1029         mState.samples = 1;
1030     }
1031     else
1032         mState.samples = 2;
1033 
1034     Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
1035                      mState.depth);
1036     GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
1037 
1038     return true;
1039 }
1040 
1041 /** Writing data to generated texture
1042  *
1043  * @param gl           GL API functions
1044  * @param target       Target for which texture is binded
1045  * @param format       Texture internal format
1046  * @param texture      Texture object
1047  *
1048  * @return Returns true if no error occurred, otherwise throws an exception.
1049  */
writeDataToTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1050 bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions &gl, GLint target, GLint format,
1051                                                           GLuint &texture, GLint level)
1052 {
1053     mLog << "Fill Texture [level: " << level << "] - ";
1054 
1055     if (level > mState.levels - 1)
1056         TCU_FAIL("Invalid level");
1057 
1058     TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1059 
1060     GLint width;
1061     GLint height;
1062     GLint depth;
1063     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1064 
1065     if (width > 0 && height > 0 && depth >= mState.minDepth)
1066     {
1067         if (target == GL_TEXTURE_CUBE_MAP)
1068             depth = depth * 6;
1069 
1070         GLint texSize = width * height * depth * mState.format.getPixelSize();
1071 
1072         std::vector<GLubyte> vecData;
1073         vecData.resize(texSize);
1074         GLubyte *data = vecData.data();
1075 
1076         deMemset(data, 255, texSize);
1077 
1078         if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1079         {
1080             Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
1081                               transferFormat.dataType, (GLvoid *)data);
1082             GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
1083         }
1084         // For multisample texture use compute shader to store image data
1085         else
1086         {
1087             for (GLint sample = 0; sample < mState.samples; ++sample)
1088             {
1089                 std::string shader = st2_compute_textureFill;
1090 
1091                 // Adjust shader source to texture format
1092                 GLint verifyTarget;
1093                 if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
1094                     verifyTarget = GL_TEXTURE_2D;
1095                 else
1096                     verifyTarget = GL_TEXTURE_2D_ARRAY;
1097                 TokenStrings s = createShaderTokens(target, verifyTarget, format, sample);
1098 
1099                 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1100                 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1101                 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1102                 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1103                 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1104                 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1105 
1106                 ProgramSources sources;
1107                 sources << ComputeSource(shader);
1108 
1109                 // Build and run shader
1110                 ShaderProgram program(m_context.getRenderContext(), sources);
1111                 if (program.isOk())
1112                 {
1113                     gl.useProgram(program.getProgram());
1114                     GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1115                     gl.bindImageTexture(0 /* unit */, texture, level /* level */, depth > 1 /* layered */,
1116                                         0 /* layer */, GL_WRITE_ONLY, format);
1117                     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1118                     gl.uniform1i(1, 0 /* image_unit */);
1119                     GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1120                     gl.dispatchCompute(width, height, depth);
1121                     GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1122                     gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1123                     GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1124                 }
1125                 else
1126                 {
1127                     mLog << "Compute shader compilation failed (writing) for target: " << target
1128                          << ", format: " << format << ", sample: " << sample
1129                          << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1130                          << ", shaderSource: " << shader.c_str() << " - ";
1131                 }
1132             }
1133         }
1134     }
1135 
1136     return true;
1137 }
1138 
1139 /** Verify if data stored in texture is as expected
1140  *
1141  * @param gl           GL API functions
1142  * @param target       Target for which texture is binded
1143  * @param format       Texture internal format
1144  * @param texture      Texture object
1145  * @param level        Texture mipmap level
1146  *
1147  * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1148  */
verifyTextureData(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1149 bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions &gl, GLint target, GLint format,
1150                                                          GLuint &texture, GLint level)
1151 {
1152     mLog << "Verify Texture [level: " << level << "] - ";
1153 
1154     if (level > mState.levels - 1)
1155         TCU_FAIL("Invalid level");
1156 
1157     TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1158 
1159     GLint width;
1160     GLint height;
1161     GLint depth;
1162     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1163 
1164     //Committed region is limited to 1/2 of width
1165     GLint widthCommitted = width / 2;
1166 
1167     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1168         return true;
1169 
1170     bool result = true;
1171 
1172     if (target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1173         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1174     {
1175         GLint texSize = width * height * depth * mState.format.getPixelSize();
1176 
1177         std::vector<GLubyte> vecExpData;
1178         std::vector<GLubyte> vecOutData;
1179         vecExpData.resize(texSize);
1180         vecOutData.resize(texSize);
1181         GLubyte *exp_data = vecExpData.data();
1182         GLubyte *out_data = vecOutData.data();
1183 
1184         deMemset(exp_data, 255, texSize);
1185         deMemset(out_data, 127, texSize);
1186 
1187         Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
1188         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1189 
1190         //Verify only committed region
1191         for (GLint x = 0; x < widthCommitted; ++x)
1192             for (GLint y = 0; y < height; ++y)
1193                 for (GLint z = 0; z < depth; ++z)
1194                 {
1195                     int pixelSize          = mState.format.getPixelSize();
1196                     GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
1197                     GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
1198                     if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1199                         result = false;
1200                 }
1201     }
1202     else if (target == GL_TEXTURE_CUBE_MAP)
1203     {
1204         std::vector<GLint> subTargets;
1205 
1206         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1207         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1208         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1209         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1210         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1211         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1212 
1213         GLint texSize = width * height * mState.format.getPixelSize();
1214 
1215         std::vector<GLubyte> vecExpData;
1216         std::vector<GLubyte> vecOutData;
1217         vecExpData.resize(texSize);
1218         vecOutData.resize(texSize);
1219         GLubyte *exp_data = vecExpData.data();
1220         GLubyte *out_data = vecOutData.data();
1221 
1222         deMemset(exp_data, 255, texSize);
1223 
1224         for (size_t i = 0; i < subTargets.size(); ++i)
1225         {
1226             GLint subTarget = subTargets[i];
1227 
1228             mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1229 
1230             deMemset(out_data, 127, texSize);
1231 
1232             Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
1233             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1234 
1235             //Verify only committed region
1236             for (GLint x = 0; x < widthCommitted; ++x)
1237                 for (GLint y = 0; y < height; ++y)
1238                     for (GLint z = 0; z < depth; ++z)
1239                     {
1240                         int pixelSize          = mState.format.getPixelSize();
1241                         GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
1242                         GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
1243                         if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1244                             result = false;
1245                     }
1246 
1247             if (!result)
1248                 break;
1249         }
1250     }
1251     // For multisample texture use compute shader to verify image data
1252     else if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1253     {
1254         GLint texSize = width * height * depth;
1255 
1256         std::vector<GLubyte> vecExpData;
1257         std::vector<GLubyte> vecOutData;
1258         vecExpData.resize(texSize);
1259         vecOutData.resize(texSize);
1260         GLubyte *exp_data = vecExpData.data();
1261         GLubyte *out_data = vecOutData.data();
1262 
1263         deMemset(exp_data, 255, texSize);
1264 
1265         // Create verifying texture
1266         GLint verifyTarget;
1267         if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
1268             verifyTarget = GL_TEXTURE_2D;
1269         else
1270             verifyTarget = GL_TEXTURE_2D_ARRAY;
1271 
1272         GLuint verifyTexture;
1273         Texture::Generate(gl, verifyTexture);
1274         Texture::Bind(gl, verifyTexture, verifyTarget);
1275         Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1276         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1277 
1278         for (int sample = 0; sample < mState.samples; ++sample)
1279         {
1280             deMemset(out_data, 0, texSize);
1281 
1282             Texture::Bind(gl, verifyTexture, verifyTarget);
1283             Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1284                               (GLvoid *)out_data);
1285             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1286 
1287             std::string shader = st2_compute_textureVerify;
1288 
1289             // Adjust shader source to texture format
1290             TokenStrings s = createShaderTokens(target, verifyTarget, format, sample);
1291 
1292             replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1293             replaceToken("<FORMAT>", s.format.c_str(), shader);
1294             replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1295             replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1296             replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1297             replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1298             replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1299             replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1300             replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1301 
1302             ProgramSources sources;
1303             sources << ComputeSource(shader);
1304 
1305             // Build and run shader
1306             ShaderProgram program(m_context.getRenderContext(), sources);
1307             if (program.isOk())
1308             {
1309                 gl.useProgram(program.getProgram());
1310                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1311                 gl.bindImageTexture(0, //unit
1312                                     verifyTexture,
1313                                     0,        //level
1314                                     GL_FALSE, //layered
1315                                     0,        //layer
1316                                     GL_WRITE_ONLY, GL_R8UI);
1317                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1318                 gl.bindImageTexture(1, //unit
1319                                     texture,
1320                                     level,    //level
1321                                     GL_FALSE, //layered
1322                                     0,        //layer
1323                                     GL_READ_ONLY, format);
1324                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1325                 gl.uniform1i(1, 0 /* image_unit */);
1326                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1327                 gl.uniform1i(2, 1 /* image_unit */);
1328                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1329                 gl.dispatchCompute(width, height, depth);
1330                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1331                 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1332                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1333 
1334                 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)out_data);
1335                 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1336 
1337                 //Verify only committed region
1338                 for (GLint x = 0; x < widthCommitted; ++x)
1339                     for (GLint y = 0; y < height; ++y)
1340                         for (GLint z = 0; z < depth; ++z)
1341                         {
1342                             GLubyte *dataRegion    = exp_data + ((x + y * width) + z * width * height);
1343                             GLubyte *outDataRegion = out_data + ((x + y * width) + z * width * height);
1344                             if (dataRegion[0] != outDataRegion[0])
1345                             {
1346                                 m_testCtx.getLog()
1347                                     << tcu::TestLog::Message << mLog.str() << "Error detected at " << x << "," << y
1348                                     << "," << z << " for sample " << sample << ": expected [" << (unsigned)dataRegion[0]
1349                                     << "] got [" << (unsigned)outDataRegion[0] << "]" << tcu::TestLog::EndMessage;
1350                                 result = false;
1351                                 goto out;
1352                             }
1353                         }
1354             }
1355             else
1356             {
1357                 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1358                      << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1359                      << ", shaderSource: " << shader.c_str() << " - ";
1360 
1361                 result = false;
1362             }
1363         }
1364     out:
1365         Texture::Delete(gl, verifyTexture);
1366     }
1367 
1368     return result;
1369 }
1370 
1371 const GLfloat texCoord[] = {
1372     0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1373 };
1374 
1375 const GLfloat vertices[] = {
1376     -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1377 };
1378 
1379 const GLuint indices[] = {0, 1, 2, 1, 2, 3};
1380 
1381 /** Constructor.
1382  *
1383  *  @param context     Rendering context
1384  */
UncommittedRegionsAccessTestCase(deqp::Context & context)1385 UncommittedRegionsAccessTestCase::UncommittedRegionsAccessTestCase(deqp::Context &context)
1386     : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccess",
1387                                        "Verifies if access to uncommitted regions of sparse texture works as expected")
1388 {
1389     /* Left blank intentionally */
1390 }
1391 
1392 /** Stub init method */
init()1393 void UncommittedRegionsAccessTestCase::init()
1394 {
1395     SparseTextureCommitmentTestCase::init();
1396 
1397     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
1398     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
1399 }
1400 
1401 /** Executes test iteration.
1402  *
1403  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1404  */
iterate()1405 tcu::TestNode::IterateResult UncommittedRegionsAccessTestCase::iterate()
1406 {
1407     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
1408     {
1409         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1410         return STOP;
1411     }
1412 
1413     const Functions &gl = m_context.getRenderContext().getFunctions();
1414 
1415     bool result = true;
1416 
1417     GLuint texture;
1418 
1419     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
1420          ++iter)
1421     {
1422         const GLint &target = *iter;
1423 
1424         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1425              formIter != mSupportedInternalFormats.end(); ++formIter)
1426         {
1427             const GLint &format = *formIter;
1428 
1429             if (!caseAllowed(target, format))
1430                 continue;
1431 
1432             mLog.str("");
1433             mLog << "Testing uncommitted regions access for target: " << target << ", format: " << format << " - ";
1434 
1435             sparseAllocateTexture(gl, target, format, texture, 3);
1436             for (int l = 0; l < mState.levels; ++l)
1437             {
1438                 if (commitTexturePage(gl, target, format, texture, l))
1439                 {
1440                     writeDataToTexture(gl, target, format, texture, l);
1441                     result = result && UncommittedReads(gl, target, format, texture, l);
1442                     result = result && UncommittedAtomicOperations(gl, target, format, texture, l);
1443                 }
1444 
1445                 if (!result)
1446                     break;
1447             }
1448 
1449             Texture::Delete(gl, texture);
1450 
1451             if (!result)
1452             {
1453                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1454                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1455                 return STOP;
1456             }
1457         }
1458     }
1459 
1460     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1461     return STOP;
1462 }
1463 
1464 /** Check if reads from uncommitted regions are allowed
1465  *
1466  * @param target       Target for which texture is binded
1467  * @param format       Texture internal format
1468  *
1469  * @return Returns true if allowed, false otherwise.
1470  */
readsAllowed(GLint target,GLint format,bool shaderOnly)1471 bool UncommittedRegionsAccessTestCase::readsAllowed(GLint target, GLint format, bool shaderOnly)
1472 {
1473     DE_UNREF(target);
1474 
1475     if (shaderOnly && (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
1476     {
1477         return false;
1478     }
1479 
1480     return true;
1481 }
1482 
1483 /** Check if atomic operations on uncommitted regions are allowed
1484  *
1485  * @param target       Target for which texture is binded
1486  * @param format       Texture internal format
1487  *
1488  * @return Returns true if allowed, false otherwise.
1489  */
atomicAllowed(GLint target,GLint format)1490 bool UncommittedRegionsAccessTestCase::atomicAllowed(GLint target, GLint format)
1491 {
1492     DE_UNREF(target);
1493 
1494     if (format == GL_R32I || format == GL_R32UI)
1495     {
1496         return true;
1497     }
1498 
1499     return false;
1500 }
1501 
1502 /** Check if depth and stencil test on uncommitted regions are allowed
1503  *
1504  * @param target       Target for which texture is binded
1505  * @param format       Texture internal format
1506  *
1507  * @return Returns true if allowed, false otherwise.
1508  */
depthStencilAllowed(GLint target,GLint format)1509 bool UncommittedRegionsAccessTestCase::depthStencilAllowed(GLint target, GLint format)
1510 {
1511     if (target == GL_TEXTURE_2D && format == GL_RGBA8)
1512     {
1513         return true;
1514     }
1515 
1516     return false;
1517 }
1518 
1519 /** Verify reads from uncommitted texture regions works as expected
1520  *
1521  * @param gl           GL API functions
1522  * @param target       Target for which texture is binded
1523  * @param format       Texture internal format
1524  * @param texture      Texture object
1525  * @param level        Texture mipmap level
1526  *
1527  * @return Returns true if data is as expected, false otherwise.
1528  */
UncommittedReads(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1529 bool UncommittedRegionsAccessTestCase::UncommittedReads(const Functions &gl, GLint target, GLint format,
1530                                                         GLuint &texture, GLint level)
1531 {
1532     bool result = true;
1533 
1534     // Verify using API glGetTexImage*
1535     if (readsAllowed(target, format, false))
1536     {
1537         mLog << "API Reads - ";
1538         result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1539     }
1540 
1541     // Verify using shader imageLoad function
1542     if (result && readsAllowed(target, format, true))
1543     {
1544         mLog << "Shader Reads - ";
1545         result = result && verifyTextureDataExtended(gl, target, format, texture, level, true);
1546     }
1547 
1548     // Verify mipmap generating
1549     if (result && level == 0 && target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
1550         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1551     {
1552         /* Khronos bugzilla #9471 states that mipmap generation with integer formats
1553          * is unsupported, so skip this test
1554          */
1555         switch (format)
1556         {
1557         case GL_RGB10_A2UI:
1558         case GL_R8I:
1559         case GL_R8UI:
1560         case GL_R16I:
1561         case GL_R16UI:
1562         case GL_R32I:
1563         case GL_R32UI:
1564         case GL_RG8I:
1565         case GL_RG8UI:
1566         case GL_RG16I:
1567         case GL_RG16UI:
1568         case GL_RG32I:
1569         case GL_RG32UI:
1570         case GL_RGBA8I:
1571         case GL_RGBA8UI:
1572         case GL_RGBA16I:
1573         case GL_RGBA16UI:
1574         case GL_RGBA32I:
1575         case GL_RGBA32UI:
1576             return result;
1577         }
1578         mLog << "Mipmap Generate - ";
1579         Texture::Bind(gl, texture, target);
1580         gl.generateMipmap(target);
1581         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap");
1582 
1583         for (int l = 1; l < mState.levels; ++l)
1584             result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1585     }
1586 
1587     return result;
1588 }
1589 
1590 /** Verify atomic operations on uncommitted texture pixels works as expected
1591  *
1592  * @param gl           GL API functions
1593  * @param target       Target for which texture is binded
1594  * @param format       Texture internal format
1595  * @param texture      Texture object
1596  * @param level        Texture mipmap level
1597  *
1598  * @return Returns true if data is as expected, false otherwise.
1599  */
UncommittedAtomicOperations(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1600 bool UncommittedRegionsAccessTestCase::UncommittedAtomicOperations(const Functions &gl, GLint target, GLint format,
1601                                                                    GLuint &texture, GLint level)
1602 {
1603     bool result = true;
1604 
1605     if (atomicAllowed(target, format))
1606     {
1607         mLog << "Atomic Operations - ";
1608         result = result && verifyAtomicOperations(gl, target, format, texture, level);
1609     }
1610 
1611     return result;
1612 }
1613 
1614 /** Verify depth and stencil tests on uncommitted texture pixels works as expected
1615  *
1616  * @param gl           GL API functions
1617  * @param target       Target for which texture is binded
1618  * @param format       Texture internal format
1619  * @param texture      Texture object
1620  * @param level        Texture mipmap level
1621  *
1622  * @return Returns true if data is as expected, false otherwise.
1623  */
UncommittedDepthStencil(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1624 bool UncommittedRegionsAccessTestCase::UncommittedDepthStencil(const Functions &gl, GLint target, GLint format,
1625                                                                GLuint &texture, GLint level)
1626 {
1627     if (!depthStencilAllowed(target, format))
1628         return true;
1629 
1630     mLog << "Depth Stencil - ";
1631 
1632     bool result = true;
1633 
1634     GLint width;
1635     GLint height;
1636     GLint depth;
1637     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1638 
1639     //Committed region is limited to 1/2 of width
1640     GLuint widthCommitted = width / 2;
1641 
1642     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1643         return true;
1644 
1645     //Prepare shaders
1646     std::string vertexSource   = st2_vertex_drawBuffer;
1647     std::string fragmentSource = st2_fragment_drawBuffer;
1648 
1649     ShaderProgram program(gl, glu::makeVtxFragSources(vertexSource, fragmentSource));
1650     if (!program.isOk())
1651     {
1652         mLog << "Shader compilation failed (depth_stencil) for target: " << target << ", format: " << format
1653              << ", vertex_infoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog
1654              << ", fragment_infoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog
1655              << ", vertexSource: " << vertexSource.c_str() << "\n"
1656              << ", fragmentSource: " << fragmentSource.c_str() << " - ";
1657 
1658         return false;
1659     }
1660 
1661     prepareDepthStencilFramebuffer(gl, width, height);
1662 
1663     gl.useProgram(program.getProgram());
1664 
1665     gl.activeTexture(GL_TEXTURE0);
1666     GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
1667     Texture::Bind(gl, texture, target);
1668     gl.uniform1i(1, 0);
1669     GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1670 
1671     // Stencil test
1672     result = result && verifyStencilTest(gl, program, width, height, widthCommitted);
1673 
1674     // Depth test
1675     result = result && verifyDepthTest(gl, program, width, height, widthCommitted);
1676 
1677     // Depth bounds test
1678     if (m_context.getContextInfo().isExtensionSupported("GL_EXT_depth_bounds_test"))
1679         result = result && verifyDepthBoundsTest(gl, program, width, height, widthCommitted);
1680 
1681     // Resources cleaning
1682     cleanupDepthStencilFramebuffer(gl);
1683 
1684     return result;
1685 }
1686 
1687 /** Prepare gl depth and stencil test resources
1688  *
1689  * @param gl      GL API functions
1690  * @param width   Framebuffer width
1691  * @param height  Framebuffer height
1692  */
prepareDepthStencilFramebuffer(const Functions & gl,GLint width,GLint height)1693 void UncommittedRegionsAccessTestCase::prepareDepthStencilFramebuffer(const Functions &gl, GLint width, GLint height)
1694 {
1695     gl.genRenderbuffers(1, &mRenderbuffer);
1696     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers");
1697     gl.bindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
1698     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer");
1699     if (mState.samples == 1)
1700     {
1701         gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
1702         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage");
1703     }
1704     else
1705     {
1706         gl.renderbufferStorageMultisample(GL_RENDERBUFFER, mState.samples, GL_DEPTH_STENCIL, width, height);
1707         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample");
1708     }
1709 
1710     gl.genFramebuffers(1, &mFramebuffer);
1711     GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
1712     gl.bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
1713     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1714     gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer);
1715     GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
1716     gl.viewport(0, 0, width, height);
1717 }
1718 
1719 /** Cleanup gl depth and stencil test resources
1720  *
1721  * @param gl   GL API functions
1722  */
cleanupDepthStencilFramebuffer(const Functions & gl)1723 void UncommittedRegionsAccessTestCase::cleanupDepthStencilFramebuffer(const Functions &gl)
1724 {
1725     gl.deleteFramebuffers(1, &mFramebuffer);
1726     GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1727     gl.deleteRenderbuffers(1, &mRenderbuffer);
1728     GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers");
1729 
1730     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1731     GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1732 }
1733 
1734 /** Verify if data stored in texture in uncommitted regions is as expected
1735  *
1736  * @param gl           GL API functions
1737  * @param target       Target for which texture is binded
1738  * @param format       Texture internal format
1739  * @param texture      Texture object
1740  * @param level        Texture mipmap level
1741  * @param shaderOnly   Shader texture filling flag, default false
1742  *
1743  * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1744  */
verifyTextureDataExtended(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level,bool shaderOnly)1745 bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions &gl, GLint target, GLint format,
1746                                                                  GLuint &texture, GLint level, bool shaderOnly)
1747 {
1748     mLog << "Verify Texture [level: " << level << "] - ";
1749 
1750     if (level > mState.levels - 1)
1751         TCU_FAIL("Invalid level");
1752 
1753     TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1754 
1755     GLint width;
1756     GLint height;
1757     GLint depth;
1758     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1759 
1760     //Committed region is limited to 1/2 of width
1761     GLint widthCommitted = width / 2;
1762 
1763     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1764         return true;
1765 
1766     bool result = true;
1767 
1768     // Verify texture using API glGetTexImage* (Skip multisample textures as it can not be verified using API)
1769     if (!shaderOnly && target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1770         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1771     {
1772         GLint texSize = width * height * depth * mState.format.getPixelSize();
1773 
1774         std::vector<GLubyte> vecExpData;
1775         std::vector<GLubyte> vecOutData;
1776         vecExpData.resize(texSize);
1777         vecOutData.resize(texSize);
1778         GLubyte *exp_data = vecExpData.data();
1779         GLubyte *out_data = vecOutData.data();
1780 
1781         // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
1782         deMemset(exp_data, 0, texSize);
1783         deMemset(out_data, 255, texSize);
1784 
1785         Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
1786         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1787 
1788         //Verify only uncommitted region
1789         for (GLint x = widthCommitted; result && x < width; ++x)
1790             for (GLint y = 0; result && y < height; ++y)
1791                 for (GLint z = 0; result && z < depth; ++z)
1792                 {
1793                     int pixelSize          = mState.format.getPixelSize();
1794                     GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
1795                     GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
1796                     if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1797                     {
1798                         mLog << "Error detected at " << x << "," << y << "," << z << ": expected [ ";
1799                         for (int e = 0; e < pixelSize; e++)
1800                             mLog << (unsigned)dataRegion[e] << " ";
1801                         mLog << "] got [ ";
1802                         for (int e = 0; e < pixelSize; e++)
1803                             mLog << (unsigned)outDataRegion[e] << " ";
1804                         mLog << "] ";
1805                         result = false;
1806                     }
1807                 }
1808     }
1809     // Verify texture using API glGetTexImage* (Only cube map as it has to be verified for subtargets)
1810     else if (!shaderOnly && target == GL_TEXTURE_CUBE_MAP)
1811     {
1812         std::vector<GLint> subTargets;
1813 
1814         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1815         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1816         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1817         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1818         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1819         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1820 
1821         GLint texSize = width * height * mState.format.getPixelSize();
1822 
1823         std::vector<GLubyte> vecExpData;
1824         std::vector<GLubyte> vecOutData;
1825         vecExpData.resize(texSize);
1826         vecOutData.resize(texSize);
1827         GLubyte *exp_data = vecExpData.data();
1828         GLubyte *out_data = vecOutData.data();
1829 
1830         deMemset(exp_data, 0, texSize);
1831 
1832         for (size_t i = 0; i < subTargets.size(); ++i)
1833         {
1834             GLint subTarget = subTargets[i];
1835 
1836             mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1837 
1838             deMemset(out_data, 255, texSize);
1839 
1840             Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
1841             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1842 
1843             //Verify only uncommitted region
1844             for (GLint x = widthCommitted; result && x < width; ++x)
1845                 for (GLint y = 0; result && y < height; ++y)
1846                     for (GLint z = 0; result && z < depth; ++z)
1847                     {
1848                         int pixelSize          = mState.format.getPixelSize();
1849                         GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
1850                         GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
1851                         if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1852                         {
1853                             mLog << "Error detected at " << x << "," << y << "," << z << ": expected [ ";
1854                             for (int e = 0; e < pixelSize; e++)
1855                                 mLog << (unsigned)dataRegion[e] << " ";
1856                             mLog << "] got [ ";
1857                             for (int e = 0; e < pixelSize; e++)
1858                                 mLog << (unsigned)outDataRegion[e] << " ";
1859                             mLog << "] ";
1860                             result = false;
1861                         }
1862                     }
1863 
1864             if (!result)
1865                 break;
1866         }
1867     }
1868     // Verify texture using shader imageLoad function
1869     else if (shaderOnly)
1870     {
1871         // Create verifying texture
1872         GLint verifyTarget;
1873         if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
1874             verifyTarget = GL_TEXTURE_2D;
1875         else
1876             verifyTarget = GL_TEXTURE_2D_ARRAY;
1877 
1878         if (target == GL_TEXTURE_CUBE_MAP)
1879             depth = depth * 6;
1880         if (depth == 1 && mState.samples == 1)
1881             target = GL_TEXTURE_2D;
1882 
1883         GLint texSize = width * height * depth;
1884 
1885         std::vector<GLubyte> vecExpData;
1886         std::vector<GLubyte> vecOutData;
1887         vecExpData.resize(texSize);
1888         vecOutData.resize(texSize);
1889         GLubyte *exp_data = vecExpData.data();
1890         GLubyte *out_data = vecOutData.data();
1891 
1892         // Expected value in this case is 255 because shader fills output texture with 255 if in texture is filled with zeros
1893         deMemset(exp_data, 255, texSize);
1894 
1895         GLuint verifyTexture;
1896         Texture::Generate(gl, verifyTexture);
1897         Texture::Bind(gl, verifyTexture, verifyTarget);
1898         Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1899         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1900 
1901         for (GLint sample = 0; sample < mState.samples; ++sample)
1902         {
1903             deMemset(out_data, 0, texSize);
1904 
1905             Texture::Bind(gl, verifyTexture, verifyTarget);
1906             Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1907                               (GLvoid *)out_data);
1908             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1909 
1910             std::string shader = st2_compute_textureVerify;
1911 
1912             // Adjust shader source to texture format
1913             TokenStrings s = createShaderTokens(target, verifyTarget, format, sample);
1914 
1915             replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1916             replaceToken("<FORMAT>", s.format.c_str(), shader);
1917             replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1918             replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1919             replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1920             replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1921             replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1922             replaceToken("<RESULT_EXPECTED>", s.resultDefault.c_str(), shader);
1923             replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1924 
1925             ProgramSources sources;
1926             sources << ComputeSource(shader);
1927 
1928             // Build and run shader
1929             ShaderProgram program(m_context.getRenderContext(), sources);
1930             if (program.isOk())
1931             {
1932                 gl.useProgram(program.getProgram());
1933                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1934                 gl.bindImageTexture(0, //unit
1935                                     verifyTexture,
1936                                     0,         //level
1937                                     depth > 1, //layered
1938                                     0,         //layer
1939                                     GL_WRITE_ONLY, GL_R8UI);
1940                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1941                 gl.bindImageTexture(1, //unit
1942                                     texture,
1943                                     level,     //level
1944                                     depth > 1, //layered
1945                                     0,         //layer
1946                                     GL_READ_ONLY, format);
1947                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1948                 gl.uniform1i(1, 0 /* image_unit */);
1949                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1950                 gl.uniform1i(2, 1 /* image_unit */);
1951                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1952                 gl.dispatchCompute(width, height, depth);
1953                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1954                 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1955                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1956 
1957                 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)out_data);
1958                 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1959 
1960                 //Verify only committed region
1961                 for (GLint x = widthCommitted; x < width; ++x)
1962                     for (GLint y = 0; y < height; ++y)
1963                         for (GLint z = 0; z < depth; ++z)
1964                         {
1965                             GLubyte *dataRegion    = exp_data + ((x + y * width) + z * width * height);
1966                             GLubyte *outDataRegion = out_data + ((x + y * width) + z * width * height);
1967                             if (dataRegion[0] != outDataRegion[0])
1968                             {
1969                                 m_testCtx.getLog()
1970                                     << tcu::TestLog::Message << mLog.str() << "Error detected at " << x << "," << y
1971                                     << "," << z << " for sample " << sample << ": expected [" << (unsigned)dataRegion[0]
1972                                     << "] got [" << (unsigned)outDataRegion[0] << "]" << tcu::TestLog::EndMessage;
1973                                 result = false;
1974                                 goto out;
1975                             }
1976                         }
1977             }
1978             else
1979             {
1980                 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1981                      << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1982                      << ", shaderSource: " << shader.c_str() << " - ";
1983 
1984                 result = false;
1985             }
1986         }
1987     out:
1988         Texture::Delete(gl, verifyTexture);
1989     }
1990 
1991     return result;
1992 }
1993 
1994 /** Verify if atomic operations on uncommitted regions returns zeros and has no effect on texture
1995  *
1996  * @param gl           GL API functions
1997  * @param target       Target for which texture is binded
1998  * @param format       Texture internal format
1999  * @param texture      Texture object
2000  * @param level        Texture mipmap level
2001  *
2002  * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
2003  */
verifyAtomicOperations(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)2004 bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions &gl, GLint target, GLint format,
2005                                                               GLuint &texture, GLint level)
2006 {
2007     mLog << "Verify Atomic Operations [level: " << level << "] - ";
2008 
2009     if (level > mState.levels - 1)
2010         TCU_FAIL("Invalid level");
2011 
2012     GLint width;
2013     GLint height;
2014     GLint depth;
2015     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2016 
2017     //Committed region is limited to 1/2 of width
2018     GLint widthCommitted = width / 2;
2019 
2020     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
2021         return true;
2022 
2023     bool result = true;
2024 
2025     // Create verifying texture
2026     GLint verifyTarget;
2027     if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
2028         verifyTarget = GL_TEXTURE_2D;
2029     else
2030         verifyTarget = GL_TEXTURE_2D_ARRAY;
2031     if (target == GL_TEXTURE_CUBE_MAP)
2032         depth = depth * 6;
2033     if (depth == 1 && mState.samples == 1)
2034         target = GL_TEXTURE_2D;
2035 
2036     GLint texSize = width * height * depth;
2037 
2038     std::vector<GLubyte> vecExpData;
2039     std::vector<GLubyte> vecOutData;
2040     vecExpData.resize(texSize);
2041     vecOutData.resize(texSize);
2042     GLubyte *exp_data = vecExpData.data();
2043     GLubyte *out_data = vecOutData.data();
2044 
2045     // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
2046     deMemset(exp_data, 0, texSize);
2047 
2048     GLuint verifyTexture;
2049     Texture::Generate(gl, verifyTexture);
2050     Texture::Bind(gl, verifyTexture, verifyTarget);
2051     Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
2052     GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
2053 
2054     for (GLint sample = 0; sample < mState.samples; ++sample)
2055     {
2056         deMemset(out_data, 255, texSize);
2057 
2058         Texture::Bind(gl, verifyTexture, verifyTarget);
2059         Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
2060                           (GLvoid *)out_data);
2061         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
2062 
2063         std::string shader = st2_compute_atomicVerify;
2064 
2065         // Adjust shader source to texture format
2066         TokenStrings s       = createShaderTokens(target, verifyTarget, format, sample);
2067         std::string dataType = (s.returnType == "ivec4" ? "int" : "uint");
2068 
2069         replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
2070         replaceToken("<FORMAT>", s.format.c_str(), shader);
2071         replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2072         replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2073         replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2074         replaceToken("<DATA_TYPE>", dataType.c_str(), shader);
2075         replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2076         replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2077 
2078         ProgramSources sources;
2079         sources << ComputeSource(shader);
2080 
2081         // Build and run shader
2082         ShaderProgram program(m_context.getRenderContext(), sources);
2083         if (program.isOk())
2084         {
2085             gl.useProgram(program.getProgram());
2086             GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2087             gl.bindImageTexture(0, //unit
2088                                 verifyTexture,
2089                                 0,         //level
2090                                 depth > 1, //layered
2091                                 0,         //layer
2092                                 GL_WRITE_ONLY, GL_R8UI);
2093             GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2094             gl.bindImageTexture(1, //unit
2095                                 texture,
2096                                 level,     //level
2097                                 depth > 1, //layered
2098                                 0,         //layer
2099                                 GL_READ_ONLY, format);
2100             GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2101             gl.uniform1i(1, 0 /* image_unit */);
2102             GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2103             gl.uniform1i(2, 1 /* image_unit */);
2104             GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2105             gl.uniform1i(3, widthCommitted /* committed width */);
2106             GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2107             gl.dispatchCompute(width, height, depth);
2108             GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2109             gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2110             GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2111 
2112             Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)out_data);
2113             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
2114 
2115             //Verify only committed region
2116             for (GLint x = 0; x < width; ++x)
2117                 for (GLint y = 0; y < height; ++y)
2118                     for (GLint z = 0; z < depth; ++z)
2119                     {
2120                         GLubyte *dataRegion    = exp_data + ((x + y * width) + z * width * height);
2121                         GLubyte *outDataRegion = out_data + ((x + y * width) + z * width * height);
2122                         if (dataRegion[0] != outDataRegion[0])
2123                         {
2124                             m_testCtx.getLog()
2125                                 << tcu::TestLog::Message << mLog.str() << "Error detected at " << x << "," << y << ","
2126                                 << z << " for sample " << sample << ": expected [" << (unsigned)dataRegion[0]
2127                                 << "] got [" << (unsigned)outDataRegion[0] << "]" << tcu::TestLog::EndMessage;
2128                             result = false;
2129                             goto out;
2130                         }
2131                     }
2132         }
2133         else
2134         {
2135             mLog << "Compute shader compilation failed (atomic) for target: " << target << ", format: " << format
2136                  << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2137                  << ", shaderSource: " << shader.c_str() << " - ";
2138 
2139             result = false;
2140         }
2141     }
2142 out:
2143     Texture::Delete(gl, verifyTexture);
2144 
2145     return result;
2146 }
2147 
2148 /** Verify if stencil test on uncommitted texture region works as expected texture
2149  *
2150  * @param gl              GL API functions
2151  * @param program         Shader program
2152  * @param width           Texture width
2153  * @param height          Texture height
2154  * @param widthCommitted  Committed region width
2155  *
2156  * @return Returns true if stencil data is as expected, false otherwise.
2157  */
verifyStencilTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2158 bool UncommittedRegionsAccessTestCase::verifyStencilTest(const Functions &gl, ShaderProgram &program, GLint width,
2159                                                          GLint height, GLint widthCommitted)
2160 {
2161     glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("vertex", 3, 4, 0, vertices),
2162                                               glu::va::Float("inTexCoord", 2, 4, 0, texCoord)};
2163 
2164     mLog << "Perform Stencil Test - ";
2165 
2166     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2167     gl.enable(GL_STENCIL_TEST);
2168     gl.stencilFunc(GL_GREATER, 1, 0xFF);
2169     gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2170 
2171     glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2172               glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2173 
2174     std::vector<GLubyte> dataStencil;
2175     dataStencil.resize(width * height);
2176     GLubyte *dataStencilPtr = dataStencil.data();
2177 
2178     gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, (GLvoid *)dataStencilPtr);
2179     for (int x = widthCommitted; x < width; ++x)
2180         for (int y = 0; y < height; ++y)
2181         {
2182             if (dataStencilPtr[x + y * width] != 0x00)
2183             {
2184                 gl.disable(GL_STENCIL_TEST);
2185                 return false;
2186             }
2187         }
2188 
2189     gl.disable(GL_STENCIL_TEST);
2190     return true;
2191 }
2192 
2193 /** Verify if depth test on uncommitted texture region works as expected texture
2194  *
2195  * @param gl              GL API functions
2196  * @param program         Shader program
2197  * @param width           Texture width
2198  * @param height          Texture height
2199  * @param widthCommitted  Committed region width
2200  *
2201  * @return Returns true if depth data is as expected, false otherwise.
2202  */
verifyDepthTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2203 bool UncommittedRegionsAccessTestCase::verifyDepthTest(const Functions &gl, ShaderProgram &program, GLint width,
2204                                                        GLint height, GLint widthCommitted)
2205 {
2206     glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("vertex", 3, 4, 0, vertices),
2207                                               glu::va::Float("inTexCoord", 2, 4, 0, texCoord)};
2208 
2209     mLog << "Perform Depth Test - ";
2210 
2211     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2212     gl.enable(GL_DEPTH_TEST);
2213     gl.depthFunc(GL_LESS);
2214 
2215     glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2216               glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2217 
2218     std::vector<GLuint> dataDepth;
2219     dataDepth.resize(width * height);
2220     GLuint *dataDepthPtr = dataDepth.data();
2221 
2222     gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid *)dataDepthPtr);
2223     for (int x = widthCommitted; x < width; ++x)
2224         for (int y = 0; y < height; ++y)
2225         {
2226             if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2227             {
2228                 gl.disable(GL_DEPTH_TEST);
2229                 return false;
2230             }
2231         }
2232 
2233     gl.disable(GL_DEPTH_TEST);
2234     return true;
2235 }
2236 
2237 /** Verify if depth bounds test on uncommitted texture region works as expected texture
2238  *
2239  * @param gl              GL API functions
2240  * @param program         Shader program
2241  * @param width           Texture width
2242  * @param height          Texture height
2243  * @param widthCommitted  Committed region width
2244  *
2245  * @return Returns true if depth data is as expected, false otherwise.
2246  */
verifyDepthBoundsTest(const Functions & gl,ShaderProgram & program,GLint width,GLint height,GLint widthCommitted)2247 bool UncommittedRegionsAccessTestCase::verifyDepthBoundsTest(const Functions &gl, ShaderProgram &program, GLint width,
2248                                                              GLint height, GLint widthCommitted)
2249 {
2250     glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("vertex", 3, 4, 0, vertices),
2251                                               glu::va::Float("inTexCoord", 2, 4, 0, texCoord)};
2252 
2253     mLog << "Perform Depth Bounds Test - ";
2254 
2255     gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2256     gl.enable(GL_DEPTH_BOUNDS_TEST_EXT);
2257     gl.depthFunc(GL_LESS);
2258 
2259     glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2260               glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2261 
2262     std::vector<GLuint> dataDepth;
2263     dataDepth.resize(width * height);
2264     GLuint *dataDepthPtr = dataDepth.data();
2265 
2266     gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid *)dataDepthPtr);
2267     for (int x = widthCommitted; x < width; ++x)
2268         for (int y = 0; y < height; ++y)
2269         {
2270             if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2271             {
2272                 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2273                 return false;
2274             }
2275         }
2276 
2277     gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2278     return true;
2279 }
2280 
2281 /** Constructor.
2282  *
2283  *  @param context     Rendering context
2284  */
SparseTexture2LookupTestCase(deqp::Context & context)2285 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context &context)
2286     : SparseTexture2CommitmentTestCase(context, "SparseTexture2Lookup",
2287                                        "Verifies if sparse texture lookup functions for GLSL works as expected")
2288 {
2289     /* Left blank intentionally */
2290 }
2291 
2292 /** Constructor.
2293  *
2294  *  @param context     Rendering context
2295  */
SparseTexture2LookupTestCase(deqp::Context & context,const char * name,const char * description)2296 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context &context, const char *name,
2297                                                            const char *description)
2298     : SparseTexture2CommitmentTestCase(context, name, description)
2299 {
2300     /* Left blank intentionally */
2301 }
2302 
2303 /** Initializes the test group contents. */
init()2304 void SparseTexture2LookupTestCase::init()
2305 {
2306     SparseTextureCommitmentTestCase::init();
2307     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
2308     mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2309 
2310     mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16);
2311 
2312     FunctionToken f;
2313     f = FunctionToken("sparseTextureARB", "<CUBE_REFZ_DEF>");
2314     f.allowedTargets.insert(GL_TEXTURE_2D);
2315     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2316     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2317     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2318     f.allowedTargets.insert(GL_TEXTURE_3D);
2319     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2320     mFunctions.push_back(f);
2321 
2322     f = FunctionToken("sparseTextureLodARB", ", <LOD>");
2323     f.allowedTargets.insert(GL_TEXTURE_2D);
2324     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2325     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2326     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2327     f.allowedTargets.insert(GL_TEXTURE_3D);
2328     mFunctions.push_back(f);
2329 
2330     f = FunctionToken("sparseTextureOffsetARB", ", <OFFSET_TYPE><OFFSET_DIM>(0)");
2331     f.allowedTargets.insert(GL_TEXTURE_2D);
2332     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2333     f.allowedTargets.insert(GL_TEXTURE_3D);
2334     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2335     mFunctions.push_back(f);
2336 
2337     f = FunctionToken("sparseTexelFetchARB", "<LOD_DEF>");
2338     f.allowedTargets.insert(GL_TEXTURE_2D);
2339     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2340     f.allowedTargets.insert(GL_TEXTURE_3D);
2341     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2342     f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2343     f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2344     mFunctions.push_back(f);
2345 
2346     f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2347     f.allowedTargets.insert(GL_TEXTURE_2D);
2348     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2349     f.allowedTargets.insert(GL_TEXTURE_3D);
2350     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2351     mFunctions.push_back(f);
2352 
2353     f = FunctionToken("sparseTextureLodOffsetARB", ", <LOD>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2354     f.allowedTargets.insert(GL_TEXTURE_2D);
2355     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2356     f.allowedTargets.insert(GL_TEXTURE_3D);
2357     mFunctions.push_back(f);
2358 
2359     f = FunctionToken("sparseTextureGradARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0)");
2360     f.allowedTargets.insert(GL_TEXTURE_2D);
2361     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2362     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2363     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2364     f.allowedTargets.insert(GL_TEXTURE_3D);
2365     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2366     mFunctions.push_back(f);
2367 
2368     f = FunctionToken("sparseTextureGradOffsetARB",
2369                       ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0)");
2370     f.allowedTargets.insert(GL_TEXTURE_2D);
2371     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2372     f.allowedTargets.insert(GL_TEXTURE_3D);
2373     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2374     mFunctions.push_back(f);
2375 
2376     f = FunctionToken("sparseTextureGatherARB", "<REFZ_DEF>");
2377     f.allowedTargets.insert(GL_TEXTURE_2D);
2378     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2379     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2380     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2381     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2382     mFunctions.push_back(f);
2383 
2384     f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2385     f.allowedTargets.insert(GL_TEXTURE_2D);
2386     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2387     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2388     mFunctions.push_back(f);
2389 
2390     f = FunctionToken("sparseTextureGatherOffsetsARB",
2391                       "<REFZ_DEF>, "
2392                       "<OFFSET_TYPE><OFFSET_DIM>[4](<OFFSET_TYPE><OFFSET_DIM>(0),<OFFSET_TYPE><OFFSET_DIM>(0),<OFFSET_"
2393                       "TYPE><OFFSET_DIM>(0),<OFFSET_TYPE><OFFSET_DIM>(0))");
2394     f.allowedTargets.insert(GL_TEXTURE_2D);
2395     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2396     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2397     mFunctions.push_back(f);
2398 
2399     f = FunctionToken("sparseImageLoadARB", "");
2400     f.allowedTargets.insert(GL_TEXTURE_2D);
2401     f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2402     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2403     f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2404     f.allowedTargets.insert(GL_TEXTURE_3D);
2405     f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2406     f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2407     f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2408     //mFunctions.push_back(f);
2409 }
2410 
2411 /** Executes test iteration.
2412  *
2413  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2414  */
iterate()2415 tcu::TestNode::IterateResult SparseTexture2LookupTestCase::iterate()
2416 {
2417     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
2418     {
2419         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2420         return STOP;
2421     }
2422 
2423     const Functions &gl = m_context.getRenderContext().getFunctions();
2424 
2425     bool result = true;
2426 
2427     GLuint texture;
2428 
2429     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
2430          ++iter)
2431     {
2432         const GLint &target = *iter;
2433 
2434         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
2435              formIter != mSupportedInternalFormats.end(); ++formIter)
2436         {
2437             const GLint &format = *formIter;
2438 
2439             if (!caseAllowed(target, format))
2440                 continue;
2441 
2442             for (std::vector<FunctionToken>::const_iterator tokIter = mFunctions.begin(); tokIter != mFunctions.end();
2443                  ++tokIter)
2444             {
2445                 // Check if target is allowed for current lookup function
2446                 FunctionToken funcToken = *tokIter;
2447                 if (!funcAllowed(target, format, funcToken))
2448                     continue;
2449 
2450                 mLog.str("");
2451                 mLog << "Testing sparse texture lookup functions for target: " << target << ", format: " << format
2452                      << " - ";
2453 
2454                 sparseAllocateTexture(gl, target, format, texture, 3);
2455                 if (format == GL_DEPTH_COMPONENT16)
2456                     setupDepthMode(gl, target, texture);
2457 
2458                 for (int l = 0; l < mState.levels; ++l)
2459                 {
2460                     if (commitTexturePage(gl, target, format, texture, l))
2461                     {
2462                         writeDataToTexture(gl, target, format, texture, l);
2463                         result = result && verifyLookupTextureData(gl, target, format, texture, l, funcToken);
2464                     }
2465 
2466                     if (!result)
2467                         break;
2468                 }
2469 
2470                 Texture::Delete(gl, texture);
2471 
2472                 if (!result)
2473                 {
2474                     m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
2475                     m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2476                     return STOP;
2477                 }
2478             }
2479         }
2480     }
2481 
2482     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2483     return STOP;
2484 }
2485 
2486 /** Create set of token strings fit to lookup functions verifying shader
2487  *
2488  * @param target       Target for which texture is binded
2489  * @param format       Texture internal format
2490  * @param level        Texture mipmap level
2491  * @param sample       Texture sample number
2492  * @param funcToken    Texture lookup function structure
2493  *
2494  * @return Returns extended token strings structure.
2495  */
createLookupShaderTokens(GLint target,GLint verifyTarget,GLint format,GLint level,GLint sample,FunctionToken & funcToken)2496 SparseTexture2LookupTestCase::TokenStringsExt SparseTexture2LookupTestCase::createLookupShaderTokens(
2497     GLint target, GLint verifyTarget, GLint format, GLint level, GLint sample, FunctionToken &funcToken)
2498 {
2499     std::string funcName = funcToken.name;
2500 
2501     TokenStringsExt s;
2502 
2503     std::string inputType;
2504     std::string samplerSufix;
2505 
2506     if (funcName == "sparseImageLoadARB")
2507         inputType = "image";
2508     else
2509         inputType = "sampler";
2510 
2511     // Copy data from TokenStrings to TokenStringsExt
2512     TokenStrings ss  = createShaderTokens(target, verifyTarget, format, sample, "image", inputType);
2513     s.epsilon        = ss.epsilon;
2514     s.format         = ss.format;
2515     s.inputType      = ss.inputType;
2516     s.outputType     = ss.outputType;
2517     s.pointDef       = ss.pointDef;
2518     s.pointType      = ss.pointType;
2519     s.resultDefault  = ss.resultDefault;
2520     s.resultExpected = ss.resultExpected;
2521     s.returnType     = ss.returnType;
2522     s.sampleDef      = ss.sampleDef;
2523 
2524     // Set format definition for image input types
2525     if (inputType == "image")
2526         s.formatDef = ", " + s.format;
2527 
2528     // Set tokens for depth texture format
2529     if (format == GL_DEPTH_COMPONENT16)
2530     {
2531         s.refZDef = ", 0.5";
2532 
2533         if (inputType == "sampler" && target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_MULTISAMPLE &&
2534             target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2535         {
2536             s.inputType = s.inputType + "Shadow";
2537         }
2538     }
2539 
2540     // Set coord type, coord definition and offset vector dimensions
2541     s.coordType   = "vec2";
2542     s.offsetType  = "ivec";
2543     s.nOffsetType = "vec";
2544     s.offsetDim   = "2";
2545     if (target == GL_TEXTURE_1D)
2546     {
2547         s.coordType   = "float";
2548         s.offsetType  = "int";
2549         s.nOffsetType = "float";
2550         s.offsetDim   = "";
2551     }
2552     else if (target == GL_TEXTURE_1D_ARRAY)
2553     {
2554         s.coordType   = "vec2";
2555         s.offsetType  = "int";
2556         s.nOffsetType = "float";
2557         s.offsetDim   = "";
2558     }
2559     else if (target == GL_TEXTURE_2D_ARRAY)
2560     {
2561         s.coordType = "vec3";
2562     }
2563     else if (target == GL_TEXTURE_3D)
2564     {
2565         s.coordType = "vec3";
2566         s.offsetDim = "3";
2567     }
2568     else if (target == GL_TEXTURE_CUBE_MAP)
2569     {
2570         s.coordType = "vec3";
2571         s.offsetDim = "3";
2572     }
2573     else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2574     {
2575         s.coordType = "vec4";
2576         s.coordDef  = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6, floor(gl_WorkGroupID.z / 6)";
2577         s.offsetDim = "3";
2578     }
2579     else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2580     {
2581         s.coordType = "vec3";
2582     }
2583 
2584     if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
2585         funcName.find("Fetch", 0) == std::string::npos)
2586     {
2587         s.cubeMapCoordDef = "    int face = point.z % 6;\n"
2588                             "    if (face == 0) coord.xyz = vec3(1, coord.y * 2 - 1, -coord.x * 2 + 1);\n"
2589                             "    if (face == 1) coord.xyz = vec3(-1, coord.y * 2 - 1, coord.x * 2 - 1);\n"
2590                             "    if (face == 2) coord.xyz = vec3(coord.x * 2 - 1, 1, coord.y * 2 - 1);\n"
2591                             "    if (face == 3) coord.xyz = vec3(coord.x * 2 - 1, -1, -coord.y * 2 + 1);\n"
2592                             "    if (face == 4) coord.xyz = vec3(coord.x * 2 - 1, coord.y * 2 - 1, 1);\n"
2593                             "    if (face == 5) coord.xyz = vec3(-coord.x * 2 + 1, coord.y * 2 - 1, -1);\n";
2594     }
2595 
2596     if (s.coordDef.empty())
2597         s.coordDef = s.pointDef;
2598 
2599     // Set expected result vector, component definition and offset array definition for gather functions
2600     if (funcName.find("Gather", 0) != std::string::npos)
2601     {
2602         if (format != GL_DEPTH_COMPONENT16)
2603             s.componentDef = ", 0";
2604         s.resultExpected = "(1, 1, 1, 1)";
2605     }
2606     // Extend coord type dimension and coord vector definition if shadow sampler and non-cube map array target selected
2607     // Set component definition to red component
2608     else if (format == GL_DEPTH_COMPONENT16)
2609     {
2610         if (target != GL_TEXTURE_CUBE_MAP_ARRAY)
2611         {
2612             if (s.coordType == "float")
2613                 s.coordType = "vec3";
2614             else if (s.coordType == "vec2")
2615                 s.coordType = "vec3";
2616             else if (s.coordType == "vec3")
2617                 s.coordType = "vec4";
2618             s.coordDef += s.refZDef;
2619         }
2620         else
2621             s.cubeMapArrayRefZDef = s.refZDef;
2622 
2623         s.componentDef = ".r";
2624     }
2625 
2626     // Set level of details definition
2627     if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
2628         target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2629     {
2630         s.lod    = de::toString(level);
2631         s.lodDef = ", " + de::toString(level);
2632     }
2633 
2634     // Set proper coord vector
2635     if (target == GL_TEXTURE_RECTANGLE || funcName.find("Fetch") != std::string::npos ||
2636         funcName.find("ImageLoad") != std::string::npos)
2637     {
2638         s.pointCoord = "icoord";
2639     }
2640     else
2641         s.pointCoord = "coord";
2642 
2643     // Set size vector definition
2644     if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos)
2645     {
2646         if (s.coordType == "float")
2647             s.sizeDef = "<TEX_WIDTH>";
2648         else if (s.coordType == "vec2" && target == GL_TEXTURE_1D_ARRAY)
2649             s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>";
2650         else if (s.coordType == "vec2")
2651             s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>";
2652         else if (s.coordType == "vec3")
2653             s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>";
2654         else if (s.coordType == "vec4")
2655             s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 6, floor(<TEX_DEPTH> / 6)";
2656     }
2657     // Set size vector for shadow samplers and non-gether functions selected
2658     else
2659     {
2660         if (s.coordType == "vec3" && target == GL_TEXTURE_1D)
2661             s.sizeDef = "<TEX_WIDTH>, 1 , 1";
2662         else if (s.coordType == "vec3" && target == GL_TEXTURE_1D_ARRAY)
2663             s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>, 1";
2664         else if (s.coordType == "vec3")
2665             s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 1";
2666         else if (s.coordType == "vec4")
2667             s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>, 1";
2668     }
2669 
2670     if (s.coordType != "float")
2671         s.iCoordType = "i" + s.coordType;
2672     else
2673         s.iCoordType = "int";
2674 
2675     return s;
2676 }
2677 
2678 /** Check if specific combination of target and format is
2679 
2680  *
2681  * @param target       Target for which texture is binded
2682  * @param format       Texture internal format
2683  *
2684  * @return Returns true if target/format combination is allowed, false otherwise.
2685  */
caseAllowed(GLint target,GLint format)2686 bool SparseTexture2LookupTestCase::caseAllowed(GLint target, GLint format)
2687 {
2688     DE_UNREF(target);
2689 
2690     // As shaders do not support some texture formats it is necessary to exclude them.
2691     if (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5)
2692     {
2693         return false;
2694     }
2695 
2696     if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_3D) &&
2697         (format == GL_DEPTH_COMPONENT16))
2698     {
2699         return false;
2700     }
2701 
2702     return true;
2703 }
2704 
2705 /** Check if specific lookup function is allowed for specific target and format
2706  *
2707  * @param target       Target for which texture is binded
2708  * @param format       Texture internal format
2709  * @param funcToken    Texture lookup function structure
2710  *
2711  * @return Returns true if target/format combination is allowed, false otherwise.
2712  */
funcAllowed(GLint target,GLint format,FunctionToken & funcToken)2713 bool SparseTexture2LookupTestCase::funcAllowed(GLint target, GLint format, FunctionToken &funcToken)
2714 {
2715     if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end())
2716         return false;
2717 
2718     if (format == GL_DEPTH_COMPONENT16)
2719     {
2720         if (funcToken.name == "sparseTextureLodARB" || funcToken.name == "sparseTextureLodOffsetARB")
2721         {
2722             if (target != GL_TEXTURE_2D)
2723                 return false;
2724         }
2725         else if (funcToken.name == "sparseTextureOffsetARB" || funcToken.name == "sparseTextureGradOffsetARB" ||
2726                  funcToken.name == "sparseTextureGatherOffsetARB" || funcToken.name == "sparseTextureGatherOffsetsARB")
2727         {
2728             if (target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE)
2729             {
2730                 return false;
2731             }
2732         }
2733         else if (funcToken.name == "sparseTexelFetchARB" || funcToken.name == "sparseTexelFetchOffsetARB")
2734         {
2735             return false;
2736         }
2737         else if (funcToken.name == "sparseTextureGradARB")
2738         {
2739             if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2740                 return false;
2741         }
2742         else if (funcToken.name == "sparseImageLoadARB")
2743         {
2744             return false;
2745         }
2746     }
2747 
2748     return true;
2749 }
2750 
2751 /** Writing data to generated texture using compute shader
2752  *
2753  * @param gl           GL API functions
2754  * @param target       Target for which texture is binded
2755  * @param format       Texture internal format
2756  * @param texture      Texture object
2757  *
2758  * @return Returns true if no error occurred, otherwise throws an exception.
2759  */
writeDataToTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)2760 bool SparseTexture2LookupTestCase::writeDataToTexture(const Functions &gl, GLint target, GLint format, GLuint &texture,
2761                                                       GLint level)
2762 {
2763     mLog << "Fill Texture with shader [level: " << level << "] - ";
2764 
2765     if (level > mState.levels - 1)
2766         TCU_FAIL("Invalid level");
2767 
2768     GLint width;
2769     GLint height;
2770     GLint depth;
2771     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2772 
2773     if (width > 0 && height > 0 && depth >= mState.minDepth)
2774     {
2775         if (target == GL_TEXTURE_CUBE_MAP)
2776             depth = depth * 6;
2777 
2778         GLint texSize = width * height * depth * mState.format.getPixelSize();
2779 
2780         std::vector<GLubyte> vecData;
2781         vecData.resize(texSize);
2782         GLubyte *data = vecData.data();
2783 
2784         deMemset(data, 255, texSize);
2785 
2786         for (GLint sample = 0; sample < mState.samples; ++sample)
2787         {
2788             std::string shader = st2_compute_textureFill;
2789 
2790             // Adjust shader source to texture format
2791             GLint verifyTarget;
2792             if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
2793                 verifyTarget = GL_TEXTURE_2D;
2794             else
2795                 verifyTarget = GL_TEXTURE_2D_ARRAY;
2796             TokenStrings s = createShaderTokens(target, verifyTarget, format, sample);
2797 
2798             replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2799             replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2800             replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2801             replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2802             replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2803             replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2804 
2805             ProgramSources sources;
2806             sources << ComputeSource(shader);
2807 
2808             GLint convFormat = format;
2809             if (format == GL_DEPTH_COMPONENT16)
2810                 convFormat = GL_R16;
2811 
2812             // Build and run shader
2813             ShaderProgram program(m_context.getRenderContext(), sources);
2814             if (program.isOk())
2815             {
2816                 gl.useProgram(program.getProgram());
2817                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2818                 gl.bindImageTexture(0 /* unit */, texture, level /* level */, depth > 1 /* layered */, 0 /* layer */,
2819                                     GL_WRITE_ONLY, convFormat);
2820                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2821                 gl.uniform1i(1, 0 /* image_unit */);
2822                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2823                 gl.dispatchCompute(width, height, depth);
2824                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2825                 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2826                 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2827             }
2828             else
2829             {
2830                 mLog << "Compute shader compilation failed (writing) for target: " << target << ", format: " << format
2831                      << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2832                      << ", shaderSource: " << shader.c_str() << " - ";
2833             }
2834         }
2835     }
2836 
2837     return true;
2838 }
2839 
2840 /** Setup depth compare mode and compare function for depth texture
2841  *
2842  * @param gl           GL API functions
2843  * @param target       Target for which texture is binded
2844  * @param texture      Texture object
2845  */
setupDepthMode(const Functions & gl,GLint target,GLuint & texture)2846 void SparseTexture2LookupTestCase::setupDepthMode(const Functions &gl, GLint target, GLuint &texture)
2847 {
2848     Texture::Bind(gl, texture, target);
2849     gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2850     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2851     gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
2852     GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2853 }
2854 
2855 /** Verify if data stored in texture is as expected
2856  *
2857  * @param gl           GL API functions
2858  * @param target       Target for which texture is binded
2859  * @param format       Texture internal format
2860  * @param texture      Texture object
2861  * @param level        Texture mipmap level
2862  * @param funcToken    Lookup function tokenize structure
2863  *
2864  * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
2865  */
verifyLookupTextureData(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level,FunctionToken & funcToken)2866 bool SparseTexture2LookupTestCase::verifyLookupTextureData(const Functions &gl, GLint target, GLint format,
2867                                                            GLuint &texture, GLint level, FunctionToken &funcToken)
2868 {
2869     mLog << "Verify Lookup Texture Data [function: " << funcToken.name << ", level: " << level << "] - ";
2870 
2871     if (level > mState.levels - 1)
2872         TCU_FAIL("Invalid level");
2873 
2874     GLint width;
2875     GLint height;
2876     GLint depth;
2877     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2878 
2879     //Committed region is limited to 1/2 of width
2880     GLint widthCommitted = width / 2;
2881 
2882     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
2883         return true;
2884 
2885     bool result = true;
2886 
2887     if (target == GL_TEXTURE_CUBE_MAP)
2888         depth = depth * 6;
2889 
2890     GLint texSize = width * height * depth;
2891 
2892     std::vector<GLubyte> vecExpData;
2893     std::vector<GLubyte> vecOutData;
2894     vecExpData.resize(texSize);
2895     vecOutData.resize(texSize);
2896     GLubyte *exp_data = vecExpData.data();
2897     GLubyte *out_data = vecOutData.data();
2898 
2899     // Expected data is 255 because
2900     deMemset(exp_data, 255, texSize);
2901 
2902     // Make token copy to work on
2903     FunctionToken f = funcToken;
2904 
2905     // Create verifying texture
2906     GLint verifyTarget;
2907     if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE)
2908         verifyTarget = GL_TEXTURE_2D;
2909     else
2910         verifyTarget = GL_TEXTURE_2D_ARRAY;
2911 
2912     GLuint verifyTexture;
2913     Texture::Generate(gl, verifyTexture);
2914     Texture::Bind(gl, verifyTexture, verifyTarget);
2915     Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
2916     GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
2917 
2918     for (int sample = 0; sample < mState.samples; ++sample)
2919     {
2920         deMemset(out_data, 0, texSize);
2921 
2922         Texture::Bind(gl, verifyTexture, verifyTarget);
2923         Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
2924                           (GLvoid *)out_data);
2925         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
2926 
2927         std::string shader = st2_compute_lookupVerify;
2928 
2929         // Adjust shader source to texture format
2930         TokenStringsExt s = createLookupShaderTokens(target, verifyTarget, format, level, sample, f);
2931 
2932         replaceToken("<FUNCTION>", f.name.c_str(), shader);
2933         replaceToken("<ARGUMENTS>", f.arguments.c_str(), shader);
2934 
2935         replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
2936         replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2937         replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), shader);
2938         replaceToken("<LOD>", s.lod.c_str(), shader);
2939         replaceToken("<LOD_DEF>", s.lodDef.c_str(), shader);
2940         replaceToken("<COORD_TYPE>", s.coordType.c_str(), shader);
2941         replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), shader);
2942         replaceToken("<COORD_DEF>", s.coordDef.c_str(), shader);
2943         replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2944         replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2945         replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2946         replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2947         replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
2948         replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2949         replaceToken("<REFZ_DEF>", s.refZDef.c_str(), shader);
2950         replaceToken("<CUBE_REFZ_DEF>", s.cubeMapArrayRefZDef.c_str(), shader);
2951         replaceToken("<POINT_COORD>", s.pointCoord.c_str(), shader);
2952         replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), shader);
2953         replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), shader);
2954         replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), shader);
2955         replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), shader);
2956         replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), shader);
2957         replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), shader);
2958         replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), shader);
2959 
2960         replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), shader);
2961         replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), shader);
2962         replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), shader);
2963 
2964         ProgramSources sources;
2965         sources << ComputeSource(shader);
2966 
2967         // Build and run shader
2968         ShaderProgram program(m_context.getRenderContext(), sources);
2969         if (program.isOk())
2970         {
2971             gl.useProgram(program.getProgram());
2972             GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2973 
2974             // Pass output image to shader
2975             gl.bindImageTexture(1, //unit
2976                                 verifyTexture,
2977                                 0,       //level
2978                                 GL_TRUE, //layered
2979                                 0,       //layer
2980                                 GL_WRITE_ONLY, GL_R8UI);
2981             GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2982             gl.uniform1i(1, 1 /* image_unit */);
2983             GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2984 
2985             // Pass input sampler/image to shader
2986             if (f.name != "sparseImageLoadARB")
2987             {
2988                 gl.activeTexture(GL_TEXTURE0);
2989                 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
2990                 gl.bindTexture(target, texture);
2991                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
2992                 gl.uniform1i(2, 0 /* sampler_unit */);
2993                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2994             }
2995             else
2996             {
2997                 gl.bindImageTexture(0, //unit
2998                                     texture,
2999                                     level,    //level
3000                                     GL_FALSE, //layered
3001                                     0,        //layer
3002                                     GL_READ_ONLY, format);
3003                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
3004                 gl.uniform1i(2, 0 /* image_unit */);
3005                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
3006             }
3007 
3008             // Pass committed region width to shader
3009             gl.uniform1i(3, widthCommitted /* committed region width */);
3010             GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
3011             gl.dispatchCompute(width, height, depth);
3012             GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
3013             gl.memoryBarrier(GL_ALL_BARRIER_BITS);
3014             GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
3015 
3016             Texture::Bind(gl, verifyTexture, verifyTarget);
3017             Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid *)out_data);
3018             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
3019 
3020             //Verify only committed region
3021             for (GLint z = 0; z < depth; ++z)
3022                 for (GLint y = 0; y < height; ++y)
3023                     for (GLint x = 0; x < width; ++x)
3024                     {
3025                         GLubyte *dataRegion    = exp_data + x + y * width + z * width * height;
3026                         GLubyte *outDataRegion = out_data + x + y * width + z * width * height;
3027                         if (dataRegion[0] != outDataRegion[0])
3028                         {
3029                             m_testCtx.getLog()
3030                                 << tcu::TestLog::Message << mLog.str() << "Error detected at " << x << "," << y << ","
3031                                 << z << " for sample " << sample << ": expected [" << (unsigned)dataRegion[0]
3032                                 << "] got [" << (unsigned)outDataRegion[0] << "]" << tcu::TestLog::EndMessage;
3033                             result = false;
3034                             goto out;
3035                         }
3036                     }
3037         }
3038         else
3039         {
3040             mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format
3041                  << ", shaderInfoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
3042                  << ", programInfoLog: " << program.getProgramInfo().infoLog << ", shaderSource: " << shader.c_str()
3043                  << " - ";
3044 
3045             result = false;
3046         }
3047     }
3048 out:
3049     Texture::Delete(gl, verifyTexture);
3050 
3051     return result;
3052 }
3053 
3054 /** Constructor.
3055  *
3056  *  @param context Rendering context.
3057  */
SparseTexture2Tests(deqp::Context & context)3058 SparseTexture2Tests::SparseTexture2Tests(deqp::Context &context)
3059     : TestCaseGroup(context, "sparse_texture2_tests", "Verify conformance of CTS_ARB_sparse_texture2 implementation")
3060 {
3061 }
3062 
3063 /** Initializes the test group contents. */
init()3064 void SparseTexture2Tests::init()
3065 {
3066     addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture2"));
3067     addChild(new StandardPageSizesTestCase(m_context));
3068     addChild(new SparseTexture2AllocationTestCase(m_context));
3069     addChild(new SparseTexture2CommitmentTestCase(m_context));
3070     addChild(new UncommittedRegionsAccessTestCase(m_context));
3071     addChild(new SparseTexture2LookupTestCase(m_context));
3072 }
3073 
3074 } // namespace gl4cts
3075