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