1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
26 * \file gl4cSparseTexture2Tests.cpp
27 * \brief Conformance tests for the GL_ARB_sparse_texture2 functionality.
28 */ /*-------------------------------------------------------------------*/
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"
50 const char* st2_compute_textureFill = "#version 430 core\n"
52 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
54 "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n"
58 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
60 " <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
61 " imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
64 const char* st2_compute_textureVerify = "#version 430 core\n"
66 "#extension GL_ARB_sparse_texture2 : enable\n"
68 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
75 " <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
77 " highp <RETURN_TYPE> color,\n"
80 " color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
81 " expected = <RETURN_TYPE><RESULT_EXPECTED>;\n"
82 " epsilon = <RETURN_TYPE>(<EPSILON>);\n"
84 " if (all(lessThanEqual(color, expected + epsilon)) &&\n"
85 " all(greaterThanEqual(color, expected - epsilon)))\n"
87 " imageStore(uni_out_image, point, uvec4(255));\n"
90 " imageStore(uni_out_image, point, uvec4(0));\n"
94 const char* st2_compute_atomicVerify = "#version 430 core\n"
96 "#extension GL_ARB_sparse_texture2 : enable\n"
98 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
103 "layout (location = 3) uniform int widthCommitted;\n"
107 " <POINT_TYPE> point,\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"
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"
141 " <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
144 " imageStore(uni_out_image, point - offset, uvec4(0));\n"
146 " imageStore(uni_out_image, point - offset, uvec4(value));\n"
148 " if (color.r == 0)\n"
149 " imageStore(uni_out_image, point, uvec4(0));\n"
151 " imageStore(uni_out_image, point, uvec4(1));\n"
155 const char* st2_vertex_drawBuffer = "#version 430 core\n"
157 "#extension GL_ARB_sparse_texture2 : enable\n"
160 "in vec2 inTexCoord;\n"
161 "out vec2 texCoord;\n"
165 " texCoord = inTexCoord;\n"
166 " gl_Position = vec4(vertex, 1);\n"
169 const char* st2_fragment_drawBuffer = "#version 430 core\n"
171 "#extension GL_ARB_sparse_texture2 : enable\n"
173 "layout (location = 1) uniform sampler2D uni_sampler;\n"
175 "in vec2 texCoord;\n"
176 "out vec4 fragColor;\n"
180 " fragColor = texture(uni_sampler, texCoord);\n"
183 const char* st2_compute_extensionCheck = "#version 450 core\n"
185 "#extension <EXTENSION> : require\n"
187 "#ifndef <EXTENSION>\n"
188 " #error <EXTENSION> not defined\n"
190 " #if (<EXTENSION> != 1)\n"
191 " #error <EXTENSION> wrong value\n"
193 "#endif // <EXTENSION>\n"
195 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
201 const char* st2_compute_lookupVerify = "#version 450 core\n"
203 "#extension GL_ARB_sparse_texture2 : enable\n"
204 "#extension GL_ARB_sparse_texture_clamp : enable\n"
206 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
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"
221 " retValue = <RETURN_TYPE>(0);\n"
222 " expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
223 " epsilon = <RETURN_TYPE>(<EPSILON>);\n"
225 "<CUBE_MAP_COORD_DEF>\n"
226 "<OFFSET_ARRAY_DEF>\n"
228 " ivec2 corner1 = ivec2(1, 1);\n"
229 " ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
231 " int code = <FUNCTION>(uni_in,\n"
232 " <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
233 " retValue<COMPONENT_DEF>);\n"
234 " memoryBarrier();\n"
236 " imageStore(uni_out, point, uvec4(255));\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"
242 " if (!sparseTexelsResidentARB(code) ||\n"
243 " any(greaterThan(retValue, expValue + epsilon)) ||\n"
244 " any(lessThan(retValue, expValue - epsilon)))\n"
246 " imageStore(uni_out, point, uvec4(0));\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"
254 " if (sparseTexelsResidentARB(code))\n"
256 " imageStore(uni_out, point, uvec4(0));\n"
261 /** Replace all occurance of <token> with <text> in <string>
263 * @param token Token string
264 * @param text String that will be used as replacement for <token>
265 * @param string String to work on
267 void replaceToken(const GLchar* token, const GLchar* text, std::string& string)
269 const size_t text_length = strlen(text);
270 const size_t token_length = strlen(token);
272 size_t token_position;
273 while ((token_position = string.find(token, 0)) != std::string::npos)
275 string.replace(token_position, token_length, text, text_length);
281 * @param context Rendering context
283 ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context, const std::string extension)
284 : TestCase(context, "ShaderExtension", "Verifies if extension is available for GLSL"), mExtension(extension)
286 /* Left blank intentionally */
289 /** Executes test iteration.
291 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
293 tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate()
295 if (!m_context.getContextInfo().isExtensionSupported(mExtension.c_str()))
297 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
301 const Functions& gl = m_context.getRenderContext().getFunctions();
303 std::string shader = st2_compute_extensionCheck;
304 replaceToken("<EXTENSION>", mExtension.c_str(), shader);
306 ProgramSources sources;
307 sources << ComputeSource(shader);
308 ShaderProgram program(gl, sources);
312 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
313 m_testCtx.getLog() << tcu::TestLog::Message << "Checking shader preprocessor directives failed. Source:\n"
314 << shader.c_str() << "InfoLog:\n"
315 << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
316 << tcu::TestLog::EndMessage;
320 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
326 * @param context Rendering context
328 StandardPageSizesTestCase::StandardPageSizesTestCase(deqp::Context& context)
329 : TestCase(context, "StandardPageSizesTestCase",
330 "Verifies if values returned by GetInternalFormativ query matches Standard Virtual Page Sizes")
332 /* Left blank intentionally */
335 /** Stub init method */
336 void StandardPageSizesTestCase::init()
338 mSupportedTargets.push_back(GL_TEXTURE_1D);
339 mSupportedTargets.push_back(GL_TEXTURE_1D_ARRAY);
340 mSupportedTargets.push_back(GL_TEXTURE_2D);
341 mSupportedTargets.push_back(GL_TEXTURE_2D_ARRAY);
342 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP);
343 mSupportedTargets.push_back(GL_TEXTURE_CUBE_MAP_ARRAY);
344 mSupportedTargets.push_back(GL_TEXTURE_RECTANGLE);
345 mSupportedTargets.push_back(GL_TEXTURE_BUFFER);
346 mSupportedTargets.push_back(GL_RENDERBUFFER);
348 mStandardVirtualPageSizesTable[GL_R8] = PageSizeStruct(256, 256, 1);
349 mStandardVirtualPageSizesTable[GL_R8_SNORM] = PageSizeStruct(256, 256, 1);
350 mStandardVirtualPageSizesTable[GL_R8I] = PageSizeStruct(256, 256, 1);
351 mStandardVirtualPageSizesTable[GL_R8UI] = PageSizeStruct(256, 256, 1);
352 mStandardVirtualPageSizesTable[GL_R16] = PageSizeStruct(256, 128, 1);
353 mStandardVirtualPageSizesTable[GL_R16_SNORM] = PageSizeStruct(256, 128, 1);
354 mStandardVirtualPageSizesTable[GL_RG8] = PageSizeStruct(256, 128, 1);
355 mStandardVirtualPageSizesTable[GL_RG8_SNORM] = PageSizeStruct(256, 128, 1);
356 mStandardVirtualPageSizesTable[GL_RGB565] = PageSizeStruct(256, 128, 1);
357 mStandardVirtualPageSizesTable[GL_R16F] = PageSizeStruct(256, 128, 1);
358 mStandardVirtualPageSizesTable[GL_R16I] = PageSizeStruct(256, 128, 1);
359 mStandardVirtualPageSizesTable[GL_R16UI] = PageSizeStruct(256, 128, 1);
360 mStandardVirtualPageSizesTable[GL_RG8I] = PageSizeStruct(256, 128, 1);
361 mStandardVirtualPageSizesTable[GL_RG8UI] = PageSizeStruct(256, 128, 1);
362 mStandardVirtualPageSizesTable[GL_RG16] = PageSizeStruct(128, 128, 1);
363 mStandardVirtualPageSizesTable[GL_RG16_SNORM] = PageSizeStruct(128, 128, 1);
364 mStandardVirtualPageSizesTable[GL_RGBA8] = PageSizeStruct(128, 128, 1);
365 mStandardVirtualPageSizesTable[GL_RGBA8_SNORM] = PageSizeStruct(128, 128, 1);
366 mStandardVirtualPageSizesTable[GL_RGB10_A2] = PageSizeStruct(128, 128, 1);
367 mStandardVirtualPageSizesTable[GL_RGB10_A2UI] = PageSizeStruct(128, 128, 1);
368 mStandardVirtualPageSizesTable[GL_RG16F] = PageSizeStruct(128, 128, 1);
369 mStandardVirtualPageSizesTable[GL_R32F] = PageSizeStruct(128, 128, 1);
370 mStandardVirtualPageSizesTable[GL_R11F_G11F_B10F] = PageSizeStruct(128, 128, 1);
371 mStandardVirtualPageSizesTable[GL_RGB9_E5] = PageSizeStruct(128, 128, 1);
372 mStandardVirtualPageSizesTable[GL_R32I] = PageSizeStruct(128, 128, 1);
373 mStandardVirtualPageSizesTable[GL_R32UI] = PageSizeStruct(128, 128, 1);
374 mStandardVirtualPageSizesTable[GL_RG16I] = PageSizeStruct(128, 128, 1);
375 mStandardVirtualPageSizesTable[GL_RG16UI] = PageSizeStruct(128, 128, 1);
376 mStandardVirtualPageSizesTable[GL_RGBA8I] = PageSizeStruct(128, 128, 1);
377 mStandardVirtualPageSizesTable[GL_RGBA8UI] = PageSizeStruct(128, 128, 1);
378 mStandardVirtualPageSizesTable[GL_RGBA16] = PageSizeStruct(128, 64, 1);
379 mStandardVirtualPageSizesTable[GL_RGBA16_SNORM] = PageSizeStruct(128, 64, 1);
380 mStandardVirtualPageSizesTable[GL_RGBA16F] = PageSizeStruct(128, 64, 1);
381 mStandardVirtualPageSizesTable[GL_RG32F] = PageSizeStruct(128, 64, 1);
382 mStandardVirtualPageSizesTable[GL_RG32I] = PageSizeStruct(128, 64, 1);
383 mStandardVirtualPageSizesTable[GL_RG32UI] = PageSizeStruct(128, 64, 1);
384 mStandardVirtualPageSizesTable[GL_RGBA16I] = PageSizeStruct(128, 64, 1);
385 mStandardVirtualPageSizesTable[GL_RGBA16UI] = PageSizeStruct(128, 64, 1);
386 mStandardVirtualPageSizesTable[GL_RGBA32F] = PageSizeStruct(64, 64, 1);
387 mStandardVirtualPageSizesTable[GL_RGBA32I] = PageSizeStruct(64, 64, 1);
388 mStandardVirtualPageSizesTable[GL_RGBA32UI] = PageSizeStruct(64, 64, 1);
391 /** Executes test iteration.
393 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
395 tcu::TestNode::IterateResult StandardPageSizesTestCase::iterate()
397 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
399 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
403 const Functions& gl = m_context.getRenderContext().getFunctions();
405 m_testCtx.getLog() << tcu::TestLog::Message << "Testing getInternalformativ" << tcu::TestLog::EndMessage;
407 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
410 const GLint& target = *iter;
412 for (std::map<glw::GLint, PageSizeStruct>::const_iterator formIter = mStandardVirtualPageSizesTable.begin();
413 formIter != mStandardVirtualPageSizesTable.end(); ++formIter)
415 const PageSizePair& format = *formIter;
416 const PageSizeStruct& page = format.second;
421 SparseTextureUtils::getTexturePageSizes(gl, target, format.first, pageSizeX, pageSizeY, pageSizeZ);
423 if (pageSizeX != page.xSize || pageSizeY != page.ySize || pageSizeZ != page.zSize)
425 m_testCtx.getLog() << tcu::TestLog::Message << "Standard Virtual Page Size mismatch, target: " << target
426 << ", format: " << format.first << ", returned: " << pageSizeX << "/" << pageSizeY
427 << "/" << pageSizeZ << ", expected: " << page.xSize << "/" << page.ySize << "/"
428 << page.zSize << tcu::TestLog::EndMessage;
430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
436 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
443 * @param context Rendering context
445 SparseTexture2AllocationTestCase::SparseTexture2AllocationTestCase(deqp::Context& context)
446 : SparseTextureAllocationTestCase(context, "SparseTexture2Allocation",
447 "Verifies TexStorage* functionality added in CTS_ARB_sparse_texture2")
449 /* Left blank intentionally */
452 /** Initializes the test group contents. */
453 void SparseTexture2AllocationTestCase::init()
455 SparseTextureAllocationTestCase::init();
457 mSupportedTargets.clear();
458 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
459 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
461 mFullArrayTargets.clear();
462 mFullArrayTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
465 /** Executes test iteration.
467 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
469 tcu::TestNode::IterateResult SparseTexture2AllocationTestCase::iterate()
471 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
473 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
477 return SparseTextureAllocationTestCase::iterate();
482 * @param context Rendering context
483 * @param name Test name
484 * @param description Test description
486 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context, const char* name,
487 const char* description)
488 : SparseTextureCommitmentTestCase(context, name, description)
490 /* Left blank intentionally */
495 * @param context Rendering context
497 SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context)
498 : SparseTextureCommitmentTestCase(
499 context, "SparseTexture2Commitment",
500 "Verifies glTexPageCommitmentARB functionality added by ARB_sparse_texture2 extension")
502 /* Left blank intentionally */
505 /** Initializes the test group contents. */
506 void SparseTexture2CommitmentTestCase::init()
508 SparseTextureCommitmentTestCase::init();
510 //Verify all targets once again and multisample targets as it was added in ARB_sparse_texture2 extension
511 mSupportedTargets.clear();
512 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
513 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
516 /** Executes test iteration.
518 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
520 tcu::TestNode::IterateResult SparseTexture2CommitmentTestCase::iterate()
522 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
524 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
528 return SparseTextureCommitmentTestCase::iterate();
531 /** Create set of token strings fit to texture verifying shader
533 * @param target Target for which texture is binded
534 * @param format Texture internal format
535 * @param sample Texture sample number
537 * @return target Structure of token strings
539 SparseTexture2CommitmentTestCase::TokenStrings SparseTexture2CommitmentTestCase::createShaderTokens(
540 GLint target, GLint format, GLint sample, const std::string outputBase, const std::string inputBase)
548 s.resultExpected = "(1, 0, 0, 1)";
549 s.resultDefault = "(0, 0, 0, 1)";
551 else if (format == GL_R8_SNORM)
553 s.format = "r8_snorm";
554 s.resultExpected = "(1, 0, 0, 1)";
555 s.resultDefault = "(0, 0, 0, 1)";
557 else if (format == GL_R16)
560 s.resultExpected = "(1, 0, 0, 1)";
561 s.resultDefault = "(0, 0, 0, 1)";
563 else if (format == GL_R16_SNORM)
565 s.format = "r16_snorm";
566 s.resultExpected = "(1, 0, 0, 1)";
567 s.resultDefault = "(0, 0, 0, 1)";
569 else if (format == GL_RG8)
572 s.resultExpected = "(1, 1, 0, 1)";
573 s.resultDefault = "(0, 0, 0, 1)";
575 else if (format == GL_RG8_SNORM)
577 s.format = "rg8_snorm";
578 s.resultExpected = "(1, 1, 0, 1)";
579 s.resultDefault = "(0, 0, 0, 1)";
581 else if (format == GL_RG16)
584 s.resultExpected = "(1, 1, 0, 1)";
585 s.resultDefault = "(0, 0, 0, 1)";
587 else if (format == GL_RG16_SNORM)
589 s.format = "rg16_snorm";
590 s.resultExpected = "(1, 1, 0, 1)";
591 s.resultDefault = "(0, 0, 0, 1)";
593 else if (format == GL_RGBA8)
596 s.resultExpected = "(1, 1, 1, 1)";
597 s.resultDefault = "(0, 0, 0, 0)";
599 else if (format == GL_RGBA8_SNORM)
601 s.format = "rgba8_snorm";
602 s.resultExpected = "(1, 1, 1, 1)";
603 s.resultDefault = "(0, 0, 0, 0)";
605 else if (format == GL_RGB10_A2)
607 s.format = "rgb10_a2";
608 s.resultExpected = "(1, 1, 1, 1)";
609 s.resultDefault = "(0, 0, 0, 0)";
611 else if (format == GL_RGB10_A2UI)
613 s.format = "rgb10_a2ui";
614 s.resultExpected = "(1, 1, 1, 1)";
615 s.resultDefault = "(0, 0, 0, 0)";
618 else if (format == GL_RGBA16)
621 s.resultExpected = "(1, 1, 1, 1)";
622 s.resultDefault = "(0, 0, 0, 0)";
624 else if (format == GL_RGBA16_SNORM)
626 s.format = "rgba16_snorm";
627 s.resultExpected = "(1, 1, 1, 1)";
628 s.resultDefault = "(0, 0, 0, 0)";
630 else if (format == GL_R16F)
633 s.resultExpected = "(1, 0, 0, 1)";
634 s.resultDefault = "(0, 0, 0, 1)";
636 else if (format == GL_RG16F)
639 s.resultExpected = "(1, 1, 0, 1)";
640 s.resultDefault = "(0, 0, 0, 1)";
642 else if (format == GL_RGBA16F)
644 s.format = "rgba16f";
645 s.resultExpected = "(1, 1, 1, 1)";
646 s.resultDefault = "(0, 0, 0, 0)";
648 else if (format == GL_R32F)
651 s.resultExpected = "(1, 0, 0, 1)";
652 s.resultDefault = "(0, 0, 0, 1)";
654 else if (format == GL_RG32F)
657 s.resultExpected = "(1, 1, 0, 1)";
658 s.resultDefault = "(0, 0, 0, 1)";
660 else if (format == GL_RGBA32F)
662 s.format = "rgba32f";
663 s.resultExpected = "(1, 1, 1, 1)";
664 s.resultDefault = "(0, 0, 0, 0)";
666 else if (format == GL_R11F_G11F_B10F)
668 s.format = "r11f_g11f_b10f";
669 s.resultExpected = "(1, 1, 1, 1)";
670 s.resultDefault = "(0, 0, 0, 1)";
672 else if (format == GL_R8I)
675 s.resultExpected = "(1, 0, 0, 1)";
676 s.resultDefault = "(0, 0, 0, 1)";
679 else if (format == GL_R8UI)
682 s.resultExpected = "(1, 0, 0, 1)";
683 s.resultDefault = "(0, 0, 0, 1)";
686 else if (format == GL_R16I)
689 s.resultExpected = "(1, 0, 0, 1)";
690 s.resultDefault = "(0, 0, 0, 1)";
693 else if (format == GL_R16UI)
696 s.resultExpected = "(1, 0, 0, 1)";
697 s.resultDefault = "(0, 0, 0, 1)";
700 else if (format == GL_R32I)
703 s.resultExpected = "(1, 0, 0, 1)";
704 s.resultDefault = "(0, 0, 0, 1)";
707 else if (format == GL_R32UI)
710 s.resultExpected = "(1, 0, 0, 1)";
711 s.resultDefault = "(0, 0, 0, 1)";
714 else if (format == GL_RG8I)
717 s.resultExpected = "(1, 1, 0, 1)";
718 s.resultDefault = "(0, 0, 0, 1)";
721 else if (format == GL_RG8UI)
724 s.resultExpected = "(1, 1, 0, 1)";
725 s.resultDefault = "(0, 0, 0, 1)";
728 else if (format == GL_RG16I)
731 s.resultExpected = "(1, 1, 0, 1)";
732 s.resultDefault = "(0, 0, 0, 1)";
735 else if (format == GL_RG16UI)
738 s.resultExpected = "(1, 1, 0, 1)";
739 s.resultDefault = "(0, 0, 0, 1)";
742 else if (format == GL_RG32I)
745 s.resultExpected = "(1, 1, 0, 1)";
746 s.resultDefault = "(0, 0, 0, 1)";
749 else if (format == GL_RG32UI)
752 s.resultExpected = "(1, 1, 0, 1)";
753 s.resultDefault = "(0, 0, 0, 1)";
756 else if (format == GL_RGBA8I)
759 s.resultExpected = "(1, 1, 1, 1)";
760 s.resultDefault = "(0, 0, 0, 0)";
763 else if (format == GL_RGBA8UI)
765 s.format = "rgba8ui";
766 s.resultExpected = "(1, 1, 1, 1)";
767 s.resultDefault = "(0, 0, 0, 0)";
770 else if (format == GL_RGBA16I)
772 s.format = "rgba16i";
773 s.resultExpected = "(1, 1, 1, 1)";
774 s.resultDefault = "(0, 0, 0, 0)";
777 else if (format == GL_RGBA16UI)
779 s.format = "rgba16ui";
780 s.resultExpected = "(1, 1, 1, 1)";
781 s.resultDefault = "(0, 0, 0, 0)";
784 else if (format == GL_RGBA32I)
786 s.format = "rgba32i";
787 s.resultExpected = "(1, 1, 1, 1)";
788 s.resultDefault = "(0, 0, 0, 0)";
791 else if (format == GL_DEPTH_COMPONENT16)
794 s.resultExpected = "(1, 0, 0, 0)";
795 s.resultDefault = "(0, 0, 0, 0)";
798 s.returnType = prefix + "vec4";
799 s.outputType = "u" + outputBase + "2D";
800 s.inputType = prefix + inputBase + "2D";
801 s.pointType = "ivec2";
802 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y";
804 if (s.returnType == "vec4")
809 if (target == GL_TEXTURE_1D)
811 s.outputType = "u" + outputBase + "2D";
812 s.inputType = prefix + inputBase + "1D";
814 s.pointDef = "gl_WorkGroupID.x";
816 else if (target == GL_TEXTURE_1D_ARRAY)
818 s.outputType = "u" + outputBase + "2D_ARRAY";
819 s.inputType = prefix + inputBase + "1DArray";
820 s.pointType = "ivec2";
821 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.z";
823 else if (target == GL_TEXTURE_2D_ARRAY)
825 s.outputType = "u" + outputBase + "2DArray";
826 s.inputType = prefix + inputBase + "2DArray";
827 s.pointType = "ivec3";
828 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
830 else if (target == GL_TEXTURE_3D)
832 s.outputType = "u" + outputBase + "2DArray";
833 s.inputType = prefix + inputBase + "3D";
834 s.pointType = "ivec3";
835 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
837 else if (target == GL_TEXTURE_CUBE_MAP)
839 s.outputType = "u" + outputBase + "2DArray";
840 s.inputType = prefix + inputBase + "Cube";
841 s.pointType = "ivec3";
842 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6";
844 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
846 s.outputType = "u" + outputBase + "2DArray";
847 s.inputType = prefix + inputBase + "CubeArray";
848 s.pointType = "ivec3";
849 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
851 else if (target == GL_TEXTURE_RECTANGLE)
853 s.inputType = prefix + inputBase + "2DRect";
855 else if (target == GL_TEXTURE_2D_MULTISAMPLE)
857 s.inputType = prefix + inputBase + "2DMS";
858 s.sampleDef = ", " + de::toString(sample);
860 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
862 s.outputType = "u" + outputBase + "2DArray";
863 s.inputType = prefix + inputBase + "2DMSArray";
864 s.pointType = "ivec3";
865 s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z";
866 s.sampleDef = ", " + de::toString(sample);
872 /** Check if specific combination of target and format is allowed
874 * @param target Target for which texture is binded
875 * @param format Texture internal format
877 * @return Returns true if target/format combination is allowed, false otherwise.
879 bool SparseTexture2CommitmentTestCase::caseAllowed(GLint target, GLint format)
881 // Multisample textures are filling with data and verifying using compute shader.
882 // As shaders do not support some texture formats it is necessary to exclude them.
883 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) &&
884 (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
892 /** Allocating sparse texture memory using texStorage* function
894 * @param gl GL API functions
895 * @param target Target for which texture is binded
896 * @param format Texture internal format
897 * @param texture Texture object
898 * @param levels Texture mipmaps level
900 * @return Returns true if no error occurred, otherwise throws an exception.
902 bool SparseTexture2CommitmentTestCase::sparseAllocateTexture(const Functions& gl, GLint target, GLint format,
903 GLuint& texture, GLint levels)
905 mLog << "Sparse Allocate [levels: " << levels << "] - ";
907 prepareTexture(gl, target, format, texture);
910 gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
911 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB");
912 gl.getTexParameteriv(target, GL_NUM_SPARSE_LEVELS_ARB, &maxLevels);
913 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv");
914 if (levels > maxLevels)
917 //GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
918 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
919 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
921 mState.levels = levels;
926 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
933 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
935 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
940 /** Allocating texture memory using texStorage* function
942 * @param gl GL API functions
943 * @param target Target for which texture is binded
944 * @param format Texture internal format
945 * @param texture Texture object
946 * @param levels Texture mipmaps level
948 * @return Returns true if no error occurred, otherwise throws an exception.
950 bool SparseTexture2CommitmentTestCase::allocateTexture(const Functions& gl, GLint target, GLint format, GLuint& texture,
953 mLog << "Allocate [levels: " << levels << "] - ";
955 prepareTexture(gl, target, format, texture);
957 // GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level
958 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
959 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
961 mState.levels = levels;
966 // GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can use multiple samples
967 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
974 Texture::Storage(gl, target, deMax32(mState.levels, mState.samples), format, mState.width, mState.height,
976 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage");
981 /** Writing data to generated texture
983 * @param gl GL API functions
984 * @param target Target for which texture is binded
985 * @param format Texture internal format
986 * @param texture Texture object
988 * @return Returns true if no error occurred, otherwise throws an exception.
990 bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format,
991 GLuint& texture, GLint level)
993 mLog << "Fill Texture [level: " << level << "] - ";
995 if (level > mState.levels - 1)
996 TCU_FAIL("Invalid level");
998 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1003 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1005 if (width > 0 && height > 0 && depth >= mState.minDepth)
1007 if (target == GL_TEXTURE_CUBE_MAP)
1010 GLint texSize = width * height * depth * mState.format.getPixelSize();
1012 std::vector<GLubyte> vecData;
1013 vecData.resize(texSize);
1014 GLubyte* data = vecData.data();
1016 deMemset(data, 255, texSize);
1018 if (target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1020 Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
1021 transferFormat.dataType, (GLvoid*)data);
1022 GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
1024 // For multisample texture use compute shader to store image data
1027 for (GLint sample = 0; sample < mState.samples; ++sample)
1029 std::string shader = st2_compute_textureFill;
1031 // Adjust shader source to texture format
1032 TokenStrings s = createShaderTokens(target, format, sample);
1034 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1035 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1036 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1037 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1038 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1039 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1041 ProgramSources sources;
1042 sources << ComputeSource(shader);
1044 // Build and run shader
1045 ShaderProgram program(m_context.getRenderContext(), sources);
1048 gl.useProgram(program.getProgram());
1049 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1050 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */,
1051 GL_WRITE_ONLY, format);
1052 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1053 gl.uniform1i(1, 0 /* image_unit */);
1054 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1055 gl.dispatchCompute(width, height, depth);
1056 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1057 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1062 mLog << "Compute shader compilation failed (writing) for target: " << target
1063 << ", format: " << format << ", sample: " << sample
1064 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1065 << ", shaderSource: " << shader.c_str() << " - ";
1074 /** Verify if data stored in texture is as expected
1076 * @param gl GL API functions
1077 * @param target Target for which texture is binded
1078 * @param format Texture internal format
1079 * @param texture Texture object
1080 * @param level Texture mipmap level
1082 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1084 bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions& gl, GLint target, GLint format,
1085 GLuint& texture, GLint level)
1087 mLog << "Verify Texture [level: " << level << "] - ";
1089 if (level > mState.levels - 1)
1090 TCU_FAIL("Invalid level");
1092 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1097 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1099 //Committed region is limited to 1/2 of width
1100 GLint widthCommitted = width / 2;
1102 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1107 if (target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1108 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1110 GLint texSize = width * height * depth * mState.format.getPixelSize();
1112 std::vector<GLubyte> vecExpData;
1113 std::vector<GLubyte> vecOutData;
1114 vecExpData.resize(texSize);
1115 vecOutData.resize(texSize);
1116 GLubyte* exp_data = vecExpData.data();
1117 GLubyte* out_data = vecOutData.data();
1119 deMemset(exp_data, 255, texSize);
1120 deMemset(out_data, 127, texSize);
1122 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1123 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1125 //Verify only committed region
1126 for (GLint x = 0; x < widthCommitted; ++x)
1127 for (GLint y = 0; y < height; ++y)
1128 for (GLint z = 0; z < depth; ++z)
1130 int pixelSize = mState.format.getPixelSize();
1131 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1132 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1133 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1137 else if (target == GL_TEXTURE_CUBE_MAP)
1139 std::vector<GLint> subTargets;
1141 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1142 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1143 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1144 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1145 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1146 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1148 GLint texSize = width * height * mState.format.getPixelSize();
1150 std::vector<GLubyte> vecExpData;
1151 std::vector<GLubyte> vecOutData;
1152 vecExpData.resize(texSize);
1153 vecOutData.resize(texSize);
1154 GLubyte* exp_data = vecExpData.data();
1155 GLubyte* out_data = vecOutData.data();
1157 deMemset(exp_data, 255, texSize);
1159 for (size_t i = 0; i < subTargets.size(); ++i)
1161 GLint subTarget = subTargets[i];
1163 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1165 deMemset(out_data, 127, texSize);
1167 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1168 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1170 //Verify only committed region
1171 for (GLint x = 0; x < widthCommitted; ++x)
1172 for (GLint y = 0; y < height; ++y)
1173 for (GLint z = 0; z < depth; ++z)
1175 int pixelSize = mState.format.getPixelSize();
1176 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1177 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1178 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1186 // For multisample texture use compute shader to verify image data
1187 else if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1189 GLint texSize = width * height * depth;
1191 std::vector<GLubyte> vecExpData;
1192 std::vector<GLubyte> vecOutData;
1193 vecExpData.resize(texSize);
1194 vecOutData.resize(texSize);
1195 GLubyte* exp_data = vecExpData.data();
1196 GLubyte* out_data = vecOutData.data();
1198 deMemset(exp_data, 255, texSize);
1200 // Create verifying texture
1202 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1203 verifyTarget = GL_TEXTURE_2D;
1205 verifyTarget = GL_TEXTURE_2D_ARRAY;
1207 GLuint verifyTexture;
1208 Texture::Generate(gl, verifyTexture);
1209 Texture::Bind(gl, verifyTexture, verifyTarget);
1210 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1211 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1213 for (int sample = 0; sample < mState.samples; ++sample)
1215 deMemset(out_data, 0, texSize);
1217 Texture::Bind(gl, verifyTexture, verifyTarget);
1218 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1220 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1222 std::string shader = st2_compute_textureVerify;
1224 // Adjust shader source to texture format
1225 TokenStrings s = createShaderTokens(target, format, sample);
1227 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1228 replaceToken("<FORMAT>", s.format.c_str(), shader);
1229 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1230 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1231 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1232 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1233 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1234 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
1235 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1237 ProgramSources sources;
1238 sources << ComputeSource(shader);
1240 // Build and run shader
1241 ShaderProgram program(m_context.getRenderContext(), sources);
1244 gl.useProgram(program.getProgram());
1245 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1246 gl.bindImageTexture(0, //unit
1251 GL_WRITE_ONLY, GL_R8UI);
1252 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1253 gl.bindImageTexture(1, //unit
1258 GL_READ_ONLY, format);
1259 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1260 gl.uniform1i(1, 0 /* image_unit */);
1261 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1262 gl.uniform1i(2, 1 /* image_unit */);
1263 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1264 gl.dispatchCompute(width, height, depth);
1265 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1266 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1267 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1269 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
1270 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1272 //Verify only committed region
1273 for (GLint x = 0; x < widthCommitted; ++x)
1274 for (GLint y = 0; y < height; ++y)
1275 for (GLint z = 0; z < depth; ++z)
1277 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
1278 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
1279 if (dataRegion[0] != outDataRegion[0])
1285 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1286 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1287 << ", shaderSource: " << shader.c_str() << " - ";
1293 Texture::Delete(gl, verifyTexture);
1299 const GLfloat texCoord[] = {
1300 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
1303 const GLfloat vertices[] = {
1304 -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
1307 const GLuint indices[] = { 0, 1, 2, 1, 2, 3 };
1311 * @param context Rendering context
1313 UncommittedRegionsAccessTestCase::UncommittedRegionsAccessTestCase(deqp::Context& context)
1314 : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccess",
1315 "Verifies if access to uncommitted regions of sparse texture works as expected")
1317 /* Left blank intentionally */
1320 /** Stub init method */
1321 void UncommittedRegionsAccessTestCase::init()
1323 SparseTextureCommitmentTestCase::init();
1325 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
1326 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
1329 /** Executes test iteration.
1331 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1333 tcu::TestNode::IterateResult UncommittedRegionsAccessTestCase::iterate()
1335 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
1337 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1341 const Functions& gl = m_context.getRenderContext().getFunctions();
1347 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
1350 const GLint& target = *iter;
1352 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
1353 formIter != mSupportedInternalFormats.end(); ++formIter)
1355 const GLint& format = *formIter;
1357 if (!caseAllowed(target, format))
1361 mLog << "Testing uncommitted regions access for target: " << target << ", format: " << format << " - ";
1363 sparseAllocateTexture(gl, target, format, texture, 3);
1364 for (int l = 0; l < mState.levels; ++l)
1366 if (commitTexturePage(gl, target, format, texture, l))
1368 writeDataToTexture(gl, target, format, texture, l);
1369 result = result && UncommittedReads(gl, target, format, texture, l);
1370 result = result && UncommittedAtomicOperations(gl, target, format, texture, l);
1371 result = result && UncommittedDepthStencil(gl, target, format, texture, l);
1378 Texture::Delete(gl, texture);
1382 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
1383 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1389 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1393 /** Check if reads from uncommitted regions are allowed
1395 * @param target Target for which texture is binded
1396 * @param format Texture internal format
1398 * @return Returns true if allowed, false otherwise.
1400 bool UncommittedRegionsAccessTestCase::readsAllowed(GLint target, GLint format, bool shaderOnly)
1404 if (shaderOnly && (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5))
1412 /** Check if atomic operations on uncommitted regions are allowed
1414 * @param target Target for which texture is binded
1415 * @param format Texture internal format
1417 * @return Returns true if allowed, false otherwise.
1419 bool UncommittedRegionsAccessTestCase::atomicAllowed(GLint target, GLint format)
1423 if (format == GL_R32I || format == GL_R32UI)
1431 /** Check if depth and stencil test on uncommitted regions are allowed
1433 * @param target Target for which texture is binded
1434 * @param format Texture internal format
1436 * @return Returns true if allowed, false otherwise.
1438 bool UncommittedRegionsAccessTestCase::depthStencilAllowed(GLint target, GLint format)
1440 if (target == GL_TEXTURE_2D && format == GL_RGBA8)
1448 /** Verify reads from uncommitted texture regions works as expected
1450 * @param gl GL API functions
1451 * @param target Target for which texture is binded
1452 * @param format Texture internal format
1453 * @param texture Texture object
1454 * @param level Texture mipmap level
1456 * @return Returns true if data is as expected, false otherwise.
1458 bool UncommittedRegionsAccessTestCase::UncommittedReads(const Functions& gl, GLint target, GLint format,
1459 GLuint& texture, GLint level)
1463 // Verify using API glGetTexImage*
1464 if (readsAllowed(target, format, false))
1466 mLog << "API Reads - ";
1467 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1470 // Verify using shader imageLoad function
1471 if (result && readsAllowed(target, format, true))
1473 mLog << "Shader Reads - ";
1474 result = result && verifyTextureDataExtended(gl, target, format, texture, level, true);
1477 // Verify mipmap generating
1478 if (result && level == 0 && target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
1479 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1481 mLog << "Mipmap Generate - ";
1482 Texture::Bind(gl, texture, target);
1483 gl.generateMipmap(target);
1484 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap");
1486 for (int l = 1; l < mState.levels; ++l)
1487 result = result && verifyTextureDataExtended(gl, target, format, texture, level, false);
1493 /** Verify atomic operations on uncommitted texture pixels works as expected
1495 * @param gl GL API functions
1496 * @param target Target for which texture is binded
1497 * @param format Texture internal format
1498 * @param texture Texture object
1499 * @param level Texture mipmap level
1501 * @return Returns true if data is as expected, false otherwise.
1503 bool UncommittedRegionsAccessTestCase::UncommittedAtomicOperations(const Functions& gl, GLint target, GLint format,
1504 GLuint& texture, GLint level)
1508 if (atomicAllowed(target, format))
1510 mLog << "Atomic Operations - ";
1511 result = result && verifyAtomicOperations(gl, target, format, texture, level);
1517 /** Verify depth and stencil tests on uncommitted texture pixels works as expected
1519 * @param gl GL API functions
1520 * @param target Target for which texture is binded
1521 * @param format Texture internal format
1522 * @param texture Texture object
1523 * @param level Texture mipmap level
1525 * @return Returns true if data is as expected, false otherwise.
1527 bool UncommittedRegionsAccessTestCase::UncommittedDepthStencil(const Functions& gl, GLint target, GLint format,
1528 GLuint& texture, GLint level)
1530 if (!depthStencilAllowed(target, format))
1533 mLog << "Depth Stencil - ";
1540 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1542 //Committed region is limited to 1/2 of width
1543 GLuint widthCommitted = width / 2;
1545 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1549 std::string vertexSource = st2_vertex_drawBuffer;
1550 std::string fragmentSource = st2_fragment_drawBuffer;
1552 ShaderProgram program(gl, glu::makeVtxFragSources(vertexSource, fragmentSource));
1553 if (!program.isOk())
1555 mLog << "Shader compilation failed (depth_stencil) for target: " << target << ", format: " << format
1556 << ", vertex_infoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog
1557 << ", fragment_infoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog
1558 << ", vertexSource: " << vertexSource.c_str() << "\n"
1559 << ", fragmentSource: " << fragmentSource.c_str() << " - ";
1564 prepareDepthStencilFramebuffer(gl, width, height);
1566 gl.useProgram(program.getProgram());
1568 gl.activeTexture(GL_TEXTURE0);
1569 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
1570 Texture::Bind(gl, texture, target);
1572 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1575 result = result && verifyStencilTest(gl, program, width, height, widthCommitted);
1578 result = result && verifyDepthTest(gl, program, width, height, widthCommitted);
1580 // Depth bounds test
1581 if (m_context.getContextInfo().isExtensionSupported("GL_EXT_depth_bounds_test"))
1582 result = result && verifyDepthBoundsTest(gl, program, width, height, widthCommitted);
1584 // Resources cleaning
1585 cleanupDepthStencilFramebuffer(gl);
1590 /** Prepare gl depth and stencil test resources
1592 * @param gl GL API functions
1593 * @param width Framebuffer width
1594 * @param height Framebuffer height
1596 void UncommittedRegionsAccessTestCase::prepareDepthStencilFramebuffer(const Functions& gl, GLint width, GLint height)
1598 gl.genRenderbuffers(1, &mRenderbuffer);
1599 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers");
1600 gl.bindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
1601 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer");
1602 if (mState.samples == 1)
1604 gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
1605 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage");
1609 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, mState.samples, GL_DEPTH_STENCIL, width, height);
1610 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample");
1613 gl.genFramebuffers(1, &mFramebuffer);
1614 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
1615 gl.bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
1616 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1617 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer);
1618 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer");
1619 gl.viewport(0, 0, width, height);
1622 /** Cleanup gl depth and stencil test resources
1624 * @param gl GL API functions
1626 void UncommittedRegionsAccessTestCase::cleanupDepthStencilFramebuffer(const Functions& gl)
1628 gl.deleteFramebuffers(1, &mFramebuffer);
1629 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1630 gl.deleteRenderbuffers(1, &mRenderbuffer);
1631 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers");
1633 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1634 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1637 /** Verify if data stored in texture in uncommitted regions is as expected
1639 * @param gl GL API functions
1640 * @param target Target for which texture is binded
1641 * @param format Texture internal format
1642 * @param texture Texture object
1643 * @param level Texture mipmap level
1644 * @param shaderOnly Shader texture filling flag, default false
1646 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1648 bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions& gl, GLint target, GLint format,
1649 GLuint& texture, GLint level, bool shaderOnly)
1651 mLog << "Verify Texture [level: " << level << "] - ";
1653 if (level > mState.levels - 1)
1654 TCU_FAIL("Invalid level");
1656 TransferFormat transferFormat = glu::getTransferFormat(mState.format);
1661 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1663 //Committed region is limited to 1/2 of width
1664 GLint widthCommitted = width / 2;
1666 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1671 // Verify texture using API glGetTexImage* (Skip multisample textures as it can not be verified using API)
1672 if (!shaderOnly && target != GL_TEXTURE_CUBE_MAP && target != GL_TEXTURE_2D_MULTISAMPLE &&
1673 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
1675 GLint texSize = width * height * depth * mState.format.getPixelSize();
1677 std::vector<GLubyte> vecExpData;
1678 std::vector<GLubyte> vecOutData;
1679 vecExpData.resize(texSize);
1680 vecOutData.resize(texSize);
1681 GLubyte* exp_data = vecExpData.data();
1682 GLubyte* out_data = vecOutData.data();
1684 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
1685 deMemset(exp_data, 0, texSize);
1686 deMemset(out_data, 255, texSize);
1688 Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1689 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1691 //Verify only uncommitted region
1692 for (GLint x = widthCommitted; x < width; ++x)
1693 for (GLint y = 0; y < height; ++y)
1694 for (GLint z = 0; z < depth; ++z)
1696 int pixelSize = mState.format.getPixelSize();
1697 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1698 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1699 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1703 // Verify texture using API glGetTexImage* (Only cube map as it has to be verified for subtargets)
1704 else if (!shaderOnly && target == GL_TEXTURE_CUBE_MAP)
1706 std::vector<GLint> subTargets;
1708 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
1709 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
1710 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
1711 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
1712 subTargets.push_back(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
1713 subTargets.push_back(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
1715 GLint texSize = width * height * mState.format.getPixelSize();
1717 std::vector<GLubyte> vecExpData;
1718 std::vector<GLubyte> vecOutData;
1719 vecExpData.resize(texSize);
1720 vecOutData.resize(texSize);
1721 GLubyte* exp_data = vecExpData.data();
1722 GLubyte* out_data = vecOutData.data();
1724 deMemset(exp_data, 0, texSize);
1726 for (size_t i = 0; i < subTargets.size(); ++i)
1728 GLint subTarget = subTargets[i];
1730 mLog << "Verify Subtarget [subtarget: " << subTarget << "] - ";
1732 deMemset(out_data, 255, texSize);
1734 Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data);
1735 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1737 //Verify only uncommitted region
1738 for (GLint x = widthCommitted; x < width; ++x)
1739 for (GLint y = 0; y < height; ++y)
1740 for (GLint z = 0; z < depth; ++z)
1742 int pixelSize = mState.format.getPixelSize();
1743 GLubyte* dataRegion = exp_data + ((x + y * width) * pixelSize);
1744 GLubyte* outDataRegion = out_data + ((x + y * width) * pixelSize);
1745 if (deMemCmp(dataRegion, outDataRegion, pixelSize) != 0)
1753 // Verify texture using shader imageLoad function
1754 else if (shaderOnly)
1756 // Create verifying texture
1758 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1759 verifyTarget = GL_TEXTURE_2D;
1761 verifyTarget = GL_TEXTURE_2D_ARRAY;
1763 if (target == GL_TEXTURE_CUBE_MAP)
1766 GLint texSize = width * height * depth;
1768 std::vector<GLubyte> vecExpData;
1769 std::vector<GLubyte> vecOutData;
1770 vecExpData.resize(texSize);
1771 vecOutData.resize(texSize);
1772 GLubyte* exp_data = vecExpData.data();
1773 GLubyte* out_data = vecOutData.data();
1775 // Expected value in this case is 255 because shader fills output texture with 255 if in texture is filled with zeros
1776 deMemset(exp_data, 255, texSize);
1778 GLuint verifyTexture;
1779 Texture::Generate(gl, verifyTexture);
1780 Texture::Bind(gl, verifyTexture, verifyTarget);
1781 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1782 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1784 for (GLint sample = 0; sample < mState.samples; ++sample)
1786 deMemset(out_data, 0, texSize);
1788 Texture::Bind(gl, verifyTexture, verifyTarget);
1789 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1791 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1793 std::string shader = st2_compute_textureVerify;
1795 // Adjust shader source to texture format
1796 TokenStrings s = createShaderTokens(target, format, sample);
1798 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1799 replaceToken("<FORMAT>", s.format.c_str(), shader);
1800 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1801 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1802 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1803 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1804 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1805 replaceToken("<RESULT_EXPECTED>", s.resultDefault.c_str(), shader);
1806 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
1808 ProgramSources sources;
1809 sources << ComputeSource(shader);
1811 // Build and run shader
1812 ShaderProgram program(m_context.getRenderContext(), sources);
1815 gl.useProgram(program.getProgram());
1816 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1817 gl.bindImageTexture(0, //unit
1822 GL_WRITE_ONLY, GL_R8UI);
1823 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1824 gl.bindImageTexture(1, //unit
1829 GL_READ_ONLY, format);
1830 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1831 gl.uniform1i(1, 0 /* image_unit */);
1832 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1833 gl.uniform1i(2, 1 /* image_unit */);
1834 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1835 gl.dispatchCompute(width, height, depth);
1836 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1837 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1838 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1840 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
1841 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1843 //Verify only committed region
1844 for (GLint x = widthCommitted; x < width; ++x)
1845 for (GLint y = 0; y < height; ++y)
1846 for (GLint z = 0; z < depth; ++z)
1848 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
1849 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
1850 if (dataRegion[0] != outDataRegion[0])
1856 mLog << "Compute shader compilation failed (reading) for target: " << target << ", format: " << format
1857 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
1858 << ", shaderSource: " << shader.c_str() << " - ";
1864 Texture::Delete(gl, verifyTexture);
1870 /** Verify if atomic operations on uncommitted regions returns zeros and has no effect on texture
1872 * @param gl GL API functions
1873 * @param target Target for which texture is binded
1874 * @param format Texture internal format
1875 * @param texture Texture object
1876 * @param level Texture mipmap level
1878 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
1880 bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& gl, GLint target, GLint format,
1881 GLuint& texture, GLint level)
1883 mLog << "Verify Atomic Operations [level: " << level << "] - ";
1885 if (level > mState.levels - 1)
1886 TCU_FAIL("Invalid level");
1891 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
1893 //Committed region is limited to 1/2 of width
1894 GLint widthCommitted = width / 2;
1896 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
1901 // Create verifying texture
1903 if (target == GL_TEXTURE_2D_MULTISAMPLE)
1904 verifyTarget = GL_TEXTURE_2D;
1906 verifyTarget = GL_TEXTURE_2D_ARRAY;
1908 GLint texSize = width * height * depth;
1910 std::vector<GLubyte> vecExpData;
1911 std::vector<GLubyte> vecOutData;
1912 vecExpData.resize(texSize);
1913 vecOutData.resize(texSize);
1914 GLubyte* exp_data = vecExpData.data();
1915 GLubyte* out_data = vecOutData.data();
1917 // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros
1918 deMemset(exp_data, 0, texSize);
1920 GLuint verifyTexture;
1921 Texture::Generate(gl, verifyTexture);
1922 Texture::Bind(gl, verifyTexture, verifyTarget);
1923 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
1924 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
1926 for (GLint sample = 0; sample < mState.samples; ++sample)
1928 deMemset(out_data, 255, texSize);
1930 Texture::Bind(gl, verifyTexture, verifyTarget);
1931 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
1933 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
1935 std::string shader = st2_compute_atomicVerify;
1937 // Adjust shader source to texture format
1938 TokenStrings s = createShaderTokens(target, format, sample);
1939 std::string dataType = (s.returnType == "ivec4" ? "int" : "uint");
1941 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
1942 replaceToken("<FORMAT>", s.format.c_str(), shader);
1943 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
1944 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
1945 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
1946 replaceToken("<DATA_TYPE>", dataType.c_str(), shader);
1947 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
1948 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
1950 ProgramSources sources;
1951 sources << ComputeSource(shader);
1953 // Build and run shader
1954 ShaderProgram program(m_context.getRenderContext(), sources);
1957 gl.useProgram(program.getProgram());
1958 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
1959 gl.bindImageTexture(0, //unit
1964 GL_WRITE_ONLY, GL_R8UI);
1965 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1966 gl.bindImageTexture(1, //unit
1971 GL_READ_ONLY, format);
1972 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
1973 gl.uniform1i(1, 0 /* image_unit */);
1974 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1975 gl.uniform1i(2, 1 /* image_unit */);
1976 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1977 gl.uniform1i(3, widthCommitted /* committed width */);
1978 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
1979 gl.dispatchCompute(width, height, depth);
1980 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
1981 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
1982 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
1984 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
1985 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
1987 //Verify only committed region
1988 for (GLint x = 0; x < width; ++x)
1989 for (GLint y = 0; y < height; ++y)
1990 for (GLint z = 0; z < depth; ++z)
1992 GLubyte* dataRegion = exp_data + ((x + y * width) + z * width * height);
1993 GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height);
1994 if (dataRegion[0] != outDataRegion[0])
1996 printf("%d:%d ", dataRegion[0], outDataRegion[0]);
2003 mLog << "Compute shader compilation failed (atomic) for target: " << target << ", format: " << format
2004 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2005 << ", shaderSource: " << shader.c_str() << " - ";
2011 Texture::Delete(gl, verifyTexture);
2016 /** Verify if stencil test on uncommitted texture region works as expected texture
2018 * @param gl GL API functions
2019 * @param program Shader program
2020 * @param width Texture width
2021 * @param height Texture height
2022 * @param widthCommitted Committed region width
2024 * @return Returns true if stencil data is as expected, false otherwise.
2026 bool UncommittedRegionsAccessTestCase::verifyStencilTest(const Functions& gl, ShaderProgram& program, GLint width,
2027 GLint height, GLint widthCommitted)
2029 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2030 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2032 mLog << "Perform Stencil Test - ";
2034 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2035 gl.enable(GL_STENCIL_TEST);
2036 gl.stencilFunc(GL_GREATER, 1, 0xFF);
2037 gl.stencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
2039 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2040 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2042 std::vector<GLubyte> dataStencil;
2043 dataStencil.resize(width * height);
2044 GLubyte* dataStencilPtr = dataStencil.data();
2046 gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, (GLvoid*)dataStencilPtr);
2047 for (int x = widthCommitted; x < width; ++x)
2048 for (int y = 0; y < height; ++y)
2050 if (dataStencilPtr[x + y * width] != 0x00)
2052 gl.disable(GL_STENCIL_TEST);
2057 gl.disable(GL_STENCIL_TEST);
2061 /** Verify if depth test on uncommitted texture region works as expected texture
2063 * @param gl GL API functions
2064 * @param program Shader program
2065 * @param width Texture width
2066 * @param height Texture height
2067 * @param widthCommitted Committed region width
2069 * @return Returns true if depth data is as expected, false otherwise.
2071 bool UncommittedRegionsAccessTestCase::verifyDepthTest(const Functions& gl, ShaderProgram& program, GLint width,
2072 GLint height, GLint widthCommitted)
2074 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2075 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2077 mLog << "Perform Depth Test - ";
2079 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2080 gl.enable(GL_DEPTH_TEST);
2081 gl.depthFunc(GL_LESS);
2083 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2084 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2086 std::vector<GLuint> dataDepth;
2087 dataDepth.resize(width * height);
2088 GLuint* dataDepthPtr = dataDepth.data();
2090 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr);
2091 for (int x = widthCommitted; x < width; ++x)
2092 for (int y = 0; y < height; ++y)
2094 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2096 gl.disable(GL_DEPTH_TEST);
2101 gl.disable(GL_DEPTH_TEST);
2105 /** Verify if depth bounds test on uncommitted texture region works as expected texture
2107 * @param gl GL API functions
2108 * @param program Shader program
2109 * @param width Texture width
2110 * @param height Texture height
2111 * @param widthCommitted Committed region width
2113 * @return Returns true if depth data is as expected, false otherwise.
2115 bool UncommittedRegionsAccessTestCase::verifyDepthBoundsTest(const Functions& gl, ShaderProgram& program, GLint width,
2116 GLint height, GLint widthCommitted)
2118 glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices),
2119 glu::va::Float("inTexCoord", 2, 4, 0, texCoord) };
2121 mLog << "Perform Depth Bounds Test - ";
2123 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2124 gl.enable(GL_DEPTH_BOUNDS_TEST_EXT);
2125 gl.depthFunc(GL_LESS);
2127 glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
2128 glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
2130 std::vector<GLuint> dataDepth;
2131 dataDepth.resize(width * height);
2132 GLuint* dataDepthPtr = dataDepth.data();
2134 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, (GLvoid*)dataDepthPtr);
2135 for (int x = widthCommitted; x < width; ++x)
2136 for (int y = 0; y < height; ++y)
2138 if (dataDepthPtr[x + y * width] != 0xFFFFFFFF)
2140 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2145 gl.disable(GL_DEPTH_BOUNDS_TEST_EXT);
2151 * @param context Rendering context
2153 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context)
2154 : SparseTexture2CommitmentTestCase(context, "SparseTexture2Lookup",
2155 "Verifies if sparse texture lookup functions for GLSL works as expected")
2157 /* Left blank intentionally */
2162 * @param context Rendering context
2164 SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context, const char* name,
2165 const char* description)
2166 : SparseTexture2CommitmentTestCase(context, name, description)
2168 /* Left blank intentionally */
2171 /** Initializes the test group contents. */
2172 void SparseTexture2LookupTestCase::init()
2174 SparseTextureCommitmentTestCase::init();
2175 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE);
2176 mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2178 mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16);
2181 f = FunctionToken("sparseTextureARB", "<CUBE_REFZ_DEF>");
2182 f.allowedTargets.insert(GL_TEXTURE_2D);
2183 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2184 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2185 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2186 f.allowedTargets.insert(GL_TEXTURE_3D);
2187 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2188 mFunctions.push_back(f);
2190 f = FunctionToken("sparseTextureLodARB", ", <LOD>");
2191 f.allowedTargets.insert(GL_TEXTURE_2D);
2192 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2193 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2194 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2195 f.allowedTargets.insert(GL_TEXTURE_3D);
2196 mFunctions.push_back(f);
2198 f = FunctionToken("sparseTextureOffsetARB", ", <OFFSET_TYPE><OFFSET_DIM>(0)");
2199 f.allowedTargets.insert(GL_TEXTURE_2D);
2200 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2201 f.allowedTargets.insert(GL_TEXTURE_3D);
2202 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2203 mFunctions.push_back(f);
2205 f = FunctionToken("sparseTexelFetchARB", "<LOD_DEF>");
2206 f.allowedTargets.insert(GL_TEXTURE_2D);
2207 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2208 f.allowedTargets.insert(GL_TEXTURE_3D);
2209 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2210 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2211 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2212 mFunctions.push_back(f);
2214 f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2215 f.allowedTargets.insert(GL_TEXTURE_2D);
2216 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2217 f.allowedTargets.insert(GL_TEXTURE_3D);
2218 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2219 mFunctions.push_back(f);
2221 f = FunctionToken("sparseTextureLodOffsetARB", ", <LOD>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2222 f.allowedTargets.insert(GL_TEXTURE_2D);
2223 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2224 f.allowedTargets.insert(GL_TEXTURE_3D);
2225 mFunctions.push_back(f);
2227 f = FunctionToken("sparseTextureGradARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0)");
2228 f.allowedTargets.insert(GL_TEXTURE_2D);
2229 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2230 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2231 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2232 f.allowedTargets.insert(GL_TEXTURE_3D);
2233 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2234 mFunctions.push_back(f);
2236 f = FunctionToken("sparseTextureGradOffsetARB",
2237 ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0)");
2238 f.allowedTargets.insert(GL_TEXTURE_2D);
2239 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2240 f.allowedTargets.insert(GL_TEXTURE_3D);
2241 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2242 mFunctions.push_back(f);
2244 f = FunctionToken("sparseTextureGatherARB", "<REFZ_DEF>");
2245 f.allowedTargets.insert(GL_TEXTURE_2D);
2246 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2247 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2248 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2249 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2250 mFunctions.push_back(f);
2252 f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
2253 f.allowedTargets.insert(GL_TEXTURE_2D);
2254 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2255 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2256 mFunctions.push_back(f);
2258 f = FunctionToken("sparseTextureGatherOffsetsARB", "<REFZ_DEF>, offsetsArray");
2259 f.allowedTargets.insert(GL_TEXTURE_2D);
2260 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2261 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2262 mFunctions.push_back(f);
2264 f = FunctionToken("sparseImageLoadARB", "");
2265 f.allowedTargets.insert(GL_TEXTURE_2D);
2266 f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
2267 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
2268 f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY);
2269 f.allowedTargets.insert(GL_TEXTURE_3D);
2270 f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
2271 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE);
2272 f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
2273 //mFunctions.push_back(f);
2276 /** Executes test iteration.
2278 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2280 tcu::TestNode::IterateResult SparseTexture2LookupTestCase::iterate()
2282 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
2284 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2288 const Functions& gl = m_context.getRenderContext().getFunctions();
2294 for (std::vector<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
2297 const GLint& target = *iter;
2299 for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
2300 formIter != mSupportedInternalFormats.end(); ++formIter)
2302 const GLint& format = *formIter;
2304 if (!caseAllowed(target, format))
2307 for (std::vector<FunctionToken>::const_iterator tokIter = mFunctions.begin(); tokIter != mFunctions.end();
2310 // Check if target is allowed for current lookup function
2311 FunctionToken funcToken = *tokIter;
2312 if (!funcAllowed(target, format, funcToken))
2316 mLog << "Testing sparse texture lookup functions for target: " << target << ", format: " << format
2319 sparseAllocateTexture(gl, target, format, texture, 3);
2320 if (format == GL_DEPTH_COMPONENT16)
2321 setupDepthMode(gl, target, texture);
2323 for (int l = 0; l < mState.levels; ++l)
2325 if (commitTexturePage(gl, target, format, texture, l))
2327 writeDataToTexture(gl, target, format, texture, l);
2328 result = result && verifyLookupTextureData(gl, target, format, texture, l, funcToken);
2335 Texture::Delete(gl, texture);
2339 m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage;
2340 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2347 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2351 /** Create set of token strings fit to lookup functions verifying shader
2353 * @param target Target for which texture is binded
2354 * @param format Texture internal format
2355 * @param level Texture mipmap level
2356 * @param sample Texture sample number
2357 * @param funcToken Texture lookup function structure
2359 * @return Returns extended token strings structure.
2361 SparseTexture2LookupTestCase::TokenStringsExt SparseTexture2LookupTestCase::createLookupShaderTokens(
2362 GLint target, GLint format, GLint level, GLint sample, FunctionToken& funcToken)
2364 std::string funcName = funcToken.name;
2368 std::string inputType;
2369 std::string samplerSufix;
2371 if (funcName == "sparseImageLoadARB")
2372 inputType = "image";
2374 inputType = "sampler";
2376 // Copy data from TokenStrings to TokenStringsExt
2377 TokenStrings ss = createShaderTokens(target, format, sample, "image", inputType);
2378 s.epsilon = ss.epsilon;
2379 s.format = ss.format;
2380 s.inputType = ss.inputType;
2381 s.outputType = ss.outputType;
2382 s.pointDef = ss.pointDef;
2383 s.pointType = ss.pointType;
2384 s.resultDefault = ss.resultDefault;
2385 s.resultExpected = ss.resultExpected;
2386 s.returnType = ss.returnType;
2387 s.sampleDef = ss.sampleDef;
2389 // Set format definition for image input types
2390 if (inputType == "image")
2391 s.formatDef = ", " + s.format;
2393 // Set tokens for depth texture format
2394 if (format == GL_DEPTH_COMPONENT16)
2396 s.refZDef = ", 0.5";
2398 if (inputType == "sampler" && target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_MULTISAMPLE &&
2399 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2401 s.inputType = s.inputType + "Shadow";
2405 // Set coord type, coord definition and offset vector dimensions
2406 s.coordType = "vec2";
2407 s.offsetType = "ivec";
2408 s.nOffsetType = "vec";
2410 if (target == GL_TEXTURE_1D)
2412 s.coordType = "float";
2413 s.offsetType = "int";
2414 s.nOffsetType = "float";
2417 else if (target == GL_TEXTURE_1D_ARRAY)
2419 s.coordType = "vec2";
2420 s.offsetType = "int";
2421 s.nOffsetType = "float";
2424 else if (target == GL_TEXTURE_2D_ARRAY)
2426 s.coordType = "vec3";
2428 else if (target == GL_TEXTURE_3D)
2430 s.coordType = "vec3";
2433 else if (target == GL_TEXTURE_CUBE_MAP)
2435 s.coordType = "vec3";
2438 else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2440 s.coordType = "vec4";
2441 s.coordDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6, floor(gl_WorkGroupID.z / 6)";
2444 else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2446 s.coordType = "vec3";
2449 if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
2450 funcName.find("Fetch", 0) == std::string::npos)
2452 s.cubeMapCoordDef = " int face = point.z % 6;\n"
2453 " if (face == 0) coord.xyz = vec3(1, coord.y * 2 - 1, -coord.x * 2 + 1);\n"
2454 " if (face == 1) coord.xyz = vec3(-1, coord.y * 2 - 1, coord.x * 2 - 1);\n"
2455 " if (face == 2) coord.xyz = vec3(coord.x * 2 - 1, 1, coord.y * 2 - 1);\n"
2456 " if (face == 3) coord.xyz = vec3(coord.x * 2 - 1, -1, -coord.y * 2 + 1);\n"
2457 " if (face == 4) coord.xyz = vec3(coord.x * 2 - 1, coord.y * 2 - 1, 1);\n"
2458 " if (face == 5) coord.xyz = vec3(-coord.x * 2 + 1, coord.y * 2 - 1, -1);\n";
2461 if (s.coordDef.empty())
2462 s.coordDef = s.pointDef;
2464 // Set expected result vector, component definition and offset array definition for gather functions
2465 if (funcName.find("Gather", 0) != std::string::npos)
2467 if (funcName.find("GatherOffsets", 0) != std::string::npos)
2469 s.offsetArrayDef = " <OFFSET_TYPE><OFFSET_DIM> offsetsArray[4];\n"
2470 " offsetsArray[0] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2471 " offsetsArray[1] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2472 " offsetsArray[2] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
2473 " offsetsArray[3] = <OFFSET_TYPE><OFFSET_DIM>(0);\n";
2476 if (format != GL_DEPTH_COMPONENT16)
2477 s.componentDef = ", 0";
2478 s.resultExpected = "(1, 1, 1, 1)";
2480 // Extend coord type dimension and coord vector definition if shadow sampler and non-cube map array target selected
2481 // Set component definition to red component
2482 else if (format == GL_DEPTH_COMPONENT16)
2484 if (target != GL_TEXTURE_CUBE_MAP_ARRAY)
2486 if (s.coordType == "float")
2487 s.coordType = "vec3";
2488 else if (s.coordType == "vec2")
2489 s.coordType = "vec3";
2490 else if (s.coordType == "vec3")
2491 s.coordType = "vec4";
2492 s.coordDef += s.refZDef;
2495 s.cubeMapArrayRefZDef = s.refZDef;
2497 s.componentDef = ".r";
2500 // Set level of details definition
2501 if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
2502 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
2504 s.lod = de::toString(level);
2505 s.lodDef = ", " + de::toString(level);
2508 // Set proper coord vector
2509 if (target == GL_TEXTURE_RECTANGLE || funcName.find("Fetch") != std::string::npos ||
2510 funcName.find("ImageLoad") != std::string::npos)
2512 s.pointCoord = "icoord";
2515 s.pointCoord = "coord";
2517 // Set size vector definition
2518 if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos)
2520 if (s.coordType == "float")
2521 s.sizeDef = "<TEX_WIDTH>";
2522 else if (s.coordType == "vec2" && target == GL_TEXTURE_1D_ARRAY)
2523 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>";
2524 else if (s.coordType == "vec2")
2525 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>";
2526 else if (s.coordType == "vec3")
2527 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>";
2528 else if (s.coordType == "vec4")
2529 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, floor(<TEX_DEPTH> / 6), 6";
2531 // Set size vector for shadow samplers and non-gether functions selected
2534 if (s.coordType == "vec3" && target == GL_TEXTURE_1D)
2535 s.sizeDef = "<TEX_WIDTH>, 1 , 1";
2536 else if (s.coordType == "vec3" && target == GL_TEXTURE_1D_ARRAY)
2537 s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>, 1";
2538 else if (s.coordType == "vec3")
2539 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 1";
2540 else if (s.coordType == "vec4")
2541 s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>, 1";
2544 if (s.coordType != "float")
2545 s.iCoordType = "i" + s.coordType;
2547 s.iCoordType = "int";
2552 /** Check if specific combination of target and format is
2555 * @param target Target for which texture is binded
2556 * @param format Texture internal format
2558 * @return Returns true if target/format combination is allowed, false otherwise.
2560 bool SparseTexture2LookupTestCase::caseAllowed(GLint target, GLint format)
2564 // As shaders do not support some texture formats it is necessary to exclude them.
2565 if (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5)
2570 if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_3D) &&
2571 (format == GL_DEPTH_COMPONENT16))
2579 /** Check if specific lookup function is allowed for specific target and format
2581 * @param target Target for which texture is binded
2582 * @param format Texture internal format
2583 * @param funcToken Texture lookup function structure
2585 * @return Returns true if target/format combination is allowed, false otherwise.
2587 bool SparseTexture2LookupTestCase::funcAllowed(GLint target, GLint format, FunctionToken& funcToken)
2589 if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end())
2592 if (format == GL_DEPTH_COMPONENT16)
2594 if (funcToken.name == "sparseTextureLodARB" || funcToken.name == "sparseTextureLodOffsetARB")
2596 if (target != GL_TEXTURE_2D)
2599 else if (funcToken.name == "sparseTextureOffsetARB" || funcToken.name == "sparseTextureGradOffsetARB" ||
2600 funcToken.name == "sparseTextureGatherOffsetARB" || funcToken.name == "sparseTextureGatherOffsetsARB")
2602 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE)
2607 else if (funcToken.name == "sparseTexelFetchARB" || funcToken.name == "sparseTexelFetchOffsetARB")
2611 else if (funcToken.name == "sparseTextureGradARB")
2613 if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
2616 else if (funcToken.name == "sparseImageLoadARB")
2625 /** Writing data to generated texture using compute shader
2627 * @param gl GL API functions
2628 * @param target Target for which texture is binded
2629 * @param format Texture internal format
2630 * @param texture Texture object
2632 * @return Returns true if no error occurred, otherwise throws an exception.
2634 bool SparseTexture2LookupTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture,
2637 mLog << "Fill Texture with shader [level: " << level << "] - ";
2639 if (level > mState.levels - 1)
2640 TCU_FAIL("Invalid level");
2645 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2647 if (width > 0 && height > 0 && depth >= mState.minDepth)
2649 if (target == GL_TEXTURE_CUBE_MAP)
2652 GLint texSize = width * height * depth * mState.format.getPixelSize();
2654 std::vector<GLubyte> vecData;
2655 vecData.resize(texSize);
2656 GLubyte* data = vecData.data();
2658 deMemset(data, 255, texSize);
2660 for (GLint sample = 0; sample < mState.samples; ++sample)
2662 std::string shader = st2_compute_textureFill;
2664 // Adjust shader source to texture format
2665 TokenStrings s = createShaderTokens(target, format, sample);
2667 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2668 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2669 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2670 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2671 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2672 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2674 ProgramSources sources;
2675 sources << ComputeSource(shader);
2677 GLint convFormat = format;
2678 if (format == GL_DEPTH_COMPONENT16)
2679 convFormat = GL_R16;
2681 // Build and run shader
2682 ShaderProgram program(m_context.getRenderContext(), sources);
2685 gl.useProgram(program.getProgram());
2686 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2687 gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */,
2688 GL_WRITE_ONLY, convFormat);
2689 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2690 gl.uniform1i(1, 0 /* image_unit */);
2691 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2692 gl.dispatchCompute(width, height, depth);
2693 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2694 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2695 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2699 mLog << "Compute shader compilation failed (writing) for target: " << target << ", format: " << format
2700 << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2701 << ", shaderSource: " << shader.c_str() << " - ";
2709 /** Setup depth compare mode and compare function for depth texture
2711 * @param gl GL API functions
2712 * @param target Target for which texture is binded
2713 * @param texture Texture object
2715 void SparseTexture2LookupTestCase::setupDepthMode(const Functions& gl, GLint target, GLuint& texture)
2717 Texture::Bind(gl, texture, target);
2718 gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
2719 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2720 gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS);
2721 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
2724 /** Verify if data stored in texture is as expected
2726 * @param gl GL API functions
2727 * @param target Target for which texture is binded
2728 * @param format Texture internal format
2729 * @param texture Texture object
2730 * @param level Texture mipmap level
2731 * @param funcToken Lookup function tokenize structure
2733 * @return Returns true if data is as expected, false if not, throws an exception if error occurred.
2735 bool SparseTexture2LookupTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format,
2736 GLuint& texture, GLint level, FunctionToken& funcToken)
2738 mLog << "Verify Lookup Texture Data [function: " << funcToken.name << ", level: " << level << "] - ";
2740 if (level > mState.levels - 1)
2741 TCU_FAIL("Invalid level");
2746 SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
2748 //Committed region is limited to 1/2 of width
2749 GLint widthCommitted = width / 2;
2751 if (widthCommitted == 0 || height == 0 || depth < mState.minDepth)
2756 if (target == GL_TEXTURE_CUBE_MAP)
2759 GLint texSize = width * height * depth;
2761 std::vector<GLubyte> vecExpData;
2762 std::vector<GLubyte> vecOutData;
2763 vecExpData.resize(texSize);
2764 vecOutData.resize(texSize);
2765 GLubyte* exp_data = vecExpData.data();
2766 GLubyte* out_data = vecOutData.data();
2768 // Expected data is 255 because
2769 deMemset(exp_data, 255, texSize);
2771 // Make token copy to work on
2772 FunctionToken f = funcToken;
2774 // Create verifying texture
2776 if (target == GL_TEXTURE_2D_MULTISAMPLE)
2777 verifyTarget = GL_TEXTURE_2D;
2779 verifyTarget = GL_TEXTURE_2D_ARRAY;
2781 GLuint verifyTexture;
2782 Texture::Generate(gl, verifyTexture);
2783 Texture::Bind(gl, verifyTexture, verifyTarget);
2784 Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth);
2785 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage");
2787 for (int sample = 0; sample < mState.samples; ++sample)
2789 deMemset(out_data, 0, texSize);
2791 Texture::Bind(gl, verifyTexture, verifyTarget);
2792 Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE,
2794 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
2796 std::string shader = st2_compute_lookupVerify;
2798 // Adjust shader source to texture format
2799 TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f);
2801 replaceToken("<FUNCTION>", f.name.c_str(), shader);
2802 replaceToken("<ARGUMENTS>", f.arguments.c_str(), shader);
2804 replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
2805 replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
2806 replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), shader);
2807 replaceToken("<LOD>", s.lod.c_str(), shader);
2808 replaceToken("<LOD_DEF>", s.lodDef.c_str(), shader);
2809 replaceToken("<COORD_TYPE>", s.coordType.c_str(), shader);
2810 replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), shader);
2811 replaceToken("<COORD_DEF>", s.coordDef.c_str(), shader);
2812 replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
2813 replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
2814 replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
2815 replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
2816 replaceToken("<EPSILON>", s.epsilon.c_str(), shader);
2817 replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), shader);
2818 replaceToken("<REFZ_DEF>", s.refZDef.c_str(), shader);
2819 replaceToken("<CUBE_REFZ_DEF>", s.cubeMapArrayRefZDef.c_str(), shader);
2820 replaceToken("<POINT_COORD>", s.pointCoord.c_str(), shader);
2821 replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), shader);
2822 replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), shader);
2823 replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), shader);
2824 replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), shader);
2825 replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), shader);
2826 replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), shader);
2827 replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), shader);
2829 replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), shader);
2830 replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), shader);
2831 replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), shader);
2833 ProgramSources sources;
2834 sources << ComputeSource(shader);
2836 // Build and run shader
2837 ShaderProgram program(m_context.getRenderContext(), sources);
2840 gl.useProgram(program.getProgram());
2841 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2843 // Pass output image to shader
2844 gl.bindImageTexture(1, //unit
2849 GL_WRITE_ONLY, GL_R8UI);
2850 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2851 gl.uniform1i(1, 1 /* image_unit */);
2852 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2854 // Pass input sampler/image to shader
2855 if (f.name != "sparseImageLoadARB")
2857 gl.activeTexture(GL_TEXTURE0);
2858 GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
2859 gl.bindTexture(target, texture);
2860 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
2861 gl.uniform1i(2, 0 /* sampler_unit */);
2862 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2866 gl.bindImageTexture(0, //unit
2871 GL_READ_ONLY, format);
2872 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture");
2873 gl.uniform1i(2, 0 /* image_unit */);
2874 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2877 // Pass committed region width to shader
2878 gl.uniform1i(3, widthCommitted /* committed region width */);
2879 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
2880 gl.dispatchCompute(width, height, depth);
2881 GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute");
2882 gl.memoryBarrier(GL_ALL_BARRIER_BITS);
2883 GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier");
2885 Texture::Bind(gl, verifyTexture, verifyTarget);
2886 Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data);
2887 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
2889 //Verify only committed region
2890 for (GLint z = 0; z < depth; ++z)
2891 for (GLint y = 0; y < height; ++y)
2892 for (GLint x = 0; x < width; ++x)
2894 GLubyte* dataRegion = exp_data + x + y * width + z * width * height;
2895 GLubyte* outDataRegion = out_data + x + y * width + z * width * height;
2896 if (dataRegion[0] != outDataRegion[0])
2902 mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format
2903 << ", shaderInfoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
2904 << ", programInfoLog: " << program.getProgramInfo().infoLog << ", shaderSource: " << shader.c_str()
2911 Texture::Delete(gl, verifyTexture);
2918 * @param context Rendering context.
2920 SparseTexture2Tests::SparseTexture2Tests(deqp::Context& context)
2921 : TestCaseGroup(context, "sparse_texture2_tests", "Verify conformance of CTS_ARB_sparse_texture2 implementation")
2925 /** Initializes the test group contents. */
2926 void SparseTexture2Tests::init()
2928 addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture2"));
2929 addChild(new StandardPageSizesTestCase(m_context));
2930 addChild(new SparseTexture2AllocationTestCase(m_context));
2931 addChild(new SparseTexture2CommitmentTestCase(m_context));
2932 addChild(new UncommittedRegionsAccessTestCase(m_context));
2933 addChild(new SparseTexture2LookupTestCase(m_context));
2936 } /* gl4cts namespace */