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