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