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