xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cSparseTextureTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 /**
25  */ /*!
26  * \file  gl4cSparseTextureTests.cpp
27  * \brief Conformance tests for the GL_ARB_sparse_texture functionality.
28  */ /*-------------------------------------------------------------------*/
29 
30 #include "gl4cSparseTextureTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "glwEnums.hpp"
34 #include "glwFunctions.hpp"
35 #include "tcuTestLog.hpp"
36 
37 #include <algorithm>
38 #include <cmath>
39 #include <cstdlib>
40 #include <string.h>
41 #include <vector>
42 
43 using namespace glw;
44 using namespace glu;
45 
46 namespace gl4cts
47 {
48 
49 typedef std::pair<GLint, GLint> IntPair;
50 
51 /** Verifies last query error and generate proper log message
52  *
53  * @param funcName         Verified function name
54  * @param target           Target for which texture is binded
55  * @param pname            Parameter name
56  * @param error            Generated error code
57  * @param expectedError    Expected error code
58  *
59  * @return Returns true if queried value is as expected, returns false otherwise
60  */
verifyQueryError(std::stringstream & log,const char * funcName,GLint target,GLint pname,GLint error,GLint expectedError)61 bool SparseTextureUtils::verifyQueryError(std::stringstream &log, const char *funcName, GLint target, GLint pname,
62                                           GLint error, GLint expectedError)
63 {
64     if (error != expectedError)
65     {
66         log << "QueryError [" << funcName << " return wrong error code"
67             << ", target: " << target << ", pname: " << pname << ", expected: " << expectedError
68             << ", returned: " << error << "] - ";
69 
70         return false;
71     }
72 
73     return true;
74 }
75 
76 /** Verifies last operation error and generate proper log message
77  *
78  * @param funcName         Verified function name
79  * @param mesage           Error message
80  * @param error            Generated error code
81  * @param expectedError    Expected error code
82  *
83  * @return Returns true if queried value is as expected, returns false otherwise
84  */
verifyError(std::stringstream & log,const char * funcName,GLint error,GLint expectedError)85 bool SparseTextureUtils::verifyError(std::stringstream &log, const char *funcName, GLint error, GLint expectedError)
86 {
87     if (error != expectedError)
88     {
89         log << "Error [" << funcName << " return wrong error code "
90             << ", expectedError: " << expectedError << ", returnedError: " << error << "] - ";
91 
92         return false;
93     }
94 
95     return true;
96 }
97 
98 /** Get minimal depth value for target
99  *
100  * @param target   Texture target
101  *
102  * @return Returns depth value
103  */
getTargetDepth(GLint target)104 GLint SparseTextureUtils::getTargetDepth(GLint target)
105 {
106     GLint depth;
107 
108     if (target == GL_TEXTURE_3D || target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY ||
109         target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE ||
110         target == GL_TEXTURE_CUBE_MAP)
111     {
112         depth = 1;
113     }
114     else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
115         depth = 6;
116     else
117         depth = 0;
118 
119     return depth;
120 }
121 
122 /** Queries for virtual page sizes
123  *
124  * @param gl           GL functions
125  * @param target       Texture target
126  * @param format       Texture internal format
127  * @param pageSizeX    Texture page size reference for X dimension
128  * @param pageSizeY    Texture page size reference for X dimension
129  * @param pageSizeZ    Texture page size reference for X dimension
130  **/
getTexturePageSizes(const glw::Functions & gl,glw::GLint target,glw::GLint format,glw::GLint & pageSizeX,glw::GLint & pageSizeY,glw::GLint & pageSizeZ)131 void SparseTextureUtils::getTexturePageSizes(const glw::Functions &gl, glw::GLint target, glw::GLint format,
132                                              glw::GLint &pageSizeX, glw::GLint &pageSizeY, glw::GLint &pageSizeZ)
133 {
134     gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &pageSizeX);
135     GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_X_ARB");
136 
137     gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &pageSizeY);
138     GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_Y_ARB");
139 
140     gl.getInternalformativ(target, format, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &pageSizeZ);
141     GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_VIRTUAL_PAGE_SIZE_Z_ARB");
142 }
143 
144 /** Calculate texture size for specific mipmap
145  *
146  * @param target  GL functions
147  * @param state   Texture current state
148  * @param level   Texture mipmap level
149  * @param width   Texture output width
150  * @param height  Texture output height
151  * @param depth   Texture output depth
152  **/
getTextureLevelSize(GLint target,TextureState & state,GLint level,GLint & width,GLint & height,GLint & depth)153 void SparseTextureUtils::getTextureLevelSize(GLint target, TextureState &state, GLint level, GLint &width,
154                                              GLint &height, GLint &depth)
155 {
156     width = state.width / (int)pow(2, level);
157     if (target == GL_TEXTURE_1D || target == GL_TEXTURE_1D_ARRAY)
158         height = 1;
159     else
160         height = state.height / (int)pow(2, level);
161 
162     if (target == GL_TEXTURE_3D)
163         depth = state.depth / (int)pow(2, level);
164     else if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY ||
165              target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
166         depth = state.depth;
167     else
168         depth = 1;
169 }
170 
171 /* Texture static fields */
172 const GLuint Texture::m_invalid_id = -1;
173 
174 /** Bind texture to target
175  *
176  * @param gl       GL API functions
177  * @param id       Id of texture
178  * @param tex_type Type of texture
179  **/
Bind(const Functions & gl,GLuint id,GLenum target)180 void Texture::Bind(const Functions &gl, GLuint id, GLenum target)
181 {
182     gl.bindTexture(target, id);
183     GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
184 }
185 
186 /** Generate texture instance
187  *
188  * @param gl     GL functions
189  * @param out_id Id of texture
190  **/
Generate(const Functions & gl,GLuint & out_id)191 void Texture::Generate(const Functions &gl, GLuint &out_id)
192 {
193     GLuint id = m_invalid_id;
194 
195     gl.genTextures(1, &id);
196     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
197 
198     if (m_invalid_id == id)
199     {
200         TCU_FAIL("Invalid id");
201     }
202 
203     out_id = id;
204 }
205 
206 /** Delete texture instance
207  *
208  * @param gl    GL functions
209  * @param id    Id of texture
210  **/
Delete(const Functions & gl,GLuint & id)211 void Texture::Delete(const Functions &gl, GLuint &id)
212 {
213     gl.deleteTextures(1, &id);
214     GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
215 }
216 
217 /** Allocate storage for texture
218  *
219  * @param gl              GL functions
220  * @param target          Texture target
221  * @param levels          Number of levels
222  * @param internal_format Internal format of texture
223  * @param width           Width of texture
224  * @param height          Height of texture
225  * @param depth           Depth of texture
226  **/
Storage(const Functions & gl,GLenum target,GLsizei levels,GLenum internal_format,GLuint width,GLuint height,GLuint depth)227 void Texture::Storage(const Functions &gl, GLenum target, GLsizei levels, GLenum internal_format, GLuint width,
228                       GLuint height, GLuint depth)
229 {
230     switch (target)
231     {
232     case GL_TEXTURE_1D:
233         gl.texStorage1D(target, levels, internal_format, width);
234         break;
235     case GL_TEXTURE_1D_ARRAY:
236         gl.texStorage2D(target, levels, internal_format, width, depth);
237         break;
238     case GL_TEXTURE_2D:
239     case GL_TEXTURE_RECTANGLE:
240     case GL_TEXTURE_CUBE_MAP:
241         gl.texStorage2D(target, levels, internal_format, width, height);
242         break;
243     case GL_TEXTURE_3D:
244     case GL_TEXTURE_2D_ARRAY:
245     case GL_TEXTURE_CUBE_MAP_ARRAY:
246         gl.texStorage3D(target, levels, internal_format, width, height, depth);
247         break;
248     case GL_TEXTURE_2D_MULTISAMPLE:
249         gl.texStorage2DMultisample(target, levels /* samples */, internal_format, width, height, GL_TRUE);
250         break;
251     case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
252         gl.texStorage3DMultisample(target, levels /* samples */, internal_format, width, height, depth, GL_TRUE);
253         break;
254     default:
255         TCU_FAIL("Invliad enum");
256     }
257 }
258 
259 /** Get texture data
260  *
261  * @param gl       GL functions
262  * @param target   Texture target
263  * @param format   Format of data
264  * @param type     Type of data
265  * @param out_data Buffer for data
266  **/
GetData(const glw::Functions & gl,glw::GLint level,glw::GLenum target,glw::GLenum format,glw::GLenum type,glw::GLvoid * out_data)267 void Texture::GetData(const glw::Functions &gl, glw::GLint level, glw::GLenum target, glw::GLenum format,
268                       glw::GLenum type, glw::GLvoid *out_data)
269 {
270     gl.getTexImage(target, level, format, type, out_data);
271 }
272 
273 /** Set contents of texture
274  *
275  * @param gl              GL functions
276  * @param target          Texture target
277  * @param level           Mipmap level
278  * @param x               X offset
279  * @param y               Y offset
280  * @param z               Z offset
281  * @param width           Width of texture
282  * @param height          Height of texture
283  * @param depth           Depth of texture
284  * @param format          Format of data
285  * @param type            Type of data
286  * @param pixels          Buffer with image data
287  **/
SubImage(const glw::Functions & gl,glw::GLenum target,glw::GLint level,glw::GLint x,glw::GLint y,glw::GLint z,glw::GLsizei width,glw::GLsizei height,glw::GLsizei depth,glw::GLenum format,glw::GLenum type,const glw::GLvoid * pixels)288 void Texture::SubImage(const glw::Functions &gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y,
289                        glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format,
290                        glw::GLenum type, const glw::GLvoid *pixels)
291 {
292     switch (target)
293     {
294     case GL_TEXTURE_1D:
295         gl.texSubImage1D(target, level, x, width, format, type, pixels);
296         break;
297     case GL_TEXTURE_1D_ARRAY:
298         gl.texSubImage2D(target, level, x, y, width, depth, format, type, pixels);
299         break;
300     case GL_TEXTURE_2D:
301     case GL_TEXTURE_RECTANGLE:
302         gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
303         break;
304     case GL_TEXTURE_CUBE_MAP:
305         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, x, y, width, height, format, type, pixels);
306         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, x, y, width, height, format, type, pixels);
307         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, x, y, width, height, format, type, pixels);
308         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, x, y, width, height, format, type, pixels);
309         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, x, y, width, height, format, type, pixels);
310         gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, x, y, width, height, format, type, pixels);
311         break;
312     case GL_TEXTURE_3D:
313     case GL_TEXTURE_2D_ARRAY:
314     case GL_TEXTURE_CUBE_MAP_ARRAY:
315         gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels);
316         break;
317     default:
318         TCU_FAIL("Invliad enum");
319     }
320 }
321 
322 /** Constructor.
323  *
324  *  @param context     Rendering context
325  */
TextureParameterQueriesTestCase(deqp::Context & context)326 TextureParameterQueriesTestCase::TextureParameterQueriesTestCase(deqp::Context &context)
327     : TestCase(
328           context, "TextureParameterQueries",
329           "Implements all glTexParameter* and glGetTexParameter* queries tests described in CTS_ARB_sparse_texture")
330 {
331     /* Left blank intentionally */
332 }
333 
334 /** Stub init method */
init()335 void TextureParameterQueriesTestCase::init()
336 {
337     mSupportedTargets.push_back(GL_TEXTURE_2D);
338     mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
339     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
340     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
341     mSupportedTargets.push_back(GL_TEXTURE_3D);
342     mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
343 
344     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
345     {
346         mNotSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
347         mNotSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
348     }
349 }
350 
351 /** Executes test iteration.
352  *
353  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
354  */
iterate()355 tcu::TestNode::IterateResult TextureParameterQueriesTestCase::iterate()
356 {
357     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
358     {
359         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
360         return STOP;
361     }
362 
363     const Functions &gl = m_context.getRenderContext().getFunctions();
364 
365     bool result = true;
366 
367     GLuint texture;
368 
369     //Iterate through supported targets
370 
371     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
372          ++iter)
373     {
374         const GLint &target = *iter;
375 
376         mLog.str("");
377 
378         Texture::Generate(gl, texture);
379         Texture::Bind(gl, texture, target);
380 
381         result = testTextureSparseARB(gl, target) && testVirtualPageSizeIndexARB(gl, target) &&
382                  testNumSparseLevelsARB(gl, target);
383 
384         Texture::Delete(gl, texture);
385 
386         if (!result)
387         {
388             m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail [positive tests]"
389                                << tcu::TestLog::EndMessage;
390             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
391             return STOP;
392         }
393     }
394 
395     //Iterate through not supported targets
396     for (std::vector<glw::GLint>::const_iterator iter = mNotSupportedTargets.begin();
397          iter != mNotSupportedTargets.end(); ++iter)
398     {
399         const GLint &target = *iter;
400 
401         mLog.str("");
402 
403         Texture::Generate(gl, texture);
404         Texture::Bind(gl, texture, target);
405 
406         result = testTextureSparseARB(gl, target, GL_INVALID_VALUE);
407 
408         Texture::Delete(gl, texture);
409 
410         if (!result)
411         {
412             m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail [positive tests]"
413                                << tcu::TestLog::EndMessage;
414             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail on negative tests");
415             return STOP;
416         }
417     }
418 
419     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
420     return STOP;
421 }
422 
423 /** Testing texParameter* functions for binded texture and GL_TEXTURE_SPARSE_ARB parameter name
424  *
425  * @param gl               GL API functions
426  * @param target           Target for which texture is binded
427  * @param expectedError    Expected error code (default value GL_NO_ERROR)
428  *
429  * @return Returns true if queried value is as expected, returns false otherwise
430  */
testTextureSparseARB(const Functions & gl,GLint target,GLint expectedError)431 bool TextureParameterQueriesTestCase::testTextureSparseARB(const Functions &gl, GLint target, GLint expectedError)
432 {
433     const GLint pname = GL_TEXTURE_SPARSE_ARB;
434 
435     bool result = true;
436 
437     GLint testValueInt;
438     GLuint testValueUInt;
439     GLfloat testValueFloat;
440 
441     mLog << "Testing TEXTURE_SPARSE_ARB for target: " << target << " - ";
442 
443     //Check getTexParameter* default value
444     if (expectedError == GL_NO_ERROR)
445         result = checkGetTexParameter(gl, target, pname, GL_FALSE);
446 
447     //Check getTexParameter* for manually set values
448     if (result)
449     {
450         //Query to set parameter
451         gl.texParameteri(target, pname, GL_TRUE);
452         if (expectedError == GL_NO_ERROR)
453         {
454             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
455             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
456 
457             //If no error verification reset TEXTURE_SPARSE_ARB value
458             gl.texParameteri(target, pname, GL_FALSE);
459             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
460         }
461         else
462             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, pname, gl.getError(),
463                                                           expectedError);
464     }
465 
466     if (result)
467     {
468         gl.texParameterf(target, pname, GL_TRUE);
469         if (expectedError == GL_NO_ERROR)
470         {
471             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf error occurred.");
472             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
473 
474             gl.texParameteri(target, pname, GL_FALSE);
475             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
476         }
477         else
478             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, pname, gl.getError(),
479                                                           expectedError);
480     }
481 
482     if (result)
483     {
484         testValueInt = GL_TRUE;
485         gl.texParameteriv(target, pname, &testValueInt);
486         if (expectedError == GL_NO_ERROR)
487         {
488             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteriv error occurred.");
489             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
490 
491             gl.texParameteri(target, pname, GL_FALSE);
492             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
493         }
494         else
495             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, pname, gl.getError(),
496                                                           expectedError);
497     }
498 
499     if (result)
500     {
501         testValueFloat = (GLfloat)GL_TRUE;
502         gl.texParameterfv(target, pname, &testValueFloat);
503         if (expectedError == GL_NO_ERROR)
504         {
505             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterfv error occurred.");
506             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
507 
508             gl.texParameteri(target, pname, GL_FALSE);
509             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
510         }
511         else
512             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, pname, gl.getError(),
513                                                           expectedError);
514     }
515 
516     if (result)
517     {
518         testValueInt = GL_TRUE;
519         gl.texParameterIiv(target, pname, &testValueInt);
520         if (expectedError == GL_NO_ERROR)
521         {
522             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIiv error occurred.");
523             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
524 
525             gl.texParameteri(target, pname, GL_FALSE);
526             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
527         }
528         else
529             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, pname, gl.getError(),
530                                                           expectedError);
531     }
532 
533     if (result)
534     {
535         testValueUInt = GL_TRUE;
536         gl.texParameterIuiv(target, pname, &testValueUInt);
537         if (expectedError == GL_NO_ERROR)
538         {
539             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIuiv error occurred.");
540             result = checkGetTexParameter(gl, target, pname, GL_TRUE);
541 
542             gl.texParameteri(target, pname, GL_FALSE);
543             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred.");
544         }
545         else
546             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, pname, gl.getError(),
547                                                           expectedError);
548     }
549 
550     return result;
551 }
552 
553 /** Testing texParameter* functions for binded texture and GL_VIRTUAL_PAGE_SIZE_INDEX_ARB parameter name
554  *
555  * @param gl               GL API functions
556  * @param target           Target for which texture is binded
557  * @param expectedError    Expected error code (default value GL_NO_ERROR)
558  *
559  * @return Returns true if queried value is as expected, returns false otherwise
560  */
testVirtualPageSizeIndexARB(const Functions & gl,GLint target,GLint expectedError)561 bool TextureParameterQueriesTestCase::testVirtualPageSizeIndexARB(const Functions &gl, GLint target,
562                                                                   GLint expectedError)
563 {
564     const GLint pname = GL_VIRTUAL_PAGE_SIZE_INDEX_ARB;
565 
566     bool result = true;
567 
568     GLint testValueInt;
569     GLuint testValueUInt;
570     GLfloat testValueFloat;
571 
572     mLog << "Testing VIRTUAL_PAGE_SIZE_INDEX_ARB for target: " << target << " - ";
573 
574     //Check getTexParameter* default value
575     if (expectedError == GL_NO_ERROR)
576         result = checkGetTexParameter(gl, target, pname, 0);
577 
578     //Check getTexParameter* for manually set values
579     if (result)
580     {
581         gl.texParameteri(target, pname, 1);
582         if (expectedError == GL_NO_ERROR)
583         {
584             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
585             result = checkGetTexParameter(gl, target, pname, 1);
586 
587             //If no error verification reset TEXTURE_SPARSE_ARB value
588             gl.texParameteri(target, pname, 0);
589             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
590         }
591         else
592             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, pname, gl.getError(),
593                                                           expectedError);
594     }
595 
596     if (result)
597     {
598         gl.texParameterf(target, pname, 2.0f);
599         if (expectedError == GL_NO_ERROR)
600         {
601             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf error occurred");
602             result = checkGetTexParameter(gl, target, pname, 2);
603 
604             gl.texParameteri(target, pname, 0);
605             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
606         }
607         else
608             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, pname, gl.getError(),
609                                                           expectedError);
610     }
611 
612     if (result)
613     {
614         testValueInt = 8;
615         gl.texParameteriv(target, pname, &testValueInt);
616         if (expectedError == GL_NO_ERROR)
617         {
618             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteriv error occurred");
619             result = checkGetTexParameter(gl, target, pname, 8);
620 
621             gl.texParameteri(target, pname, 0);
622             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
623         }
624         else
625             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, pname, gl.getError(),
626                                                           expectedError);
627     }
628 
629     if (result)
630     {
631         testValueFloat = 10.0f;
632         gl.texParameterfv(target, pname, &testValueFloat);
633         if (expectedError == GL_NO_ERROR)
634         {
635             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterfv error occurred");
636             result = checkGetTexParameter(gl, target, pname, 10);
637 
638             gl.texParameteri(target, pname, 0);
639             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
640         }
641         else
642             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, pname, gl.getError(),
643                                                           expectedError);
644     }
645 
646     if (result)
647     {
648         testValueInt = 6;
649         gl.texParameterIiv(target, pname, &testValueInt);
650         if (expectedError == GL_NO_ERROR)
651         {
652             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIiv error occurred");
653             result = checkGetTexParameter(gl, target, pname, 6);
654 
655             gl.texParameteri(target, pname, 0);
656             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
657         }
658         else
659             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, pname, gl.getError(),
660                                                           expectedError);
661     }
662 
663     if (result)
664     {
665         testValueUInt = 16;
666         gl.texParameterIuiv(target, pname, &testValueUInt);
667         if (expectedError == GL_NO_ERROR)
668         {
669             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterIuiv error occurred");
670             result = checkGetTexParameter(gl, target, pname, 16);
671 
672             gl.texParameteri(target, pname, 0);
673             GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri error occurred");
674         }
675         else
676             result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, pname, gl.getError(),
677                                                           expectedError);
678     }
679 
680     return result;
681 }
682 
683 /** Testing getTexParameter* functions for binded texture and GL_NUM_SPARSE_LEVELS_ARB parameter name
684  *
685  * @param gl               GL API functions
686  * @param target           Target for which texture is binded
687  * @param expectedError    Expected error code (default value GL_NO_ERROR)
688  *
689  * @return Returns true if no error code was generated, throws exception otherwise
690  */
testNumSparseLevelsARB(const Functions & gl,GLint target)691 bool TextureParameterQueriesTestCase::testNumSparseLevelsARB(const Functions &gl, GLint target)
692 {
693     const GLint pname = GL_NUM_SPARSE_LEVELS_ARB;
694 
695     bool result = true;
696 
697     GLint value_int;
698     GLuint value_uint;
699     GLfloat value_float;
700 
701     mLog << "Testing NUM_SPARSE_LEVELS_ARB for target: " << target << " - ";
702 
703     gl.getTexParameteriv(target, pname, &value_int);
704     result = SparseTextureUtils::verifyError(mLog, "glGetTexParameteriv", gl.getError(), GL_NO_ERROR);
705 
706     if (result)
707     {
708         gl.getTexParameterfv(target, pname, &value_float);
709         result = SparseTextureUtils::verifyError(mLog, "glGetTexParameterfv", gl.getError(), GL_NO_ERROR);
710 
711         if (result)
712         {
713             gl.getTexParameterIiv(target, pname, &value_int);
714             result = SparseTextureUtils::verifyError(mLog, "glGetGexParameterIiv", gl.getError(), GL_NO_ERROR);
715 
716             if (result)
717             {
718                 gl.getTexParameterIuiv(target, pname, &value_uint);
719                 result = SparseTextureUtils::verifyError(mLog, "getTexParameterIuiv", gl.getError(), GL_NO_ERROR);
720             }
721         }
722     }
723 
724     return result;
725 }
726 
727 /** Checking if getTexParameter* for binded texture returns value as expected
728  *
729  * @param gl           GL API functions
730  * @param target       Target for which texture is binded
731  * @param pname        Parameter name
732  * @param expected     Expected value (int because function is designed to query only int and boolean parameters)
733  *
734  * @return Returns true if queried value is as expected, returns false otherwise
735  */
checkGetTexParameter(const Functions & gl,GLint target,GLint pname,GLint expected)736 bool TextureParameterQueriesTestCase::checkGetTexParameter(const Functions &gl, GLint target, GLint pname,
737                                                            GLint expected)
738 {
739     bool result = true;
740 
741     GLint value_int;
742     GLuint value_uint;
743     GLfloat value_float;
744 
745     mLog << "Testing GetTexParameter for target: " << target << " - ";
746 
747     gl.getTexParameteriv(target, pname, &value_int);
748     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv error occurred");
749     if (value_int != expected)
750     {
751         mLog << "glGetTexParameteriv return wrong value"
752              << ", target: " << target << ", pname: " << pname << ", expected: " << expected
753              << ", returned: " << value_int << " - ";
754 
755         result = false;
756     }
757 
758     gl.getTexParameterfv(target, pname, &value_float);
759     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameterfv error occurred");
760     if ((GLint)value_float != expected)
761     {
762         mLog << "glGetTexParameterfv return wrong value"
763              << ", target: " << target << ", pname: " << pname << ", expected: " << expected
764              << ", returned: " << (GLint)value_float << " - ";
765 
766         result = false;
767     }
768 
769     gl.getTexParameterIiv(target, pname, &value_int);
770     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetGexParameterIiv error occurred");
771     if (value_int != expected)
772     {
773         mLog << "glGetGexParameterIiv return wrong value"
774              << ", target: " << target << ", pname: " << pname << ", expected: " << expected
775              << ", returned: " << value_int << " - ";
776 
777         result = false;
778     }
779 
780     gl.getTexParameterIuiv(target, pname, &value_uint);
781     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetGexParameterIui error occurred");
782     if ((GLint)value_uint != expected)
783     {
784         mLog << "glGetGexParameterIui return wrong value"
785              << ", target: " << target << ", pname: " << pname << ", expected: " << expected
786              << ", returned: " << (GLint)value_uint << " - ";
787 
788         result = false;
789     }
790 
791     return result;
792 }
793 
794 /** Constructor.
795  *
796  *  @param context     Rendering context
797  */
InternalFormatQueriesTestCase(deqp::Context & context)798 InternalFormatQueriesTestCase::InternalFormatQueriesTestCase(deqp::Context &context)
799     : TestCase(context, "InternalFormatQueries",
800                "Implements GetInternalformat query tests described in CTS_ARB_sparse_texture")
801 {
802     /* Left blank intentionally */
803 }
804 
805 /** Stub init method */
init()806 void InternalFormatQueriesTestCase::init()
807 {
808     mSupportedTargets.push_back(GL_TEXTURE_2D);
809     mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
810     mSupportedTargets.push_back(GL_TEXTURE_3D);
811     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
812     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
813     mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
814 
815     mSupportedInternalFormats.push_back(GL_R8);
816     mSupportedInternalFormats.push_back(GL_R8_SNORM);
817     mSupportedInternalFormats.push_back(GL_R16);
818     mSupportedInternalFormats.push_back(GL_R16_SNORM);
819     mSupportedInternalFormats.push_back(GL_RG8);
820     mSupportedInternalFormats.push_back(GL_RG8_SNORM);
821     mSupportedInternalFormats.push_back(GL_RG16);
822     mSupportedInternalFormats.push_back(GL_RG16_SNORM);
823     mSupportedInternalFormats.push_back(GL_RGB565);
824     mSupportedInternalFormats.push_back(GL_RGBA8);
825     mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
826     mSupportedInternalFormats.push_back(GL_RGB10_A2);
827     mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
828     mSupportedInternalFormats.push_back(GL_RGBA16);
829     mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
830     mSupportedInternalFormats.push_back(GL_R16F);
831     mSupportedInternalFormats.push_back(GL_RG16F);
832     mSupportedInternalFormats.push_back(GL_RGBA16F);
833     mSupportedInternalFormats.push_back(GL_R32F);
834     mSupportedInternalFormats.push_back(GL_RG32F);
835     mSupportedInternalFormats.push_back(GL_RGBA32F);
836     mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
837     mSupportedInternalFormats.push_back(GL_RGB9_E5);
838     mSupportedInternalFormats.push_back(GL_R8I);
839     mSupportedInternalFormats.push_back(GL_R8UI);
840     mSupportedInternalFormats.push_back(GL_R16I);
841     mSupportedInternalFormats.push_back(GL_R16UI);
842     mSupportedInternalFormats.push_back(GL_R32I);
843     mSupportedInternalFormats.push_back(GL_R32UI);
844     mSupportedInternalFormats.push_back(GL_RG8I);
845     mSupportedInternalFormats.push_back(GL_RG8UI);
846     mSupportedInternalFormats.push_back(GL_RG16I);
847     mSupportedInternalFormats.push_back(GL_RG16UI);
848     mSupportedInternalFormats.push_back(GL_RG32I);
849     mSupportedInternalFormats.push_back(GL_RG32UI);
850     mSupportedInternalFormats.push_back(GL_RGBA8I);
851     mSupportedInternalFormats.push_back(GL_RGBA8UI);
852     mSupportedInternalFormats.push_back(GL_RGBA16I);
853     mSupportedInternalFormats.push_back(GL_RGBA16UI);
854     mSupportedInternalFormats.push_back(GL_RGBA32I);
855 }
856 
857 /** Executes test iteration.
858  *
859  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
860  */
iterate()861 tcu::TestNode::IterateResult InternalFormatQueriesTestCase::iterate()
862 {
863     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
864     {
865         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
866         return STOP;
867     }
868 
869     const Functions &gl = m_context.getRenderContext().getFunctions();
870 
871     bool result = true;
872 
873     mLog << "Testing getInternalformativ - ";
874 
875     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
876          ++iter)
877     {
878         const GLint &target = *iter;
879 
880         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
881              formIter != mSupportedInternalFormats.end(); ++formIter)
882         {
883             const GLint &format = *formIter;
884             GLint value;
885 
886             gl.getInternalformativ(target, format, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &value);
887             GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ error occurred for GL_NUM_VIRTUAL_PAGE_SIZES_ARB");
888             if (value == 0)
889             {
890                 mLog << "getInternalformativ for GL_NUM_VIRTUAL_PAGE_SIZES_ARB, target: " << target
891                      << ", format: " << format << " returns wrong value: " << value << " - ";
892 
893                 result = false;
894             }
895 
896             if (result)
897             {
898                 GLint pageSizeX;
899                 GLint pageSizeY;
900                 GLint pageSizeZ;
901                 SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);
902             }
903             else
904             {
905                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
906                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
907                 return STOP;
908             }
909         }
910     }
911 
912     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
913 
914     return STOP;
915 }
916 
917 /** Constructor.
918  *
919  *  @param context     Rendering context
920  */
SimpleQueriesTestCase(deqp::Context & context)921 SimpleQueriesTestCase::SimpleQueriesTestCase(deqp::Context &context)
922     : TestCase(context, "SimpleQueries", "Implements Get* queries tests described in CTS_ARB_sparse_texture")
923 {
924     /* Left blank intentionally */
925 }
926 
927 /** Executes test iteration.
928  *
929  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
930  */
iterate()931 tcu::TestNode::IterateResult SimpleQueriesTestCase::iterate()
932 {
933     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
934     {
935         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
936         return STOP;
937     }
938 
939     const Functions &gl = m_context.getRenderContext().getFunctions();
940 
941     testSipmleQueries(gl, GL_MAX_SPARSE_TEXTURE_SIZE_ARB);
942     testSipmleQueries(gl, GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB);
943     testSipmleQueries(gl, GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB);
944     testSipmleQueries(gl, GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB);
945 
946     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
947     return STOP;
948 }
949 
testSipmleQueries(const Functions & gl,GLint pname)950 void SimpleQueriesTestCase::testSipmleQueries(const Functions &gl, GLint pname)
951 {
952     std::stringstream log;
953     log << "Testing simple query for pname: " << pname << " - ";
954 
955     bool result = true;
956 
957     GLint value_int;
958     GLint64 value_int64;
959     GLfloat value_float;
960     GLdouble value_double;
961     GLboolean value_bool;
962 
963     gl.getIntegerv(pname, &value_int);
964     result = SparseTextureUtils::verifyError(log, "getIntegerv", gl.getError(), GL_NO_ERROR);
965 
966     if (result)
967     {
968         gl.getInteger64v(pname, &value_int64);
969         result = SparseTextureUtils::verifyError(log, "getInteger64v", gl.getError(), GL_NO_ERROR);
970 
971         if (result)
972         {
973             gl.getFloatv(pname, &value_float);
974             result = SparseTextureUtils::verifyError(log, "getFloatv", gl.getError(), GL_NO_ERROR);
975 
976             if (result)
977             {
978                 gl.getDoublev(pname, &value_double);
979                 result = SparseTextureUtils::verifyError(log, "getDoublev", gl.getError(), GL_NO_ERROR);
980 
981                 if (result)
982                 {
983                     gl.getBooleanv(pname, &value_bool);
984                     result = SparseTextureUtils::verifyError(log, "getBooleanv", gl.getError(), GL_NO_ERROR);
985                 }
986             }
987         }
988     }
989 
990     if (!result)
991     {
992         TCU_FAIL(log.str().c_str());
993     }
994 }
995 
996 /** Constructor.
997  *
998  *  @param context     Rendering context
999  */
SparseTextureAllocationTestCase(deqp::Context & context)1000 SparseTextureAllocationTestCase::SparseTextureAllocationTestCase(deqp::Context &context)
1001     : TestCase(context, "SparseTextureAllocation", "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture")
1002 {
1003     /* Left blank intentionally */
1004 }
1005 
1006 /** Constructor.
1007  *
1008  *  @param context     Rendering context
1009  */
SparseTextureAllocationTestCase(deqp::Context & context,const char * name,const char * description)1010 SparseTextureAllocationTestCase::SparseTextureAllocationTestCase(deqp::Context &context, const char *name,
1011                                                                  const char *description)
1012     : TestCase(context, name, description)
1013 {
1014     /* Left blank intentionally */
1015 }
1016 
1017 /** Initializes the test group contents. */
init()1018 void SparseTextureAllocationTestCase::init()
1019 {
1020     mSupportedTargets.push_back(GL_TEXTURE_2D);
1021     mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
1022     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
1023     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
1024     mSupportedTargets.push_back(GL_TEXTURE_3D);
1025     mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
1026 
1027     mFullArrayTargets.push_back(GL_TEXTURE_2D_ARRAY);
1028     mFullArrayTargets.push_back(GL_TEXTURE_CUBE_MAP);
1029     mFullArrayTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
1030 
1031     mSupportedInternalFormats.push_back(GL_R8);
1032     mSupportedInternalFormats.push_back(GL_R8_SNORM);
1033     mSupportedInternalFormats.push_back(GL_R16);
1034     mSupportedInternalFormats.push_back(GL_R16_SNORM);
1035     mSupportedInternalFormats.push_back(GL_RG8);
1036     mSupportedInternalFormats.push_back(GL_RG8_SNORM);
1037     mSupportedInternalFormats.push_back(GL_RG16);
1038     mSupportedInternalFormats.push_back(GL_RG16_SNORM);
1039     mSupportedInternalFormats.push_back(GL_RGB565);
1040     mSupportedInternalFormats.push_back(GL_RGBA8);
1041     mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
1042     mSupportedInternalFormats.push_back(GL_RGB10_A2);
1043     mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
1044     mSupportedInternalFormats.push_back(GL_RGBA16);
1045     mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
1046     mSupportedInternalFormats.push_back(GL_R16F);
1047     mSupportedInternalFormats.push_back(GL_RG16F);
1048     mSupportedInternalFormats.push_back(GL_RGBA16F);
1049     mSupportedInternalFormats.push_back(GL_R32F);
1050     mSupportedInternalFormats.push_back(GL_RG32F);
1051     mSupportedInternalFormats.push_back(GL_RGBA32F);
1052     mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
1053     mSupportedInternalFormats.push_back(GL_RGB9_E5);
1054     mSupportedInternalFormats.push_back(GL_R8I);
1055     mSupportedInternalFormats.push_back(GL_R8UI);
1056     mSupportedInternalFormats.push_back(GL_R16I);
1057     mSupportedInternalFormats.push_back(GL_R16UI);
1058     mSupportedInternalFormats.push_back(GL_R32I);
1059     mSupportedInternalFormats.push_back(GL_R32UI);
1060     mSupportedInternalFormats.push_back(GL_RG8I);
1061     mSupportedInternalFormats.push_back(GL_RG8UI);
1062     mSupportedInternalFormats.push_back(GL_RG16I);
1063     mSupportedInternalFormats.push_back(GL_RG16UI);
1064     mSupportedInternalFormats.push_back(GL_RG32I);
1065     mSupportedInternalFormats.push_back(GL_RG32UI);
1066     mSupportedInternalFormats.push_back(GL_RGBA8I);
1067     mSupportedInternalFormats.push_back(GL_RGBA8UI);
1068     mSupportedInternalFormats.push_back(GL_RGBA16I);
1069     mSupportedInternalFormats.push_back(GL_RGBA16UI);
1070     mSupportedInternalFormats.push_back(GL_RGBA32I);
1071 }
1072 
1073 /** Executes test iteration.
1074  *
1075  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1076  */
iterate()1077 tcu::TestNode::IterateResult SparseTextureAllocationTestCase::iterate()
1078 {
1079     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
1080     {
1081         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1082         return STOP;
1083     }
1084 
1085     const Functions &gl = m_context.getRenderContext().getFunctions();
1086 
1087     bool result = true;
1088 
1089     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
1090          ++iter)
1091     {
1092         const GLint &target = *iter;
1093 
1094         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1095              formIter != mSupportedInternalFormats.end(); ++formIter)
1096         {
1097             const GLint &format = *formIter;
1098 
1099             mLog.str("");
1100             mLog << "Testing sparse texture allocation for target: " << target << ", format: " << format << " - ";
1101 
1102             result = positiveTesting(gl, target, format) && verifyTexParameterErrors(gl, target, format) &&
1103                      verifyTexStorageVirtualPageSizeIndexError(gl, target, format) &&
1104                      verifyTexStorageFullArrayCubeMipmapsError(gl, target, format) &&
1105                      verifyTexStorageInvalidValueErrors(gl, target, format);
1106 
1107             if (!result)
1108             {
1109                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1110                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1111                 return STOP;
1112             }
1113         }
1114     }
1115 
1116     for (std::vector<glw::GLint>::const_iterator iter = mFullArrayTargets.begin(); iter != mFullArrayTargets.end();
1117          ++iter)
1118     {
1119         const GLint &target = *iter;
1120 
1121         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1122              formIter != mSupportedInternalFormats.end(); ++formIter)
1123         {
1124             const GLint &format = *formIter;
1125 
1126             mLog.str("");
1127             mLog << "Testing sparse texture allocation for target [full array]: " << target << ", format: " << format
1128                  << " - ";
1129 
1130             result = verifyTexStorageFullArrayCubeMipmapsError(gl, target, format);
1131 
1132             if (!result)
1133             {
1134                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1135                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1136                 return STOP;
1137             }
1138         }
1139     }
1140 
1141     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1142     return STOP;
1143 }
1144 
1145 /** Testing if texStorage* functionality added in ARB_sparse_texture extension works properly for given target and internal format
1146  *
1147  * @param gl           GL API functions
1148  * @param target       Target for which texture is binded
1149  * @param format       Texture internal format
1150  *
1151  * @return Returns true if no errors occurred, false otherwise.
1152  **/
positiveTesting(const Functions & gl,GLint target,GLint format)1153 bool SparseTextureAllocationTestCase::positiveTesting(const Functions &gl, GLint target, GLint format)
1154 {
1155     mLog << "Positive Testing - ";
1156 
1157     GLuint texture;
1158 
1159     Texture::Generate(gl, texture);
1160     Texture::Bind(gl, texture, target);
1161 
1162     GLint pageSizeX;
1163     GLint pageSizeY;
1164     GLint pageSizeZ;
1165     GLint depth = SparseTextureUtils::getTargetDepth(target);
1166     SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);
1167 
1168     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
1169     if (!SparseTextureUtils::verifyError(mLog, "texParameteri", gl.getError(), GL_NO_ERROR))
1170     {
1171         Texture::Delete(gl, texture);
1172         return false;
1173     }
1174 
1175     //The <width> and <height> has to be equal for cube map textures
1176     if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
1177     {
1178         if (pageSizeX > pageSizeY)
1179             pageSizeY = pageSizeX;
1180         else if (pageSizeX < pageSizeY)
1181             pageSizeX = pageSizeY;
1182     }
1183 
1184     Texture::Storage(gl, target, 1, format, pageSizeX, pageSizeY, depth * pageSizeZ);
1185     if (!SparseTextureUtils::verifyError(mLog, "Texture::Storage", gl.getError(), GL_NO_ERROR))
1186     {
1187         Texture::Delete(gl, texture);
1188         return false;
1189     }
1190 
1191     Texture::Delete(gl, texture);
1192     return true;
1193 }
1194 
1195 /** Verifies if texParameter* generate proper errors for given target and internal format.
1196  *
1197  * @param gl           GL API functions
1198  * @param target       Target for which texture is binded
1199  * @param format       Texture internal format
1200  *
1201  * @return Returns true if errors are as expected, false otherwise.
1202  */
verifyTexParameterErrors(const Functions & gl,GLint target,GLint format)1203 bool SparseTextureAllocationTestCase::verifyTexParameterErrors(const Functions &gl, GLint target, GLint format)
1204 {
1205     mLog << "Verify TexParameter errors - ";
1206 
1207     bool result = true;
1208 
1209     GLuint texture;
1210     GLint depth;
1211 
1212     Texture::Generate(gl, texture);
1213     Texture::Bind(gl, texture, target);
1214 
1215     depth = SparseTextureUtils::getTargetDepth(target);
1216 
1217     Texture::Storage(gl, target, 1, format, 8, 8, depth);
1218     if (!SparseTextureUtils::verifyError(mLog, "TexStorage", gl.getError(), GL_NO_ERROR))
1219     {
1220         Texture::Delete(gl, texture);
1221         return false;
1222     }
1223 
1224     GLint immutableFormat;
1225 
1226     gl.getTexParameteriv(target, GL_TEXTURE_IMMUTABLE_FORMAT, &immutableFormat);
1227     if (!SparseTextureUtils::verifyQueryError(mLog, "getTexParameteriv", target, GL_TEXTURE_IMMUTABLE_FORMAT,
1228                                               gl.getError(), GL_NO_ERROR))
1229     {
1230         Texture::Delete(gl, texture);
1231         return false;
1232     }
1233 
1234     // Test error only if texture is immutable format, otherwise skip
1235     if (immutableFormat == GL_TRUE)
1236     {
1237         std::vector<IntPair> params;
1238         params.push_back(IntPair(GL_TEXTURE_SPARSE_ARB, GL_TRUE));
1239         params.push_back(IntPair(GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, 1));
1240 
1241         for (std::vector<IntPair>::const_iterator iter = params.begin(); iter != params.end(); ++iter)
1242         {
1243             const IntPair &param = *iter;
1244 
1245             if (result)
1246             {
1247                 gl.texParameteri(target, param.first, param.second);
1248                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteri", target, param.first,
1249                                                               gl.getError(), GL_INVALID_OPERATION);
1250             }
1251 
1252             if (result)
1253             {
1254                 gl.texParameterf(target, param.first, (GLfloat)param.second);
1255                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterf", target, param.first,
1256                                                               gl.getError(), GL_INVALID_OPERATION);
1257             }
1258 
1259             if (result)
1260             {
1261                 GLint value = param.second;
1262                 gl.texParameteriv(target, param.first, &value);
1263                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameteriv", target, param.first,
1264                                                               gl.getError(), GL_INVALID_OPERATION);
1265             }
1266 
1267             if (result)
1268             {
1269                 GLfloat value = (GLfloat)param.second;
1270                 gl.texParameterfv(target, param.first, &value);
1271                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterfv", target, param.first,
1272                                                               gl.getError(), GL_INVALID_OPERATION);
1273             }
1274 
1275             if (result)
1276             {
1277                 GLint value = param.second;
1278                 gl.texParameterIiv(target, param.first, &value);
1279                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIiv", target, param.first,
1280                                                               gl.getError(), GL_INVALID_OPERATION);
1281             }
1282 
1283             if (result)
1284             {
1285                 GLuint value = param.second;
1286                 gl.texParameterIuiv(target, param.first, &value);
1287                 result = SparseTextureUtils::verifyQueryError(mLog, "glTexParameterIuiv", target, param.first,
1288                                                               gl.getError(), GL_INVALID_OPERATION);
1289             }
1290         }
1291     }
1292 
1293     Texture::Delete(gl, texture);
1294     return result;
1295 }
1296 
1297 /** Verifies if texStorage* generate proper error for given target and internal format when
1298  *  VIRTUAL_PAGE_SIZE_INDEX_ARB value is greater than NUM_VIRTUAL_PAGE_SIZES_ARB.
1299  *
1300  * @param gl           GL API functions
1301  * @param target       Target for which texture is binded
1302  * @param format       Texture internal format
1303  *
1304  * @return Returns true if errors are as expected, false otherwise.
1305  */
verifyTexStorageVirtualPageSizeIndexError(const Functions & gl,GLint target,GLint format)1306 bool SparseTextureAllocationTestCase::verifyTexStorageVirtualPageSizeIndexError(const Functions &gl, GLint target,
1307                                                                                 GLint format)
1308 {
1309     mLog << "Verify VirtualPageSizeIndex errors - ";
1310 
1311     GLuint texture;
1312     GLint depth;
1313     GLint numPageSizes;
1314 
1315     Texture::Generate(gl, texture);
1316     Texture::Bind(gl, texture, target);
1317 
1318     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
1319     if (!SparseTextureUtils::verifyQueryError(mLog, "texParameteri", target, GL_TEXTURE_SPARSE_ARB, gl.getError(),
1320                                               GL_NO_ERROR))
1321     {
1322         Texture::Delete(gl, texture);
1323         return false;
1324     }
1325 
1326     gl.getInternalformativ(target, format, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &numPageSizes);
1327     if (!SparseTextureUtils::verifyQueryError(mLog, "getInternalformativ", target, GL_NUM_VIRTUAL_PAGE_SIZES_ARB,
1328                                               gl.getError(), GL_NO_ERROR))
1329     {
1330         Texture::Delete(gl, texture);
1331         return false;
1332     }
1333 
1334     numPageSizes += 1;
1335     gl.texParameteri(target, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, numPageSizes);
1336     if (!SparseTextureUtils::verifyQueryError(mLog, "texParameteri", target, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB,
1337                                               gl.getError(), GL_NO_ERROR))
1338     {
1339         Texture::Delete(gl, texture);
1340         return false;
1341     }
1342 
1343     depth = SparseTextureUtils::getTargetDepth(target);
1344 
1345     Texture::Storage(gl, target, 1, format, 8, 8, depth);
1346     if (!SparseTextureUtils::verifyError(mLog, "TexStorage", gl.getError(), GL_INVALID_OPERATION))
1347     {
1348         Texture::Delete(gl, texture);
1349         return false;
1350     }
1351 
1352     Texture::Delete(gl, texture);
1353     return true;
1354 }
1355 
1356 /** Verifies if texStorage* generate proper errors for given target and internal format and
1357  *  SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB value set to FALSE.
1358  *
1359  * @param gl           GL API functions
1360  * @param target       Target for which texture is binded
1361  * @param format       Texture internal format
1362  *
1363  * @return Returns true if errors are as expected, false otherwise.
1364  */
verifyTexStorageFullArrayCubeMipmapsError(const Functions & gl,GLint target,GLint format)1365 bool SparseTextureAllocationTestCase::verifyTexStorageFullArrayCubeMipmapsError(const Functions &gl, GLint target,
1366                                                                                 GLint format)
1367 {
1368     mLog << "Verify FullArrayCubeMipmaps errors - ";
1369 
1370     bool result = true;
1371 
1372     GLuint texture;
1373     GLint depth;
1374 
1375     depth = SparseTextureUtils::getTargetDepth(target);
1376 
1377     GLboolean fullArrayCubeMipmaps;
1378 
1379     gl.getBooleanv(GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB, &fullArrayCubeMipmaps);
1380     if (!SparseTextureUtils::verifyQueryError(
1381             mLog, "getBooleanv", target, GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB, gl.getError(), GL_NO_ERROR))
1382         return false;
1383 
1384     if (fullArrayCubeMipmaps == GL_FALSE &&
1385         (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY))
1386     {
1387         Texture::Generate(gl, texture);
1388         Texture::Bind(gl, texture, target);
1389 
1390         GLint pageSizeX;
1391         GLint pageSizeY;
1392         GLint pageSizeZ;
1393         SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);
1394 
1395         gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
1396 
1397         GLint levels = 4;
1398         GLint width  = pageSizeX * (int)pow(2, levels - 1);
1399         GLint height = pageSizeY * (int)pow(2, levels - 1);
1400 
1401         // Check 2 different cases:
1402         // 1) wrong width
1403         // 2) wrong height
1404         if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
1405         {
1406             GLint widthHeight = de::max(width, height);
1407             GLint pageSize    = de::max(pageSizeX, pageSizeY);
1408             Texture::Storage(gl, target, levels, format, widthHeight + pageSize, widthHeight + pageSize, depth);
1409             result =
1410                 SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_OPERATION);
1411         }
1412         else
1413         {
1414             Texture::Storage(gl, target, levels, format, width + pageSizeX, height, depth);
1415             result =
1416                 SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_OPERATION);
1417 
1418             if (result)
1419             {
1420                 Texture::Storage(gl, target, levels, format, width, height + pageSizeY, depth);
1421                 result = SparseTextureUtils::verifyError(mLog, "TexStorage [wrong height]", gl.getError(),
1422                                                          GL_INVALID_OPERATION);
1423             }
1424         }
1425 
1426         Texture::Delete(gl, texture);
1427     }
1428 
1429     return result;
1430 }
1431 
1432 /** Verifies if texStorage* generate proper errors for given target and internal format when
1433  *  texture size are set greater than allowed.
1434  *
1435  * @param gl           GL API functions
1436  * @param target       Target for which texture is binded
1437  * @param format       Texture internal format
1438  *
1439  * @return Returns true if errors are as expected, false otherwise.
1440  */
verifyTexStorageInvalidValueErrors(const Functions & gl,GLint target,GLint format)1441 bool SparseTextureAllocationTestCase::verifyTexStorageInvalidValueErrors(const Functions &gl, GLint target,
1442                                                                          GLint format)
1443 {
1444     mLog << "Verify Invalid Value errors - ";
1445 
1446     GLuint texture;
1447 
1448     Texture::Generate(gl, texture);
1449     Texture::Bind(gl, texture, target);
1450 
1451     GLint pageSizeX;
1452     GLint pageSizeY;
1453     GLint pageSizeZ;
1454     SparseTextureUtils::getTexturePageSizes(gl, target, format, pageSizeX, pageSizeY, pageSizeZ);
1455 
1456     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
1457 
1458     GLint width  = pageSizeX;
1459     GLint height = pageSizeY;
1460     GLint depth  = SparseTextureUtils::getTargetDepth(target) * pageSizeZ;
1461 
1462     if (target == GL_TEXTURE_3D)
1463     {
1464         GLint max3DTextureSize;
1465 
1466         gl.getIntegerv(GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB, &max3DTextureSize);
1467         if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB,
1468                                                   gl.getError(), GL_NO_ERROR))
1469         {
1470             Texture::Delete(gl, texture);
1471             return false;
1472         }
1473 
1474         // Check 3 different cases:
1475         // 1) wrong width
1476         // 2) wrong height
1477         // 3) wrong depth
1478         Texture::Storage(gl, target, 1, format, width + max3DTextureSize, height, depth);
1479         if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong width]", gl.getError(),
1480                                              GL_INVALID_VALUE))
1481         {
1482             Texture::Delete(gl, texture);
1483             return false;
1484         }
1485 
1486         Texture::Storage(gl, target, 1, format, width, height + max3DTextureSize, depth);
1487         if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong height]", gl.getError(),
1488                                              GL_INVALID_VALUE))
1489         {
1490             Texture::Delete(gl, texture);
1491             return false;
1492         }
1493 
1494         // Check for GL_NV_deep_texture3D support, if so we'll need to check
1495         // against the depth limit instead of the generic 3D texture size limit
1496         if (m_context.getContextInfo().isExtensionSupported("GL_NV_deep_texture3D"))
1497         {
1498 
1499             // Ensure that width and height are within the valid bounds for a
1500             // deep texture
1501             GLint maxTextureWidthHeight;
1502             gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &maxTextureWidthHeight);
1503 
1504             if (width < maxTextureWidthHeight && height < maxTextureWidthHeight)
1505             {
1506                 gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &max3DTextureSize);
1507             }
1508         }
1509 
1510         Texture::Storage(gl, target, 1, format, width, height, depth + max3DTextureSize);
1511         if (!SparseTextureUtils::verifyError(mLog, "TexStorage [GL_TEXTURE_3D wrong depth]", gl.getError(),
1512                                              GL_INVALID_VALUE))
1513         {
1514             Texture::Delete(gl, texture);
1515             return false;
1516         }
1517     }
1518     else
1519     {
1520         GLint maxTextureSize;
1521 
1522         gl.getIntegerv(GL_MAX_SPARSE_TEXTURE_SIZE_ARB, &maxTextureSize);
1523         if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_TEXTURE_SIZE_ARB,
1524                                                   gl.getError(), GL_NO_ERROR))
1525         {
1526             Texture::Delete(gl, texture);
1527             return false;
1528         }
1529 
1530         // Check 3 different cases:
1531         // 1) wrong width
1532         // 2) wrong height
1533         Texture::Storage(gl, target, 1, format, width + maxTextureSize, height, depth);
1534         if (!SparseTextureUtils::verifyError(mLog, "TexStorage [!GL_TEXTURE_3D wrong width]", gl.getError(),
1535                                              GL_INVALID_VALUE))
1536         {
1537             Texture::Delete(gl, texture);
1538             return false;
1539         }
1540 
1541         if (target != GL_TEXTURE_1D_ARRAY)
1542         {
1543             Texture::Storage(gl, target, 1, format, width, height + maxTextureSize, depth);
1544             if (!SparseTextureUtils::verifyError(mLog, "TexStorage [!GL_TEXTURE_3D wrong height]", gl.getError(),
1545                                                  GL_INVALID_VALUE))
1546             {
1547                 Texture::Delete(gl, texture);
1548                 return false;
1549             }
1550         }
1551 
1552         GLint maxArrayTextureLayers;
1553 
1554         gl.getIntegerv(GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB, &maxArrayTextureLayers);
1555         if (!SparseTextureUtils::verifyQueryError(mLog, "getIntegerv", target, GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB,
1556                                                   gl.getError(), GL_NO_ERROR))
1557         {
1558             Texture::Delete(gl, texture);
1559             return false;
1560         }
1561 
1562         if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
1563         {
1564             Texture::Storage(gl, target, 1, format, width, height, depth + maxArrayTextureLayers);
1565             if (!SparseTextureUtils::verifyError(mLog, "TexStorage [ARRAY wrong depth]", gl.getError(),
1566                                                  GL_INVALID_VALUE))
1567             {
1568                 Texture::Delete(gl, texture);
1569                 return false;
1570             }
1571         }
1572     }
1573 
1574     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
1575     {
1576         if (pageSizeX > 1)
1577         {
1578             Texture::Storage(gl, target, 1, format, pageSizeX + 1, height, depth);
1579             if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong width]", gl.getError(), GL_INVALID_VALUE))
1580             {
1581                 Texture::Delete(gl, texture);
1582                 return false;
1583             }
1584         }
1585 
1586         if (pageSizeY > 1)
1587         {
1588             Texture::Storage(gl, target, 1, format, width, pageSizeY + 1, depth);
1589             if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong height]", gl.getError(), GL_INVALID_VALUE))
1590             {
1591                 Texture::Delete(gl, texture);
1592                 return false;
1593             }
1594         }
1595 
1596         if (pageSizeZ > 1)
1597         {
1598             Texture::Storage(gl, target, 1, format, width, height, pageSizeZ + 1);
1599             if (!SparseTextureUtils::verifyError(mLog, "TexStorage [wrong depth]", gl.getError(), GL_INVALID_VALUE))
1600             {
1601                 Texture::Delete(gl, texture);
1602                 return false;
1603             }
1604         }
1605     }
1606 
1607     Texture::Delete(gl, texture);
1608     return true;
1609 }
1610 
1611 /** Constructor.
1612  *
1613  *  @param context     Rendering context
1614  */
SparseTextureCommitmentTestCase(deqp::Context & context)1615 SparseTextureCommitmentTestCase::SparseTextureCommitmentTestCase(deqp::Context &context)
1616     : TestCase(context, "SparseTextureCommitment",
1617                "Verifies TexPageCommitmentARB functionality added in CTS_ARB_sparse_texture")
1618     , mState()
1619 {
1620     /* Left blank intentionally */
1621 }
1622 
1623 /** Constructor.
1624  *
1625  *  @param context     Rendering context
1626  *  @param name        Test name
1627  *  @param description Test description
1628  */
SparseTextureCommitmentTestCase(deqp::Context & context,const char * name,const char * description)1629 SparseTextureCommitmentTestCase::SparseTextureCommitmentTestCase(deqp::Context &context, const char *name,
1630                                                                  const char *description)
1631     : TestCase(context, name, description)
1632     , mState()
1633 {
1634     /* Left blank intentionally */
1635 }
1636 
1637 /** Initializes the test case. */
init()1638 void SparseTextureCommitmentTestCase::init()
1639 {
1640     mSupportedTargets.push_back(GL_TEXTURE_2D);
1641     mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
1642     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
1643     mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
1644     mSupportedTargets.push_back(GL_TEXTURE_3D);
1645     mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
1646 
1647     mSupportedInternalFormats.push_back(GL_R8);
1648     mSupportedInternalFormats.push_back(GL_R8_SNORM);
1649     mSupportedInternalFormats.push_back(GL_R16);
1650     mSupportedInternalFormats.push_back(GL_R16_SNORM);
1651     mSupportedInternalFormats.push_back(GL_RG8);
1652     mSupportedInternalFormats.push_back(GL_RG8_SNORM);
1653     mSupportedInternalFormats.push_back(GL_RG16);
1654     mSupportedInternalFormats.push_back(GL_RG16_SNORM);
1655     mSupportedInternalFormats.push_back(GL_RGB565);
1656     mSupportedInternalFormats.push_back(GL_RGBA8);
1657     mSupportedInternalFormats.push_back(GL_RGBA8_SNORM);
1658     mSupportedInternalFormats.push_back(GL_RGB10_A2);
1659     mSupportedInternalFormats.push_back(GL_RGB10_A2UI);
1660     mSupportedInternalFormats.push_back(GL_RGBA16);
1661     mSupportedInternalFormats.push_back(GL_RGBA16_SNORM);
1662     mSupportedInternalFormats.push_back(GL_R16F);
1663     mSupportedInternalFormats.push_back(GL_RG16F);
1664     mSupportedInternalFormats.push_back(GL_RGBA16F);
1665     mSupportedInternalFormats.push_back(GL_R32F);
1666     mSupportedInternalFormats.push_back(GL_RG32F);
1667     mSupportedInternalFormats.push_back(GL_RGBA32F);
1668     mSupportedInternalFormats.push_back(GL_R11F_G11F_B10F);
1669     mSupportedInternalFormats.push_back(GL_RGB9_E5);
1670     mSupportedInternalFormats.push_back(GL_R8I);
1671     mSupportedInternalFormats.push_back(GL_R8UI);
1672     mSupportedInternalFormats.push_back(GL_R16I);
1673     mSupportedInternalFormats.push_back(GL_R16UI);
1674     mSupportedInternalFormats.push_back(GL_R32I);
1675     mSupportedInternalFormats.push_back(GL_R32UI);
1676     mSupportedInternalFormats.push_back(GL_RG8I);
1677     mSupportedInternalFormats.push_back(GL_RG8UI);
1678     mSupportedInternalFormats.push_back(GL_RG16I);
1679     mSupportedInternalFormats.push_back(GL_RG16UI);
1680     mSupportedInternalFormats.push_back(GL_RG32I);
1681     mSupportedInternalFormats.push_back(GL_RG32UI);
1682     mSupportedInternalFormats.push_back(GL_RGBA8I);
1683     mSupportedInternalFormats.push_back(GL_RGBA8UI);
1684     mSupportedInternalFormats.push_back(GL_RGBA16I);
1685     mSupportedInternalFormats.push_back(GL_RGBA16UI);
1686     mSupportedInternalFormats.push_back(GL_RGBA32I);
1687 }
1688 
1689 /** Executes test iteration.
1690  *
1691  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1692  */
iterate()1693 tcu::TestNode::IterateResult SparseTextureCommitmentTestCase::iterate()
1694 {
1695     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
1696     {
1697         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1698         return STOP;
1699     }
1700 
1701     const Functions &gl = m_context.getRenderContext().getFunctions();
1702 
1703     bool result = true;
1704 
1705     GLuint texture;
1706 
1707     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
1708          ++iter)
1709     {
1710         const GLint &target = *iter;
1711 
1712         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1713              formIter != mSupportedInternalFormats.end(); ++formIter)
1714         {
1715             const GLint &format = *formIter;
1716 
1717             if (!caseAllowed(target, format))
1718                 continue;
1719 
1720             mLog.str("");
1721             mLog << "Testing sparse texture commitment for target: " << target << ", format: " << format << " - ";
1722 
1723             //Checking if written data into not committed region generates no error
1724             sparseAllocateTexture(gl, target, format, texture, 3);
1725             for (int l = 0; l < mState.levels; ++l)
1726                 writeDataToTexture(gl, target, format, texture, l);
1727 
1728             //Checking if written data into committed region is as expected
1729             for (int l = 0; l < mState.levels; ++l)
1730             {
1731                 if (commitTexturePage(gl, target, format, texture, l))
1732                 {
1733                     writeDataToTexture(gl, target, format, texture, l);
1734                     result = verifyTextureData(gl, target, format, texture, l);
1735                 }
1736 
1737                 if (!result)
1738                     break;
1739             }
1740 
1741             Texture::Delete(gl, texture);
1742 
1743             //verify errors
1744             result = result && verifyInvalidOperationErrors(gl, target, format, texture);
1745             result = result && verifyInvalidValueErrors(gl, target, format, texture);
1746 
1747             if (!result)
1748             {
1749                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1750                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1751                 return STOP;
1752             }
1753         }
1754     }
1755 
1756     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1757     return STOP;
1758 }
1759 
1760 /** Bind texPageCommitmentARB function
1761  *
1762  * @param gl           GL API functions
1763  * @param target       Target for which texture is binded
1764  * @param format       Texture internal format
1765  * @param texture      Texture object
1766  * @param xOffset      Texture commitment x offset
1767  * @param yOffset      Texture commitment y offset
1768  * @param zOffset      Texture commitment z offset
1769  * @param width        Texture commitment width
1770  * @param height       Texture commitment height
1771  * @param depth        Texture commitment depth
1772  * @param commit       Commit or de-commit indicator
1773  **/
texPageCommitment(const glw::Functions & gl,glw::GLint target,glw::GLint format,glw::GLuint & texture,GLint level,GLint xOffset,GLint yOffset,GLint zOffset,GLint width,GLint height,GLint depth,GLboolean commit)1774 void SparseTextureCommitmentTestCase::texPageCommitment(const glw::Functions &gl, glw::GLint target, glw::GLint format,
1775                                                         glw::GLuint &texture, GLint level, GLint xOffset, GLint yOffset,
1776                                                         GLint zOffset, GLint width, GLint height, GLint depth,
1777                                                         GLboolean commit)
1778 {
1779     DE_UNREF(format);
1780     Texture::Bind(gl, texture, target);
1781 
1782     gl.texPageCommitmentARB(target, level, xOffset, yOffset, zOffset, width, height, depth, commit);
1783 }
1784 
1785 /** Check if specific combination of target and format is allowed
1786  *
1787  * @param target       Target for which texture is binded
1788  * @param format       Texture internal format
1789  *
1790  * @return Returns true if target/format combination is allowed, false otherwise.
1791  */
caseAllowed(GLint target,GLint format)1792 bool SparseTextureCommitmentTestCase::caseAllowed(GLint target, GLint format)
1793 {
1794     DE_UNREF(target);
1795     DE_UNREF(format);
1796     return true;
1797 }
1798 
1799 /** Preparing texture
1800  *
1801  * @param gl           GL API functions
1802  * @param target       Target for which texture is binded
1803  * @param format       Texture internal format
1804  * @param texture      Texture object
1805  *
1806  * @return Returns true if no error occurred, otherwise throws an exception.
1807  */
prepareTexture(const Functions & gl,GLint target,GLint format,GLuint & texture)1808 bool SparseTextureCommitmentTestCase::prepareTexture(const Functions &gl, GLint target, GLint format, GLuint &texture)
1809 {
1810     Texture::Generate(gl, texture);
1811     Texture::Bind(gl, texture, target);
1812 
1813     mState.minDepth = SparseTextureUtils::getTargetDepth(target);
1814     SparseTextureUtils::getTexturePageSizes(gl, target, format, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ);
1815 
1816     //The <width> and <height> has to be equal for cube map textures
1817     if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
1818     {
1819         if (mState.pageSizeX > mState.pageSizeY)
1820             mState.pageSizeY = mState.pageSizeX;
1821         else if (mState.pageSizeX < mState.pageSizeY)
1822             mState.pageSizeX = mState.pageSizeY;
1823     }
1824 
1825     mState.width  = 2 * mState.pageSizeX;
1826     mState.height = 2 * mState.pageSizeY;
1827     mState.depth  = 2 * mState.pageSizeZ * mState.minDepth;
1828 
1829     mState.format = glu::mapGLInternalFormat(format);
1830 
1831     return true;
1832 }
1833 
1834 /** Allocating sparse texture memory using texStorage* function
1835  *
1836  * @param gl           GL API functions
1837  * @param target       Target for which texture is binded
1838  * @param format       Texture internal format
1839  * @param texture      Texture object
1840  * @param levels       Texture mipmaps level
1841  *
1842  * @return Returns true if no error occurred, otherwise throws an exception.
1843  */
sparseAllocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)1844 bool SparseTextureCommitmentTestCase::sparseAllocateTexture(const Functions &gl, GLint target, GLint format,
1845                                                             GLuint &texture, GLint levels)
1846 {
1847     mLog << "Sparse Allocate [levels: " << levels << "] - ";
1848 
1849     prepareTexture(gl, target, format, texture);
1850 
1851     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
1852     GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");
1853 
1854     // GL_TEXTURE_RECTANGLE can have only one level
1855     mState.levels = target == GL_TEXTURE_RECTANGLE ? 1 : levels;
1856 
1857     Texture::Storage(gl, target, mState.levels, format, mState.width, mState.height, mState.depth);
1858     GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
1859 
1860     return true;
1861 }
1862 
1863 /** Allocating texture memory using texStorage* function
1864  *
1865  * @param gl           GL API functions
1866  * @param target       Target for which texture is binded
1867  * @param format       Texture internal format
1868  * @param texture      Texture object
1869  * @param levels       Texture mipmaps level
1870  *
1871  * @return Returns true if no error occurred, otherwise throws an exception.
1872  */
allocateTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint levels)1873 bool SparseTextureCommitmentTestCase::allocateTexture(const Functions &gl, GLint target, GLint format, GLuint &texture,
1874                                                       GLint levels)
1875 {
1876     mLog << "Allocate [levels: " << levels << "] - ";
1877 
1878     prepareTexture(gl, target, format, texture);
1879 
1880     //GL_TEXTURE_RECTANGLE can have only one level
1881     if (target != GL_TEXTURE_RECTANGLE)
1882         mState.levels = levels;
1883     else
1884         mState.levels = 1;
1885 
1886     Texture::Storage(gl, target, mState.levels, format, mState.width, mState.height, mState.depth);
1887     GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
1888 
1889     return true;
1890 }
1891 
1892 /** Writing data to generated texture
1893  *
1894  * @param gl           GL API functions
1895  * @param target       Target for which texture is binded
1896  * @param format       Texture internal format
1897  * @param texture      Texture object
1898  *
1899  * @return Returns true if no error occurred, otherwise throws an exception.
1900  */
writeDataToTexture(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1901 bool SparseTextureCommitmentTestCase::writeDataToTexture(const Functions &gl, GLint target, GLint format,
1902                                                          GLuint &texture, GLint level)
1903 {
1904     DE_UNREF(format);
1905     DE_UNREF(texture);
1906 
1907     mLog << "Fill texture [level: " << level << "] - ";
1908 
1909     if (level > mState.levels - 1)
1910         TCU_FAIL("Invalid level");
1911 
1912     TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1913 
1914     GLint width;
1915     GLint height;
1916     GLint depth;
1917     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1918 
1919     if (width > 0 && height > 0 && depth >= mState.minDepth)
1920     {
1921         GLint texSize = width * height * depth * mState.format.getPixelSize();
1922 
1923         std::vector<GLubyte> vecData;
1924         vecData.resize(texSize);
1925         GLubyte *data = vecData.data();
1926 
1927         deMemset(data, 16 + 16 * level, texSize);
1928 
1929         Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
1930                           transferFormat.dataType, (GLvoid *)data);
1931         GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
1932     }
1933 
1934     return true;
1935 }
1936 
1937 /** Verify if data stored in texture is as expected
1938  *
1939  * @param gl           GL API functions
1940  * @param target       Target for which texture is binded
1941  * @param format       Texture internal format
1942  * @param texture      Texture object
1943  * @param level        Texture mipmap level
1944  *
1945  * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1946  */
verifyTextureData(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)1947 bool SparseTextureCommitmentTestCase::verifyTextureData(const Functions &gl, GLint target, GLint format,
1948                                                         GLuint &texture, GLint level)
1949 {
1950     DE_UNREF(format);
1951     DE_UNREF(texture);
1952 
1953     mLog << "Verify Texture [level: " << level << "] - ";
1954 
1955     if (level > mState.levels - 1)
1956         TCU_FAIL("Invalid level");
1957 
1958     TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1959 
1960     GLint width;
1961     GLint height;
1962     GLint depth;
1963     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1964 
1965     //Committed region is limited to 1/2 of width
1966     GLint widthCommitted = width / 2;
1967 
1968     if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1969         return true;
1970 
1971     bool result = true;
1972 
1973     if (target != GL_TEXTURE_CUBE_MAP)
1974     {
1975         GLint texSize = width * height * depth * mState.format.getPixelSize();
1976 
1977         std::vector<GLubyte> vecExpData;
1978         std::vector<GLubyte> vecOutData;
1979         vecExpData.resize(texSize);
1980         vecOutData.resize(texSize);
1981         GLubyte *exp_data = vecExpData.data();
1982         GLubyte *out_data = vecOutData.data();
1983 
1984         deMemset(exp_data, 16 + 16 * level, texSize);
1985         deMemset(out_data, 255, texSize);
1986 
1987         Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
1988         GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1989 
1990         //Verify only committed region
1991         for (GLint x = 0; x < widthCommitted; ++x)
1992             for (GLint y = 0; y < height; ++y)
1993                 for (GLint z = 0; z < depth; ++z)
1994                 {
1995                     int pixelSize          = mState.format.getPixelSize();
1996                     GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
1997                     GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
1998                     if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1999                         result = false;
2000                 }
2001     }
2002     else
2003     {
2004         std::vector<GLint> subTargets;
2005 
2006         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
2007         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
2008         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
2009         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
2010         subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
2011         subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
2012 
2013         GLint texSize = width * height * mState.format.getPixelSize();
2014 
2015         std::vector<GLubyte> vecExpData;
2016         std::vector<GLubyte> vecOutData;
2017         vecExpData.resize(texSize);
2018         vecOutData.resize(texSize);
2019         GLubyte *exp_data = vecExpData.data();
2020         GLubyte *out_data = vecOutData.data();
2021 
2022         deMemset(exp_data, 16 + 16 * level, texSize);
2023         deMemset(out_data, 255, texSize);
2024 
2025         for (size_t i = 0; i < subTargets.size(); ++i)
2026         {
2027             GLint subTarget = subTargets[i];
2028 
2029             mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
2030 
2031             deMemset(out_data, 255, texSize);
2032 
2033             Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid *)out_data);
2034             GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
2035 
2036             //Verify only committed region
2037             for (GLint x = 0; x < widthCommitted; ++x)
2038                 for (GLint y = 0; y < height; ++y)
2039                     for (GLint z = 0; z < depth; ++z)
2040                     {
2041                         int pixelSize          = mState.format.getPixelSize();
2042                         GLubyte *dataRegion    = exp_data + ((x + y * width) * pixelSize);
2043                         GLubyte *outDataRegion = out_data + ((x + y * width) * pixelSize);
2044                         if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
2045                             result = false;
2046                     }
2047 
2048             if (!result)
2049                 break;
2050         }
2051     }
2052 
2053     return result;
2054 }
2055 
2056 /** Commit texture page using texPageCommitment function
2057  *
2058  * @param gl           GL API functions
2059  * @param target       Target for which texture is binded
2060  * @param format       Texture internal format
2061  * @param texture      Texture object
2062  * @param level        Texture mipmap level
2063  *
2064  * @return Returns true if commitment is done properly, false if commitment is not allowed or throws exception if error occurred.
2065  */
commitTexturePage(const Functions & gl,GLint target,GLint format,GLuint & texture,GLint level)2066 bool SparseTextureCommitmentTestCase::commitTexturePage(const Functions &gl, GLint target, GLint format,
2067                                                         GLuint &texture, GLint level)
2068 {
2069     mLog << "Commit Region [level: " << level << "] - ";
2070 
2071     if (level > mState.levels - 1)
2072         TCU_FAIL("Invalid level");
2073 
2074     // Avoid not allowed commitments
2075     if (!isInPageSizesRange(target, level) || !isPageSizesMultiplication(target, level))
2076     {
2077         mLog << "Skip commitment [level: " << level << "] - ";
2078         return false;
2079     }
2080 
2081     GLint width;
2082     GLint height;
2083     GLint depth;
2084     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2085 
2086     if (target == GL_TEXTURE_CUBE_MAP)
2087         depth = 6 * depth;
2088 
2089     GLint widthCommitted = width / 2;
2090 
2091     Texture::Bind(gl, texture, target);
2092     texPageCommitment(gl, target, format, texture, level, 0, 0, 0, widthCommitted, height, depth, GL_TRUE);
2093     GLU_EXPECT_NO_ERROR(gl.getError(), "texPageCommitment");
2094 
2095     return true;
2096 }
2097 
2098 /** Check if current texture size for level is greater or equal page size in a corresponding direction
2099  *
2100  * @param target  Target for which texture is binded
2101  * @param level   Texture mipmap level
2102  *
2103  * @return Returns true if the texture size condition is fulfilled, false otherwise.
2104  */
isInPageSizesRange(GLint target,GLint level)2105 bool SparseTextureCommitmentTestCase::isInPageSizesRange(GLint target, GLint level)
2106 {
2107     GLint width;
2108     GLint height;
2109     GLint depth;
2110     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2111 
2112     if (target == GL_TEXTURE_CUBE_MAP)
2113         depth = 6 * depth;
2114 
2115     GLint widthCommitted = width / 2;
2116     if (widthCommitted >= mState.pageSizeX && height >= mState.pageSizeY &&
2117         (mState.minDepth == 0 || depth >= mState.pageSizeZ))
2118     {
2119         return true;
2120     }
2121 
2122     return false;
2123 }
2124 
2125 /** Check if current texture size for level is page size multiplication in a corresponding direction
2126  *
2127  * @param target  Target for which texture is binded
2128  * @param level   Texture mipmap level
2129  *
2130  * @return Returns true if the texture size condition is fulfilled, false otherwise.
2131  */
isPageSizesMultiplication(GLint target,GLint level)2132 bool SparseTextureCommitmentTestCase::isPageSizesMultiplication(GLint target, GLint level)
2133 {
2134     GLint width;
2135     GLint height;
2136     GLint depth;
2137     SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2138 
2139     if (target == GL_TEXTURE_CUBE_MAP)
2140         depth = 6 * depth;
2141 
2142     GLint widthCommitted = width / 2;
2143     if ((widthCommitted % mState.pageSizeX) == 0 && (height % mState.pageSizeY) == 0 && (depth % mState.pageSizeZ) == 0)
2144     {
2145         return true;
2146     }
2147 
2148     return false;
2149 }
2150 
2151 /** Verifies if gltexPageCommitment generates INVALID_OPERATION error in expected use cases
2152  *
2153  * @param gl           GL API functions
2154  * @param target       Target for which texture is binded
2155  * @param format       Texture internal format
2156  * @param texture      Texture object
2157  *
2158  * @return Returns true if no error occurred, otherwise throws an exception.
2159  */
verifyInvalidOperationErrors(const Functions & gl,GLint target,GLint format,GLuint & texture)2160 bool SparseTextureCommitmentTestCase::verifyInvalidOperationErrors(const Functions &gl, GLint target, GLint format,
2161                                                                    GLuint &texture)
2162 {
2163     mLog << "Verify INVALID_OPERATION Errors - ";
2164 
2165     bool result = true;
2166 
2167     // Case 1 - texture is not GL_TEXTURE_IMMUTABLE_FORMAT
2168     Texture::Generate(gl, texture);
2169     Texture::Bind(gl, texture, target);
2170 
2171     gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
2172     GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");
2173 
2174     GLint immutableFormat;
2175 
2176     gl.getTexParameteriv(target, GL_TEXTURE_IMMUTABLE_FORMAT, &immutableFormat);
2177     GLU_EXPECT_NO_ERROR(gl.getError(), "getTexParameteriv error occurred for GL_TEXTURE_IMMUTABLE_FORMAT");
2178 
2179     if (immutableFormat == GL_FALSE)
2180     {
2181         texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
2182                           GL_TRUE);
2183         result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [GL_TEXTURE_IMMUTABLE_FORMAT texture]",
2184                                                  gl.getError(), GL_INVALID_OPERATION);
2185         if (!result)
2186             goto verifing_invalid_operation_end;
2187     }
2188 
2189     Texture::Delete(gl, texture);
2190 
2191     // Case 2 - texture is not TEXTURE_SPARSE_ARB
2192     allocateTexture(gl, target, format, texture, 1);
2193 
2194     texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
2195                       GL_TRUE);
2196     result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [not TEXTURE_SPARSE_ARB texture]", gl.getError(),
2197                                              GL_INVALID_OPERATION);
2198     if (!result)
2199         goto verifing_invalid_operation_end;
2200 
2201     // Sparse allocate texture
2202     Texture::Delete(gl, texture);
2203     sparseAllocateTexture(gl, target, format, texture, 1);
2204 
2205     // Case 3 - commitment sizes greater than expected
2206     texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width + mState.pageSizeX, mState.height,
2207                       mState.depth, GL_TRUE);
2208     result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment width greater than expected]",
2209                                              gl.getError(), GL_INVALID_OPERATION);
2210     if (!result)
2211         goto verifing_invalid_operation_end;
2212 
2213     texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width, mState.height + mState.pageSizeY,
2214                       mState.depth, GL_TRUE);
2215     result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment height greater than expected]",
2216                                              gl.getError(), GL_INVALID_OPERATION);
2217     if (!result)
2218         goto verifing_invalid_operation_end;
2219 
2220     if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
2221     {
2222         texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.width, mState.height,
2223                           mState.depth + mState.pageSizeZ, GL_TRUE);
2224         result = SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment depth greater than expected]",
2225                                                  gl.getError(), GL_INVALID_OPERATION);
2226         if (!result)
2227             goto verifing_invalid_operation_end;
2228     }
2229 
2230     // Case 4 - commitment sizes not multiple of corresponding page sizes
2231     if (mState.pageSizeX > 1)
2232     {
2233         texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, 1, mState.pageSizeY, mState.pageSizeZ, GL_TRUE);
2234         result =
2235             SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment width not multiple of page sizes X]",
2236                                             gl.getError(), GL_INVALID_OPERATION);
2237         if (!result)
2238             goto verifing_invalid_operation_end;
2239     }
2240 
2241     if (mState.pageSizeY > 1)
2242     {
2243         texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, 1, mState.pageSizeZ, GL_TRUE);
2244         result =
2245             SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment height not multiple of page sizes Y]",
2246                                             gl.getError(), GL_INVALID_OPERATION);
2247         if (!result)
2248             goto verifing_invalid_operation_end;
2249     }
2250 
2251     if (mState.pageSizeZ > 1)
2252     {
2253         if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
2254         {
2255             texPageCommitment(gl, target, format, texture, 0, 0, 0, 0, mState.pageSizeX, mState.pageSizeY,
2256                               mState.minDepth, GL_TRUE);
2257             result = SparseTextureUtils::verifyError(
2258                 mLog, "texPageCommitment [commitment depth not multiple of page sizes Z]", gl.getError(),
2259                 GL_INVALID_OPERATION);
2260             if (!result)
2261                 goto verifing_invalid_operation_end;
2262         }
2263     }
2264 
2265 verifing_invalid_operation_end:
2266 
2267     Texture::Delete(gl, texture);
2268 
2269     return result;
2270 }
2271 
2272 /** Verifies if texPageCommitment generates INVALID_VALUE error in expected use cases
2273  *
2274  * @param gl           GL API functions
2275  * @param target       Target for which texture is binded
2276  * @param format       Texture internal format
2277  * @param texture      Texture object
2278  *
2279  * @return Returns true if no error occurred, otherwise throws an exception.
2280  */
verifyInvalidValueErrors(const Functions & gl,GLint target,GLint format,GLuint & texture)2281 bool SparseTextureCommitmentTestCase::verifyInvalidValueErrors(const Functions &gl, GLint target, GLint format,
2282                                                                GLuint &texture)
2283 {
2284     mLog << "Verify INVALID_VALUE Errors - ";
2285 
2286     bool result = true;
2287 
2288     sparseAllocateTexture(gl, target, format, texture, 1);
2289 
2290     // Case 1 - commitment offset not multiple of page size in corresponding dimension
2291     if (mState.pageSizeX > 1)
2292     {
2293         texPageCommitment(gl, target, format, texture, 0, 1, 0, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
2294                           GL_TRUE);
2295         result =
2296             SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetX not multiple of page size X]",
2297                                             gl.getError(), GL_INVALID_VALUE);
2298         if (!result)
2299             goto verifing_invalid_value_end;
2300     }
2301     if (mState.pageSizeY > 1)
2302     {
2303         texPageCommitment(gl, target, format, texture, 0, 0, 1, 0, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ,
2304                           GL_TRUE);
2305         result =
2306             SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetY not multiple of page size Y]",
2307                                             gl.getError(), GL_INVALID_VALUE);
2308         if (!result)
2309             goto verifing_invalid_value_end;
2310     }
2311     if ((target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
2312         (mState.minDepth % mState.pageSizeZ))
2313     {
2314         texPageCommitment(gl, target, format, texture, 0, 0, 0, mState.minDepth, mState.pageSizeX, mState.pageSizeY,
2315                           mState.pageSizeZ, GL_TRUE);
2316         result =
2317             SparseTextureUtils::verifyError(mLog, "texPageCommitment [commitment offsetZ not multiple of page size Z]",
2318                                             gl.getError(), GL_INVALID_VALUE);
2319         if (!result)
2320             goto verifing_invalid_value_end;
2321     }
2322 
2323 verifing_invalid_value_end:
2324 
2325     Texture::Delete(gl, texture);
2326 
2327     return result;
2328 }
2329 
2330 /** Constructor.
2331  *
2332  *  @param context     Rendering context
2333  */
SparseDSATextureCommitmentTestCase(deqp::Context & context)2334 SparseDSATextureCommitmentTestCase::SparseDSATextureCommitmentTestCase(deqp::Context &context)
2335     : SparseTextureCommitmentTestCase(context, "SparseDSATextureCommitment",
2336                                       "Verifies texturePageCommitmentEXT functionality added in CTS_ARB_sparse_texture")
2337 {
2338     /* Left blank intentionally */
2339 }
2340 
2341 /** Executes test iteration.
2342  *
2343  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2344  */
iterate()2345 tcu::TestNode::IterateResult SparseDSATextureCommitmentTestCase::iterate()
2346 {
2347     if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture"))
2348     {
2349         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2350         return STOP;
2351     }
2352 
2353     if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_direct_state_access"))
2354     {
2355         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_EXT_direct_state_access extension is not supported.");
2356         return STOP;
2357     }
2358 
2359     const Functions &gl = m_context.getRenderContext().getFunctions();
2360 
2361     bool result = true;
2362 
2363     GLuint texture;
2364 
2365     for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
2366          ++iter)
2367     {
2368         const GLint &target = *iter;
2369 
2370         for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
2371              formIter != mSupportedInternalFormats.end(); ++formIter)
2372         {
2373             const GLint &format = *formIter;
2374 
2375             mLog.str("");
2376             mLog << "Testing DSA sparse texture commitment for target: " << target << ", format: " << format << " - ";
2377 
2378             //Checking if written data into committed region is as expected
2379             sparseAllocateTexture(gl, target, format, texture, 3);
2380             for (int l = 0; l < mState.levels; ++l)
2381             {
2382                 if (commitTexturePage(gl, target, format, texture, l))
2383                 {
2384                     writeDataToTexture(gl, target, format, texture, l);
2385                     result = verifyTextureData(gl, target, format, texture, l);
2386                 }
2387 
2388                 if (!result)
2389                     break;
2390             }
2391 
2392             Texture::Delete(gl, texture);
2393 
2394             //verify errors
2395             result = result && verifyInvalidOperationErrors(gl, target, format, texture);
2396             result = result && verifyInvalidValueErrors(gl, target, format, texture);
2397 
2398             if (!result)
2399             {
2400                 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
2401                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2402                 return STOP;
2403             }
2404         }
2405     }
2406 
2407     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2408     return STOP;
2409 }
2410 
2411 /** Bind DSA texturePageCommitmentEXT function
2412  *
2413  * @param gl           GL API functions
2414  * @param target       Target for which texture is binded
2415  * @param format       Texture internal format
2416  * @param texture      Texture object
2417  * @param xOffset      Texture commitment x offset
2418  * @param yOffset      Texture commitment y offset
2419  * @param zOffset      Texture commitment z offset
2420  * @param width        Texture commitment width
2421  * @param height       Texture commitment height
2422  * @param depth        Texture commitment depth
2423  * @param commit       Commit or de-commit indicator
2424  **/
texPageCommitment(const glw::Functions & gl,glw::GLint target,glw::GLint format,glw::GLuint & texture,GLint level,GLint xOffset,GLint yOffset,GLint zOffset,GLint width,GLint height,GLint depth,GLboolean commit)2425 void SparseDSATextureCommitmentTestCase::texPageCommitment(const glw::Functions &gl, glw::GLint target,
2426                                                            glw::GLint format, glw::GLuint &texture, GLint level,
2427                                                            GLint xOffset, GLint yOffset, GLint zOffset, GLint width,
2428                                                            GLint height, GLint depth, GLboolean commit)
2429 {
2430     DE_UNREF(target);
2431     DE_UNREF(format);
2432     gl.texturePageCommitmentEXT(texture, level, xOffset, yOffset, zOffset, width, height, depth, commit);
2433 }
2434 
2435 /** Constructor.
2436  *
2437  *  @param context Rendering context.
2438  */
SparseTextureTests(deqp::Context & context)2439 SparseTextureTests::SparseTextureTests(deqp::Context &context)
2440     : TestCaseGroup(context, "sparse_texture_tests", "Verify conformance of CTS_ARB_sparse_texture implementation")
2441 {
2442 }
2443 
2444 /** Initializes the test group contents. */
init()2445 void SparseTextureTests::init()
2446 {
2447     addChild(new TextureParameterQueriesTestCase(m_context));
2448     addChild(new InternalFormatQueriesTestCase(m_context));
2449     addChild(new SimpleQueriesTestCase(m_context));
2450     addChild(new SparseTextureAllocationTestCase(m_context));
2451     addChild(new SparseTextureCommitmentTestCase(m_context));
2452     addChild(new SparseDSATextureCommitmentTestCase(m_context));
2453 }
2454 
2455 } // namespace gl4cts
2456