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