• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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