From: Adam Czupryna Date: Fri, 16 Dec 2016 14:58:18 +0000 (+0100) Subject: Extended CTS_ARB_sparse_texture2 MS34 X-Git-Tag: upstream/0.1.0~556 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4cb898aa4c2cc18b67b53802be1defc42daa1f07;p=platform%2Fupstream%2FVK-GL-CTS.git Extended CTS_ARB_sparse_texture2 MS34 * Added ShaderExtensionTestCase, * Added SparseTexture2LookupTestCase Change-Id: I444205daec25d875ac0eea3662ad28482e12695e --- diff --git a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp index 1def620..608fc88 100644 --- a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp +++ b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp @@ -28,6 +28,7 @@ */ /*-------------------------------------------------------------------*/ #include "gl4cSparseTexture2Tests.hpp" +#include "deStringUtil.hpp" #include "gl4cSparseTextureTests.hpp" #include "gluContextInfo.hpp" #include "gluDefs.hpp" @@ -36,6 +37,7 @@ #include "tcuTestLog.hpp" #include +#include #include #include @@ -47,35 +49,39 @@ namespace gl4cts const char* compute_textureFill = "#version 430 core\n" "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" "\n" - "layout (location = 1) writeonly uniform highp uni_image;\n" + "layout (location = 1) writeonly uniform highp uni_image;\n" "\n" "void main()\n" "{\n" " point = ();\n" " memoryBarrier();\n" - " color = ;\n" + " color = ;\n" " imageStore(uni_image, point, color);\n" "}\n"; const char* compute_textureVerify = "#version 430 core\n" "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" "\n" - "layout (location = 1, r8ui) writeonly uniform uni_out_image;\n" - "layout (location = 2, ) readonly uniform uni_in_image;\n" + "layout (location = 1, r8ui) writeonly uniform uni_out_image;\n" + "layout (location = 2, ) readonly uniform uni_in_image;\n" "\n" "void main()\n" "{\n" " point = ();\n" " memoryBarrier();\n" - " highp color,\n" - " expected,\n" - " epsilon;\n" + " highp color,\n" + " expected,\n" + " epsilon;\n" " color = imageLoad(uni_in_image, point);\n" - " expected = ;\n" - " epsilon = ();\n" + " expected = ;\n" + " epsilon = ();\n" "\n" " if (all(lessThanEqual(color, expected + epsilon)) &&\n" " all(greaterThanEqual(color, expected - epsilon)))\n" @@ -87,60 +93,71 @@ const char* compute_textureVerify = "#version 430 core\n" " }\n" "}\n"; -const char* compute_atomicVerify = - "#version 430 core\n" - "\n" - "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" - "\n" - "layout (location = 1, r8ui) writeonly uniform uni_out_image;\n" - "layout (location = 2, ) uniform uni_in_image;\n" - "\n" - "layout (location = 3) uniform int widthCommitted;\n" - "\n" - "void main()\n" - "{\n" - " point,\n" - " offset;\n" - " point = ();\n" - " offset = (0);\n" - " offset.x = widthCommitted;\n" - " memoryBarrier();\n" - " if (point.x >= widthCommitted) {\n" - " uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n" - " value = 127;\n" - " if (index == 0)\n" - " value = imageAtomicExchange(uni_in_image, point, (0x0F));\n" - " else if (index == 1)\n" - " value = imageAtomicCompSwap(uni_in_image, point, (0), (0x0F));\n" - " else if (index == 2)\n" - " value = imageAtomicAdd(uni_in_image, point, (0x0F));\n" - " else if (index == 3)\n" - " value = imageAtomicAnd(uni_in_image, point, (0x0F));\n" - " else if (index == 4)\n" - " value = imageAtomicOr(uni_in_image, point, (0x0F));\n" - " else if (index == 5)\n" - " value = imageAtomicXor(uni_in_image, point, (0x0F));\n" - " else if (index == 6)\n" - " value = imageAtomicMin(uni_in_image, point, (0x0F));\n" - " else if (index == 7)\n" - " value = imageAtomicMax(uni_in_image, point, (0x0F));\n" - "\n" - " color = imageLoad(uni_in_image, point);\n" - "\n" - " if (value == 0)\n" - " imageStore(uni_out_image, point - offset, uvec4(0));\n" - " else\n" - " imageStore(uni_out_image, point - offset, uvec4(value));\n" - "\n" - " if (color.r == 0)\n" - " imageStore(uni_out_image, point, uvec4(0));\n" - " else\n" - " imageStore(uni_out_image, point, uvec4(1));\n" - " }\n" - "}\n"; +const char* compute_atomicVerify = "#version 430 core\n" + "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" + "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + "\n" + "layout (location = 1, r8ui) writeonly uniform uni_out_image;\n" + "layout (location = 2, ) uniform uni_in_image;\n" + "\n" + "layout (location = 3) uniform int widthCommitted;\n" + "\n" + "void main()\n" + "{\n" + " point,\n" + " offset;\n" + " point = ();\n" + " offset = (0);\n" + " offset.x = widthCommitted;\n" + " memoryBarrier();\n" + " if (point.x >= widthCommitted) {\n" + " uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n" + " value = 127;\n" + " if (index == 0)\n" + " value = imageAtomicExchange(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 1)\n" + " value = imageAtomicCompSwap(uni_in_image, point,\n" + " (0), (0x0F));\n" + " else if (index == 2)\n" + " value = imageAtomicAdd(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 3)\n" + " value = imageAtomicAnd(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 4)\n" + " value = imageAtomicOr(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 5)\n" + " value = imageAtomicXor(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 6)\n" + " value = imageAtomicMin(uni_in_image, point,\n" + " (0x0F));\n" + " else if (index == 7)\n" + " value = imageAtomicMax(uni_in_image, point,\n" + " (0x0F));\n" + "\n" + " color = imageLoad(uni_in_image, point);\n" + "\n" + " if (value == 0)\n" + " imageStore(uni_out_image, point - offset, uvec4(0));\n" + " else\n" + " imageStore(uni_out_image, point - offset, uvec4(value));\n" + "\n" + " if (color.r == 0)\n" + " imageStore(uni_out_image, point, uvec4(0));\n" + " else\n" + " imageStore(uni_out_image, point, uvec4(1));\n" + " }\n" + "}\n"; const char* vertex_drawBuffer = "#version 430 core\n" "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" "in vec3 vertex;\n" "in vec2 inTexCoord;\n" "out vec2 texCoord;\n" @@ -153,6 +170,8 @@ const char* vertex_drawBuffer = "#version 430 core\n" const char* fragment_drawBuffer = "#version 430 core\n" "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" "layout (location = 1) uniform sampler2D uni_sampler;\n" "\n" "in vec2 texCoord;\n" @@ -163,22 +182,141 @@ const char* fragment_drawBuffer = "#version 430 core\n" " fragColor = texture(uni_sampler, texCoord);\n" "}\n"; -/** Replace first occurance of with in starting at +const char* compute_extensionCheck = "#version 450 core\n" + "\n" + "#extension GL_ARB_sparse_texture2 : require\n" + "\n" + "#ifndef GL_ARB_sparse_texture2\n" + " #error GL_ARB_sparse_texture2 not defined\n" + "#else\n" + " #if (GL_ARB_sparse_texture2 != 1)\n" + " #error GL_ARB_sparse_texture2 wrong value\n" + " #endif\n" + "#endif // GL_ARB_sparse_texture2\n" + "\n" + "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + "\n" + "void main()\n" + "{\n" + "}\n"; + +const char* compute_lookupVerify = "#version 450 core\n" + "\n" + "#extension GL_ARB_sparse_texture2 : enable\n" + "\n" + "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" + "\n" + "layout (location = 1, r8ui) writeonly uniform uni_out;\n" + "layout (location = 2) uniform uni_in;\n" + "layout (location = 3) uniform int widthCommitted;\n" + "\n" + "void main()\n" + "{\n" + " point = ();\n" + " i texSize = i();\n" + " i icoord = i();\n" + " coord = () / (texSize);\n" + " retValue,\n" + " expValue,\n" + " epsilon;\n" + " retValue = (0);\n" + " expValue = ;\n" + " epsilon = ();\n" + "\n" + "\n" + "\n" + "\n" + " ivec2 corner1 = ivec2(1, 1);\n" + " ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n" + "\n" + " int code = (uni_in,\n" + " ,\n" + " retValue);\n" + " memoryBarrier();\n" + "\n" + " imageStore(uni_out, point, uvec4(255));\n" + "\n" + " if (point.x > corner1.x && point.y > corner1.y &&\n" + " point.x < corner2.x && point.y < corner2.y &&\n" + " point.x < widthCommitted - 1)\n" + " {\n" + " if (!sparseTexelsResidentARB(code) ||\n" + " any(greaterThan(retValue, expValue + epsilon)) ||\n" + " any(lessThan(retValue, expValue - epsilon)))\n" + " {\n" + " imageStore(uni_out, point, uvec4(0));\n" + " }\n" + " }\n" + "\n" + " if (point.x > corner1.x && point.y > corner1.y &&\n" + " point.x < corner2.x && point.y < corner2.y &&\n" + " point.x >= widthCommitted + 1)\n" + " {\n" + " if (sparseTexelsResidentARB(code))\n" + " {\n" + " imageStore(uni_out, point, uvec4(0));\n" + " }\n" + " }\n" + "}\n"; + +/** Replace all occurance of with in * * @param token Token string - * @param search_position Position at which find will start, it is updated to position at which replaced text ends * @param text String that will be used as replacement for * @param string String to work on **/ -void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string) +void replaceToken(const GLchar* token, const GLchar* text, std::string& string) { - const size_t text_length = strlen(text); - const size_t token_length = strlen(token); - const size_t token_position = string.find(token, search_position); + const size_t text_length = strlen(text); + const size_t token_length = strlen(token); - string.replace(token_position, token_length, text, text_length); + size_t token_position; + while ((token_position = string.find(token, 0)) != std::string::npos) + { + string.replace(token_position, token_length, text, text_length); + } +} - search_position = token_position + text_length; +/** Constructor. + * + * @param context Rendering context + */ +ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context) + : TestCase(context, "ShaderExtension", "Verifies if GL_ARB_sparse_texture2 extension is available for GLSL") +{ + /* Left blank intentionally */ +} + +/** Executes test iteration. + * + * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. + */ +tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate() +{ + if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) + { + m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); + return STOP; + } + + const Functions& gl = m_context.getRenderContext().getFunctions(); + + ProgramSources sources; + sources << ComputeSource(compute_extensionCheck); + ShaderProgram program(gl, sources); + + if (!program.isOk()) + { + m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); + m_testCtx.getLog() << tcu::TestLog::Message << "Checking shader preprocessor directives failed. Source:\n" + << compute_extensionCheck << "InfoLog:\n" + << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n" + << tcu::TestLog::EndMessage; + return STOP; + } + + m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); + return STOP; } /** Constructor. @@ -309,19 +447,6 @@ SparseTexture2AllocationTestCase::SparseTexture2AllocationTestCase(deqp::Context /* Left blank intentionally */ } -/** Constructor. - * - * @param context Rendering context - * @param name Test name - * @param description Test description - */ -SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context, const char* name, - const char* description) - : SparseTextureCommitmentTestCase(context, name, description) -{ - /* Left blank intentionally */ -} - /** Initializes the test group contents. */ void SparseTexture2AllocationTestCase::init() { @@ -353,6 +478,19 @@ tcu::TestNode::IterateResult SparseTexture2AllocationTestCase::iterate() /** Constructor. * * @param context Rendering context + * @param name Test name + * @param description Test description + */ +SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context, const char* name, + const char* description) + : SparseTextureCommitmentTestCase(context, name, description) +{ + /* Left blank intentionally */ +} + +/** Constructor. + * + * @param context Rendering context */ SparseTexture2CommitmentTestCase::SparseTexture2CommitmentTestCase(deqp::Context& context) : SparseTextureCommitmentTestCase( @@ -388,327 +526,328 @@ tcu::TestNode::IterateResult SparseTexture2CommitmentTestCase::iterate() return SparseTextureCommitmentTestCase::iterate(); } -/** Sets proper strings that will be used to tekenize shaders depending on target and format. +/** Create set of token strings fit to texture verifying shader * * @param target Target for which texture is binded * @param format Texture internal format - * @param sample Multisample texture sample number + * @param sample Texture sample number * @return target Structure of token strings */ -TokenStrings SparseTexture2CommitmentTestCase::setupShaderTokens(GLint target, GLint format, GLint sample) +SparseTexture2CommitmentTestCase::TokenStrings SparseTexture2CommitmentTestCase::createShaderTokens( + GLint target, GLint format, GLint sample, const std::string outputBase, const std::string inputBase) { - std::stringstream stemp; - TokenStrings s; std::string prefix; if (format == GL_R8) { - s.format = "r8"; - s.inColorExpected = "(0.1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r8"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_R8_SNORM) { - s.format = "r8_snorm"; - s.inColorExpected = "(0.1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r8_snorm"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_R16) { - s.format = "r16"; - s.inColorExpected = "(0.1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r16"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_R16_SNORM) { - s.format = "r16_snorm"; - s.inColorExpected = "(0.1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r16_snorm"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG8) { - s.format = "rg8"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg8"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG8_SNORM) { - s.format = "rg8_snorm"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg8_snorm"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG16) { - s.format = "rg16"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg16"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG16_SNORM) { - s.format = "rg16_snorm"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg16_snorm"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RGBA8) { - s.format = "rgba8"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba8"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_RGBA8_SNORM) { - s.format = "rgba8_snorm"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba8_snorm"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_RGB10_A2) { - s.format = "rgb10_a2"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgb10_a2"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_RGB10_A2UI) { - s.format = "rgb10_a2ui"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "u"; + s.format = "rgb10_a2ui"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "u"; } else if (format == GL_RGBA16) { - s.format = "rgba16"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba16"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_RGBA16_SNORM) { - s.format = "rgba16_snorm"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba16_snorm"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_R16F) { - s.format = "r16f"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r16f"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG16F) { - s.format = "rg16f"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg16f"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RGBA16F) { - s.format = "rgba16f"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba16f"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_R32F) { - s.format = "r32f"; - s.inColorExpected = "(0.1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r32f"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RG32F) { - s.format = "rg32f"; - s.inColorExpected = "(0.1, 0.1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "rg32f"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_RGBA32F) { - s.format = "rgba32f"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; + s.format = "rgba32f"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; } else if (format == GL_R11F_G11F_B10F) { - s.format = "r11f_g11f_b10f"; - s.inColorExpected = "(0.1, 0.1, 0.1, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; + s.format = "r11f_g11f_b10f"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; } else if (format == GL_R8I) { - s.format = "r8i"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "r8i"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_R8UI) { - s.format = "r8ui"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "r8ui"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_R16I) { - s.format = "r16i"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "r16i"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_R16UI) { - s.format = "r16ui"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "r16ui"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_R32I) { - s.format = "r32i"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "r32i"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_R32UI) { - s.format = "r32ui"; - s.inColorExpected = "(1, 0, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "r32ui"; + s.resultExpected = "(1, 0, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_RG8I) { - s.format = "rg8i"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "rg8i"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_RG8UI) { - s.format = "rg8ui"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "rg8ui"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_RG16I) { - s.format = "rg16i"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "rg16i"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_RG16UI) { - s.format = "rg16ui"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "rg16ui"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_RG32I) { - s.format = "rg32i"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "i"; + s.format = "rg32i"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "i"; } else if (format == GL_RG32UI) { - s.format = "rg32ui"; - s.inColorExpected = "(1, 1, 0, 1)"; - s.inEmptyColor = "(0, 0, 0, 1)"; - prefix = "u"; + s.format = "rg32ui"; + s.resultExpected = "(1, 1, 0, 1)"; + s.resultDefault = "(0, 0, 0, 1)"; + prefix = "u"; } else if (format == GL_RGBA8I) { - s.format = "rgba8i"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "i"; + s.format = "rgba8i"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "i"; } else if (format == GL_RGBA8UI) { - s.format = "rgba8ui"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "u"; + s.format = "rgba8ui"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "u"; } else if (format == GL_RGBA16I) { - s.format = "rgba16i"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "i"; + s.format = "rgba16i"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "i"; } else if (format == GL_RGBA16UI) { - s.format = "rgba16ui"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "u"; + s.format = "rgba16ui"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "u"; } else if (format == GL_RGBA32I) { - s.format = "rgba32i"; - s.inColorExpected = "(1, 1, 1, 1)"; - s.inEmptyColor = "(0, 0, 0, 0)"; - prefix = "i"; + s.format = "rgba32i"; + s.resultExpected = "(1, 1, 1, 1)"; + s.resultDefault = "(0, 0, 0, 0)"; + prefix = "i"; + } + else if (format == GL_DEPTH_COMPONENT16) + { + s.format = "r16"; + s.resultExpected = "(1, 0, 0, 0)"; + s.resultDefault = "(0, 0, 0, 0)"; } - s.inColorType = prefix + "vec4"; - s.outImageType = "uimage2D"; - s.inImageType = prefix + "image2D"; - s.pointType = "ivec2"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y"; + s.returnType = prefix + "vec4"; + s.outputType = "u" + outputBase + "2D"; + s.inputType = prefix + inputBase + "2D"; + s.pointType = "ivec2"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y"; - if (s.inColorType == "vec4") + if (s.returnType == "vec4") s.epsilon = "0.008"; else s.epsilon = "0"; if (target == GL_TEXTURE_2D_ARRAY) { - s.outImageType = "uimage2DArray"; - s.inImageType = prefix + "image2DArray"; - s.pointType = "ivec3"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; + s.outputType = "u" + outputBase + "2DArray"; + s.inputType = prefix + inputBase + "2DArray"; + s.pointType = "ivec3"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; } else if (target == GL_TEXTURE_3D) { - s.outImageType = "uimage2DArray"; - s.inImageType = prefix + "image3D"; - s.pointType = "ivec3"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; + s.outputType = "u" + outputBase + "2DArray"; + s.inputType = prefix + inputBase + "3D"; + s.pointType = "ivec3"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; } else if (target == GL_TEXTURE_CUBE_MAP) { - s.outImageType = "uimage2DArray"; - s.inImageType = prefix + "imageCube"; - s.pointType = "ivec3"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; + s.outputType = "u" + outputBase + "2DArray"; + s.inputType = prefix + inputBase + "Cube"; + s.pointType = "ivec3"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6"; } else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) { - s.outImageType = "uimage2DArray"; - s.inImageType = prefix + "imageCubeArray"; - s.pointType = "ivec3"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; + s.outputType = "u" + outputBase + "2DArray"; + s.inputType = prefix + inputBase + "CubeArray"; + s.pointType = "ivec3"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; } else if (target == GL_TEXTURE_RECTANGLE) { - s.inImageType = prefix + "image2DRect"; + s.inputType = prefix + inputBase + "2DRect"; } else if (target == GL_TEXTURE_2D_MULTISAMPLE) { - s.inImageType = prefix + "image2DMS"; - stemp.str(""); - stemp << ", " << sample; - s.sampleDef = stemp.str(); + s.inputType = prefix + inputBase + "2DMS"; + s.sampleDef = ", " + de::toString(sample); } else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { - s.outImageType = "uimage2DArray"; - s.inImageType = prefix + "image2DMSArray"; - s.pointType = "ivec3"; - s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; - stemp.str(""); - stemp << ", " << sample; - s.sampleDef = stemp.str(); + s.outputType = "u" + outputBase + "2DArray"; + s.inputType = prefix + inputBase + "2DMSArray"; + s.pointType = "ivec3"; + s.pointDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z"; + s.sampleDef = ", " + de::toString(sample); } return s; @@ -751,17 +890,19 @@ bool SparseTexture2CommitmentTestCase::sparseAllocateTexture(const Functions& gl prepareTexture(gl, target, format, texture); + GLint maxLevels; gl.texParameteri(target, GL_TEXTURE_SPARSE_ARB, GL_TRUE); GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri error occurred for GL_TEXTURE_SPARSE_ARB"); + gl.getTexParameteriv(target, GL_NUM_SPARSE_LEVELS_ARB, &maxLevels); + GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv"); + if (levels > maxLevels) + levels = maxLevels; //GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY can have only one level if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { - gl.getTexParameteriv(target, GL_NUM_SPARSE_LEVELS_ARB, &mState.levels); - GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexParameteriv"); - - mState.levels = deMin32(mState.levels, levels); + mState.levels = levels; } else mState.levels = 1; @@ -847,6 +988,9 @@ bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions& gl, G if (width > 0 && height > 0 && depth >= mState.minDepth) { + if (target == GL_TEXTURE_CUBE_MAP) + depth = depth * 6; + GLint texSize = width * height * depth * mState.format.getPixelSize(); std::vector vecData; @@ -869,17 +1013,14 @@ bool SparseTexture2CommitmentTestCase::writeDataToTexture(const Functions& gl, G std::string shader = compute_textureFill; // Adjust shader source to texture format - TokenStrings s = setupShaderTokens(target, format, sample); - - size_t pos = 0; - replaceToken("", pos, s.inImageType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointDef.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.inColorExpected.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); + TokenStrings s = createShaderTokens(target, format, sample); + + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); + replaceToken("", s.resultExpected.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); ProgramSources sources; sources << ComputeSource(shader); @@ -1065,23 +1206,17 @@ bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions& gl, GL std::string shader = compute_textureVerify; // Adjust shader source to texture format - TokenStrings s = setupShaderTokens(target, format, sample); - - size_t pos = 0; - std::string imageType; - - replaceToken("", pos, s.outImageType.c_str(), shader); - replaceToken("", pos, s.format.c_str(), shader); - replaceToken("", pos, s.inImageType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointDef.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.inColorExpected.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.epsilon.c_str(), shader); + TokenStrings s = createShaderTokens(target, format, sample); + + replaceToken("", s.outputType.c_str(), shader); + replaceToken("", s.format.c_str(), shader); + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); + replaceToken("", s.resultExpected.c_str(), shader); + replaceToken("", s.epsilon.c_str(), shader); ProgramSources sources; sources << ComputeSource(shader); @@ -1094,7 +1229,7 @@ bool SparseTexture2CommitmentTestCase::verifyTextureData(const Functions& gl, GL GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); gl.bindImageTexture(0, //unit verifyTexture, - level, //level + 0, //level GL_FALSE, //layered 0, //layer GL_WRITE_ONLY, GL_R8UI); @@ -1160,7 +1295,7 @@ const GLuint indices[] = { 0, 1, 2, 1, 2, 3 }; * @param context Rendering context */ UncommittedRegionsAccessTestCase::UncommittedRegionsAccessTestCase(deqp::Context& context) - : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccessTest", + : SparseTexture2CommitmentTestCase(context, "UncommittedRegionsAccess", "Verifies if access to uncommitted regions of sparse texture works as expected") { /* Left blank intentionally */ @@ -1530,8 +1665,9 @@ bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions GLubyte* exp_data = vecExpData.data(); GLubyte* out_data = vecOutData.data(); + // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros deMemset(exp_data, 0, texSize); - deMemset(out_data, 127, texSize); + deMemset(out_data, 255, texSize); Texture::GetData(gl, level, target, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); @@ -1569,7 +1705,7 @@ bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions GLubyte* exp_data = vecExpData.data(); GLubyte* out_data = vecOutData.data(); - deMemset(exp_data, 0, texSize); + deMemset(exp_data, 255, texSize); for (size_t i = 0; i < subTargets.size(); ++i) { @@ -1577,7 +1713,7 @@ bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions mLog << "Verify Subtarget [subtarget: " << subTarget << "] - "; - deMemset(out_data, 127, texSize); + deMemset(out_data, 255, texSize); Texture::GetData(gl, level, subTarget, transferFormat.format, transferFormat.dataType, (GLvoid*)out_data); GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); @@ -1641,21 +1777,17 @@ bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions std::string shader = compute_textureVerify; // Adjust shader source to texture format - TokenStrings s = setupShaderTokens(target, format, sample); - - size_t pos = 0; - replaceToken("", pos, s.outImageType.c_str(), shader); - replaceToken("", pos, s.format.c_str(), shader); - replaceToken("", pos, s.inImageType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointDef.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.inEmptyColor.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.epsilon.c_str(), shader); + TokenStrings s = createShaderTokens(target, format, sample); + + replaceToken("", s.outputType.c_str(), shader); + replaceToken("", s.format.c_str(), shader); + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); + replaceToken("", s.resultDefault.c_str(), shader); + replaceToken("", s.epsilon.c_str(), shader); ProgramSources sources; sources << ComputeSource(shader); @@ -1668,7 +1800,7 @@ bool UncommittedRegionsAccessTestCase::verifyTextureDataExtended(const Functions GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); gl.bindImageTexture(0, //unit verifyTexture, - level, //level + 0, //level GL_FALSE, //layered 0, //layer GL_WRITE_ONLY, GL_R8UI); @@ -1766,7 +1898,7 @@ bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& g GLubyte* exp_data = vecExpData.data(); GLubyte* out_data = vecOutData.data(); - // Expected value in this case is 255 because shader fills output texture with 255 if in texture is filled with zeros + // Expected value in this case is 0 because atomic operations result on uncommitted regions are zeros deMemset(exp_data, 0, texSize); GLuint verifyTexture; @@ -1787,37 +1919,17 @@ bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& g std::string shader = compute_atomicVerify; // Adjust shader source to texture format - TokenStrings s = setupShaderTokens(target, format, sample); - std::string dataType = (s.inColorType == "ivec4" ? "int" : "uint"); - - size_t pos = 0; - replaceToken("", pos, s.outImageType.c_str(), shader); - replaceToken("", pos, s.format.c_str(), shader); - replaceToken("", pos, s.inImageType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, s.pointDef.c_str(), shader); - replaceToken("", pos, s.pointType.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); - replaceToken("", pos, dataType.c_str(), shader); - replaceToken("", pos, s.inColorType.c_str(), shader); - replaceToken("", pos, s.sampleDef.c_str(), shader); + TokenStrings s = createShaderTokens(target, format, sample); + std::string dataType = (s.returnType == "ivec4" ? "int" : "uint"); + + replaceToken("", s.outputType.c_str(), shader); + replaceToken("", s.format.c_str(), shader); + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", dataType.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); ProgramSources sources; sources << ComputeSource(shader); @@ -1830,7 +1942,7 @@ bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& g GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); gl.bindImageTexture(0, //unit verifyTexture, - level, //level + 0, //level GL_FALSE, //layered 0, //layer GL_WRITE_ONLY, GL_R8UI); @@ -1865,6 +1977,7 @@ bool UncommittedRegionsAccessTestCase::verifyAtomicOperations(const Functions& g GLubyte* outDataRegion = out_data + ((x + y * width) + z * width * height); if (dataRegion[0] != outDataRegion[0]) { + printf("%d:%d ", dataRegion[0], outDataRegion[0]); result = false; } } @@ -2019,6 +2132,722 @@ bool UncommittedRegionsAccessTestCase::verifyDepthBoundsTest(const Functions& gl /** Constructor. * + * @param context Rendering context + */ +SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context) + : SparseTexture2CommitmentTestCase(context, "SparseTexture2Lookup", + "Verifies if sparse texture lookup functions for GLSL works as expected") +{ + /* Left blank intentionally */ +} + +/** Initializes the test group contents. */ +void SparseTexture2LookupTestCase::init() +{ + SparseTextureCommitmentTestCase::init(); + mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE); + mSupportedTargets.push_back(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + + mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16); + + FunctionToken f; + f = FunctionToken("sparseTextureARB", ""); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureLodARB", ""); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureOffsetARB", ", ivec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTexelFetchARB", ""); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE); + f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + mFunctions.push_back(f); + + f = FunctionToken("sparseTexelFetchOffsetARB", ", ivec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureLodOffsetARB", ", ivec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureGradARB", ", vec(0), vec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureGradOffsetARB", ", vec(0), vec(0), ivec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureGatherARB", ""); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureGatherOffsetARB", ", ivec(0)"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseTextureGatherOffsetsARB", ", offsetsArray"); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + mFunctions.push_back(f); + + f = FunctionToken("sparseImageLoadARB", ""); + f.allowedTargets.insert(GL_TEXTURE_2D); + f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP); + f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP_ARRAY); + f.allowedTargets.insert(GL_TEXTURE_3D); + f.allowedTargets.insert(GL_TEXTURE_RECTANGLE); + f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE); + f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + mFunctions.push_back(f); +} + +/** Executes test iteration. + * + * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed. + */ +tcu::TestNode::IterateResult SparseTexture2LookupTestCase::iterate() +{ + if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2")) + { + m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); + return STOP; + } + + const Functions& gl = m_context.getRenderContext().getFunctions(); + + bool result = true; + + GLuint texture; + + for (std::vector::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end(); + ++iter) + { + const GLint& target = *iter; + + for (std::vector::const_iterator formIter = mSupportedInternalFormats.begin(); + formIter != mSupportedInternalFormats.end(); ++formIter) + { + const GLint& format = *formIter; + + if (!caseAllowed(target, format)) + continue; + + for (std::vector::const_iterator tokIter = mFunctions.begin(); tokIter != mFunctions.end(); + ++tokIter) + { + // Check if target is allowed for current lookup function + FunctionToken funcToken = *tokIter; + if (!funcAllowed(target, format, funcToken)) + continue; + + mLog.str(""); + mLog << "Testing sparse texture lookup functions for target: " << target << ", format: " << format + << " - "; + + sparseAllocateTexture(gl, target, format, texture, 3); + if (format == GL_DEPTH_COMPONENT16) + setupDepthMode(gl, target, texture); + + for (int l = 0; l < mState.levels; ++l) + { + if (commitTexturePage(gl, target, format, texture, l)) + { + writeDataToTexture(gl, target, format, texture, l); + result = result && verifyLookupTextureData(gl, target, format, texture, l, funcToken); + } + + if (!result) + break; + } + + Texture::Delete(gl, texture); + + if (!result) + { + m_testCtx.getLog() << tcu::TestLog::Message << mLog.str() << "Fail" << tcu::TestLog::EndMessage; + m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); + return STOP; + } + } + } + } + + m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); + return STOP; +} + +/** Create set of token strings fit to lookup functions verifying shader + * + * @param target Target for which texture is binded + * @param format Texture internal format + * @param level Texture mipmap level + * @param sample Texture sample number + * @param funcToken Texture lookup function structure + * + * @return Returns extended token strings structure. + */ +SparseTexture2LookupTestCase::TokenStringsExt SparseTexture2LookupTestCase::createLookupShaderTokens( + GLint target, GLint format, GLint level, GLint sample, FunctionToken& funcToken) +{ + std::string funcName = funcToken.name; + + TokenStringsExt s; + + std::string inputType; + std::string samplerSufix; + + if (funcName == "sparseImageLoadARB") + inputType = "image"; + else + inputType = "sampler"; + + // Copy data from TokenStrings to TokenStringsExt + TokenStrings ss = createShaderTokens(target, format, sample, "image", inputType); + s.epsilon = ss.epsilon; + s.format = ss.format; + s.inputType = ss.inputType; + s.outputType = ss.outputType; + s.pointDef = ss.pointDef; + s.pointType = ss.pointType; + s.resultDefault = ss.resultDefault; + s.resultExpected = ss.resultExpected; + s.returnType = ss.returnType; + s.sampleDef = ss.sampleDef; + + // Set format definition for image input types + if (inputType == "image") + s.formatDef = ", " + s.format; + + // Set tokens for depth texture format + if (format == GL_DEPTH_COMPONENT16) + { + s.refZDef = ", 0.5"; + + if (inputType == "sampler" && target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_MULTISAMPLE && + target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + s.inputType = s.inputType + "Shadow"; + } + } + + // Set coord type, coord definition and offset vector dimensions + s.coordType = "vec2"; + s.offsetDim = "2"; + if (target == GL_TEXTURE_2D_ARRAY) + { + s.coordType = "vec3"; + } + else if (target == GL_TEXTURE_3D) + { + s.coordType = "vec3"; + s.offsetDim = "3"; + } + else if (target == GL_TEXTURE_CUBE_MAP) + { + s.coordType = "vec3"; + s.offsetDim = "3"; + } + else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) + { + s.coordType = "vec4"; + s.coordDef = "gl_WorkGroupID.x, gl_WorkGroupID.y, gl_WorkGroupID.z % 6, floor(gl_WorkGroupID.z / 6)"; + s.offsetDim = "3"; + } + else if (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + s.coordType = "vec3"; + } + + if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) && + funcName.find("Fetch", 0) == std::string::npos) + { + s.cubeMapCoordDef = " if (point.z == 0) coord.xyz = vec3(1, coord.y * 2 - 1, -coord.x * 2 + 1);\n" + " if (point.z == 1) coord.xyz = vec3(-1, coord.y * 2 - 1, coord.x * 2 - 1);\n" + " if (point.z == 2) coord.xyz = vec3(coord.x * 2 - 1, 1, coord.y * 2 - 1);\n" + " if (point.z == 3) coord.xyz = vec3(coord.x * 2 - 1, -1, -coord.y * 2 + 1);\n" + " if (point.z == 4) coord.xyz = vec3(coord.x * 2 - 1, coord.y * 2 - 1, 1);\n" + " if (point.z == 5) coord.xyz = vec3(-coord.x * 2 + 1, coord.y * 2 - 1, -1);\n"; + } + + if (s.coordDef.empty()) + s.coordDef = s.pointDef; + + // Set expected result vector, component definition and offset array definition for gather functions + if (funcName.find("Gather", 0) != std::string::npos) + { + if (funcName.find("GatherOffsets", 0) != std::string::npos) + { + s.offsetArrayDef = " ivec offsetsArray[4];\n" + " offsetsArray[0] = ivec(0);\n" + " offsetsArray[1] = ivec(0);\n" + " offsetsArray[2] = ivec(0);\n" + " offsetsArray[3] = ivec(0);\n"; + } + + if (format != GL_DEPTH_COMPONENT16) + s.componentDef = ", 0"; + s.resultExpected = "(1, 1, 1, 1)"; + } + // Extend coord type dimension and coord vector definition if shadow sampler and non-cube map array target selected + // Set component definition to red component + else if (format == GL_DEPTH_COMPONENT16) + { + if (target != GL_TEXTURE_CUBE_MAP_ARRAY) + { + if (s.coordType == "vec2") + s.coordType = "vec3"; + else if (s.coordType == "vec3") + s.coordType = "vec4"; + s.coordDef += s.refZDef; + } + else + funcToken.arguments += s.refZDef; + + s.componentDef = ".r"; + } + + // Set level of details definition + if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE && + target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + s.lodDef = ", " + de::toString(level); + } + + // Set proper coord vector + if (target == GL_TEXTURE_RECTANGLE || funcName.find("Fetch") != std::string::npos || + funcName.find("ImageLoad") != std::string::npos) + { + s.pointCoord = "icoord"; + } + else + s.pointCoord = "coord"; + + // Set size vector definition + if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos) + { + if (s.coordType == "vec2") + s.sizeDef = ", "; + else if (s.coordType == "vec3") + s.sizeDef = ", , "; + else if (s.coordType == "vec4") + s.sizeDef = ", , floor( / 6), 6"; + } + // Set size vector for shadow samplers and non-gether functions selected + else + { + if (s.coordType == "vec3") + s.sizeDef = ", , 1"; + else if (s.coordType == "vec4") + s.sizeDef = ", , , 1"; + } + + return s; +} + +/** Check if specific combination of target and format is allowed + * + * @param target Target for which texture is binded + * @param format Texture internal format + * + * @return Returns true if target/format combination is allowed, false otherwise. + */ +bool SparseTexture2LookupTestCase::caseAllowed(GLint target, GLint format) +{ + DE_UNREF(target); + + // As shaders do not support some texture formats it is necessary to exclude them. + if (format == GL_RGB565 || format == GL_RGB10_A2UI || format == GL_RGB9_E5) + { + return false; + } + + if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_3D) && + (format == GL_DEPTH_COMPONENT16)) + { + return false; + } + + return true; +} + +/** Check if specific lookup function is allowed for specific target and format + * + * @param target Target for which texture is binded + * @param format Texture internal format + * @param sample Multisample texture sample number + * @param funcToken Texture lookup function structure + * + * @return Returns true if target/format combination is allowed, false otherwise. + */ +bool SparseTexture2LookupTestCase::funcAllowed(GLint target, GLint format, FunctionToken& funcToken) +{ + if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end()) + return false; + + if (format == GL_DEPTH_COMPONENT16) + { + if (funcToken.name == "sparseTextureLodARB" || funcToken.name == "sparseTextureLodOffsetARB") + { + if (target != GL_TEXTURE_2D) + return false; + } + else if (funcToken.name == "sparseTextureOffsetARB" || funcToken.name == "sparseTextureGradOffsetARB" || + funcToken.name == "sparseTextureGatherOffsetARB" || funcToken.name == "sparseTextureGatherOffsetsARB") + { + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_2D_ARRAY && target != GL_TEXTURE_RECTANGLE) + { + return false; + } + } + else if (funcToken.name == "sparseTexelFetchARB" || funcToken.name == "sparseTexelFetchOffsetARB") + { + return false; + } + else if (funcToken.name == "sparseTextureGradARB") + { + if (target == GL_TEXTURE_CUBE_MAP_ARRAY) + return false; + } + else if (funcToken.name == "sparseImageLoadARB") + { + return false; + } + } + + return true; +} + +/** Writing data to generated texture using compute shader + * + * @param gl GL API functions + * @param target Target for which texture is binded + * @param format Texture internal format + * @param texture Texture object + * + * @return Returns true if no error occurred, otherwise throws an exception. + */ +bool SparseTexture2LookupTestCase::writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture, + GLint level) +{ + mLog << "Fill Texture with shader [level: " << level << "] - "; + + if (level > mState.levels - 1) + TCU_FAIL("Invalid level"); + + GLint width; + GLint height; + GLint depth; + SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); + + if (width > 0 && height > 0 && depth >= mState.minDepth) + { + if (target == GL_TEXTURE_CUBE_MAP) + depth = depth * 6; + + GLint texSize = width * height * depth * mState.format.getPixelSize(); + + std::vector vecData; + vecData.resize(texSize); + GLubyte* data = vecData.data(); + + deMemset(data, 255, texSize); + + for (GLint sample = 0; sample < mState.samples; ++sample) + { + std::string shader = compute_textureFill; + + // Adjust shader source to texture format + TokenStrings s = createShaderTokens(target, format, sample); + + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); + replaceToken("", s.resultExpected.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); + + ProgramSources sources; + sources << ComputeSource(shader); + + GLint convFormat = format; + if (format == GL_DEPTH_COMPONENT16) + convFormat = GL_R16; + + // Build and run shader + ShaderProgram program(m_context.getRenderContext(), sources); + if (program.isOk()) + { + gl.useProgram(program.getProgram()); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); + gl.bindImageTexture(0 /* unit */, texture, level /* level */, GL_FALSE /* layered */, 0 /* layer */, + GL_WRITE_ONLY, convFormat); + GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); + gl.uniform1i(1, 0 /* image_unit */); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); + gl.dispatchCompute(width, height, depth); + GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); + gl.memoryBarrier(GL_ALL_BARRIER_BITS); + GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); + } + else + { + mLog << "Compute shader compilation failed (writing) for target: " << target << ", format: " << format + << ", sample: " << sample << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog + << ", shaderSource: " << shader.c_str() << " - "; + } + } + } + + return true; +} + +/** Setup depth compare mode and compare function for depth texture + * + * @param gl GL API functions + * @param target Target for which texture is binded + * @param texture Texture object + */ +void SparseTexture2LookupTestCase::setupDepthMode(const Functions& gl, GLint target, GLuint& texture) +{ + Texture::Bind(gl, texture, target); + gl.texParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); + gl.texParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_ALWAYS); + GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri"); +} + +/** Verify if data stored in texture is as expected + * + * @param gl GL API functions + * @param target Target for which texture is binded + * @param format Texture internal format + * @param texture Texture object + * @param level Texture mipmap level + * @param funcToken Lookup function tokenize structure + * + * @return Returns true if data is as expected, false if not, throws an exception if error occurred. + */ +bool SparseTexture2LookupTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format, + GLuint& texture, GLint level, FunctionToken& funcToken) +{ + mLog << "Verify Lookup Texture Data [function: " << funcToken.name << ", level: " << level << "] - "; + + if (level > mState.levels - 1) + TCU_FAIL("Invalid level"); + + GLint width; + GLint height; + GLint depth; + SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth); + + //Committed region is limited to 1/2 of width + GLint widthCommitted = width / 2; + + if (widthCommitted == 0 || height == 0 || depth < mState.minDepth) + return true; + + bool result = true; + + if (target == GL_TEXTURE_CUBE_MAP) + depth = depth * 6; + + GLint texSize = width * height * depth; + + std::vector vecExpData; + std::vector vecOutData; + vecExpData.resize(texSize); + vecOutData.resize(texSize); + GLubyte* exp_data = vecExpData.data(); + GLubyte* out_data = vecOutData.data(); + + // Expected data is 255 because + deMemset(exp_data, 255, texSize); + + // Make token copy to work on + FunctionToken f = funcToken; + + // Create verifying texture + GLint verifyTarget; + if (target == GL_TEXTURE_2D_MULTISAMPLE) + verifyTarget = GL_TEXTURE_2D; + else + verifyTarget = GL_TEXTURE_2D_ARRAY; + + GLuint verifyTexture; + Texture::Generate(gl, verifyTexture); + Texture::Bind(gl, verifyTexture, verifyTarget); + Texture::Storage(gl, verifyTarget, 1, GL_R8, width, height, depth); + GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::Storage"); + + for (int sample = 0; sample < mState.samples; ++sample) + { + deMemset(out_data, 0, texSize); + + Texture::Bind(gl, verifyTexture, verifyTarget); + Texture::SubImage(gl, verifyTarget, 0, 0, 0, 0, width, height, depth, GL_RED, GL_UNSIGNED_BYTE, + (GLvoid*)out_data); + GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage"); + + std::string shader = compute_lookupVerify; + + // Adjust shader source to texture format + TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f); + + replaceToken("", f.name.c_str(), shader); + replaceToken("", f.arguments.c_str(), shader); + + replaceToken("", s.outputType.c_str(), shader); + replaceToken("", s.inputType.c_str(), shader); + replaceToken("", s.sizeDef.c_str(), shader); + replaceToken("", s.lodDef.c_str(), shader); + replaceToken("", s.coordType.c_str(), shader); + replaceToken("", s.coordDef.c_str(), shader); + replaceToken("", s.pointType.c_str(), shader); + replaceToken("", s.pointDef.c_str(), shader); + replaceToken("", s.returnType.c_str(), shader); + replaceToken("", s.resultExpected.c_str(), shader); + replaceToken("", s.epsilon.c_str(), shader); + replaceToken("", s.sampleDef.c_str(), shader); + replaceToken("", s.refZDef.c_str(), shader); + replaceToken("", s.pointCoord.c_str(), shader); + replaceToken("", s.componentDef.c_str(), shader); + replaceToken("", s.cubeMapCoordDef.c_str(), shader); + replaceToken("", s.offsetArrayDef.c_str(), shader); + replaceToken("", s.formatDef.c_str(), shader); + replaceToken("", s.offsetDim.c_str(), shader); + + replaceToken("", de::toString(width).c_str(), shader); + replaceToken("", de::toString(height).c_str(), shader); + replaceToken("", de::toString(depth).c_str(), shader); + + ProgramSources sources; + sources << ComputeSource(shader); + + // Build and run shader + ShaderProgram program(m_context.getRenderContext(), sources); + if (program.isOk()) + { + gl.useProgram(program.getProgram()); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram"); + + // Pass output image to shader + gl.bindImageTexture(1, //unit + verifyTexture, + 0, //level + GL_TRUE, //layered + 0, //layer + GL_WRITE_ONLY, GL_R8UI); + GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); + gl.uniform1i(1, 1 /* image_unit */); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); + + // Pass input sampler/image to shader + if (f.name != "sparseImageLoadARB") + { + gl.activeTexture(GL_TEXTURE0); + GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture"); + gl.bindTexture(target, texture); + GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); + gl.uniform1i(2, 0 /* sampler_unit */); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); + } + else + { + gl.bindImageTexture(1, //unit + texture, + level, //level + GL_FALSE, //layered + 0, //layer + GL_READ_ONLY, format); + GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture"); + gl.uniform1i(1, 1 /* image_unit */); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); + } + + // Pass committed region width to shader + gl.uniform1i(3, widthCommitted /* committed region width */); + GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i"); + gl.dispatchCompute(width, height, depth); + GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute"); + gl.memoryBarrier(GL_ALL_BARRIER_BITS); + GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier"); + + Texture::Bind(gl, verifyTexture, verifyTarget); + Texture::GetData(gl, 0, verifyTarget, GL_RED, GL_UNSIGNED_BYTE, (GLvoid*)out_data); + GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData"); + + //Verify only committed region + for (GLint x = 0; x < width; ++x) + for (GLint y = 0; y < height; ++y) + for (GLint z = 0; z < depth; ++z) + { + GLubyte* dataRegion = exp_data + x + y * width + z * width * height; + GLubyte* outDataRegion = out_data + x + y * width + z * width * height; + if (dataRegion[0] != outDataRegion[0]) + result = false; + } + } + else + { + mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format + << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog + << ", shaderSource: " << shader.c_str() << " - "; + + result = false; + } + } + + Texture::Delete(gl, verifyTexture); + + return result; +} + +/** Constructor. + * * @param context Rendering context. */ SparseTexture2Tests::SparseTexture2Tests(deqp::Context& context) @@ -2029,10 +2858,12 @@ SparseTexture2Tests::SparseTexture2Tests(deqp::Context& context) /** Initializes the test group contents. */ void SparseTexture2Tests::init() { + addChild(new ShaderExtensionTestCase(m_context)); addChild(new StandardPageSizesTestCase(m_context)); addChild(new SparseTexture2AllocationTestCase(m_context)); addChild(new SparseTexture2CommitmentTestCase(m_context)); addChild(new UncommittedRegionsAccessTestCase(m_context)); + addChild(new SparseTexture2LookupTestCase(m_context)); } } /* gl4cts namespace */ diff --git a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp index e15d07a..d80313c 100644 --- a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp +++ b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp @@ -31,8 +31,10 @@ #include "glcTestCase.hpp" #include "glwDefs.hpp" +#include "glwEnums.hpp" #include "tcuDefs.hpp" #include +#include #include #include "gl4cSparseTextureTests.hpp" @@ -63,18 +65,18 @@ struct PageSizeStruct typedef std::pair PageSizePair; -struct TokenStrings +/** Test verifies if GL_ARB_sparse_texture2 extension is available for GLSL + **/ +class ShaderExtensionTestCase : public deqp::TestCase { - std::string format; - std::string pointType; - std::string pointDef; - std::string outImageType; - std::string inImageType; - std::string inColorType; - std::string inColorExpected; - std::string inEmptyColor; - std::string epsilon; - std::string sampleDef; +public: + /* Public methods */ + ShaderExtensionTestCase(deqp::Context& context); + + tcu::TestNode::IterateResult iterate(); + +private: + /* Private members */ }; /** Test verifies if values returned by GetInternalFormat* query matches Standard Virtual Page Sizes for : @@ -129,9 +131,23 @@ public: protected: /* Protected members */ + struct TokenStrings + { + std::string format; + std::string pointType; + std::string pointDef; + std::string outputType; + std::string inputType; + std::string returnType; + std::string resultExpected; + std::string resultDefault; + std::string epsilon; + std::string sampleDef; + }; /* Protected methods */ - TokenStrings setupShaderTokens(GLint target, GLint format, GLint sample); + TokenStrings createShaderTokens(GLint target, GLint format, GLint sample, const std::string outputBase = "image", + const std::string inputBase = "image"); virtual bool caseAllowed(GLint target, GLint format); @@ -178,6 +194,67 @@ private: GLint widthCommitted); }; +/** Test verifies if sparse texture lookup functions for GLSL works as expected + **/ +class SparseTexture2LookupTestCase : public SparseTexture2CommitmentTestCase +{ +public: + /* Public methods */ + SparseTexture2LookupTestCase(deqp::Context& context); + + void init(); + tcu::TestNode::IterateResult iterate(); + +private: + /* Private types */ + struct FunctionToken + { + std::string name; + std::string arguments; + + std::set allowedTargets; + + FunctionToken() + { + } + + FunctionToken(std::string fname, std::string fargs) : name(fname), arguments(fargs) + { + } + }; + + struct TokenStringsExt : public TokenStrings + { + std::string formatDef; + std::string sizeDef; + std::string lodDef; + std::string coordType; + std::string coordDef; + std::string cubeMapCoordDef; + std::string refZDef; + std::string offsetDim; + std::string componentDef; + std::string offsetArrayDef; + std::string pointCoord; + }; + + /* Private members */ + std::vector mFunctions; + + /* Private methods */ + TokenStringsExt createLookupShaderTokens(GLint target, GLint format, GLint level, GLint sample, + FunctionToken& funcToken); + + virtual bool caseAllowed(GLint target, GLint format); + virtual bool funcAllowed(GLint target, GLint format, FunctionToken& funcToken); + + virtual bool writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level); + + virtual void setupDepthMode(const Functions& gl, GLint target, GLuint& texture); + virtual bool verifyLookupTextureData(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level, + FunctionToken& funcToken); +}; + /** Test group which encapsulates all sparse texture conformance tests */ class SparseTexture2Tests : public deqp::TestCaseGroup {