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 ¶m = *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