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