Add CTS_ARB_sparse_texture_clamp tests

Added CTS_ARB_sparse_texture_clamp cases:
ShaderExtensionTestCase
SparseTextureClampLookupResidencyTestCase
SparseTextureClampLookupColorTestCase

affects:

GL45-CTS.sparse_texture_tests.*
GL45-CTS.sparse_texture2_tests.*

components: OpenGL, Framework

VK-GL-CTS issue: 60

Change-Id: I1d312fe7fd82d5de74926d189f1e6ec6ce910ce2
diff --git a/external/openglcts/modules/gl/CMakeLists.txt b/external/openglcts/modules/gl/CMakeLists.txt
index 54500bd..ca93752 100644
--- a/external/openglcts/modules/gl/CMakeLists.txt
+++ b/external/openglcts/modules/gl/CMakeLists.txt
@@ -106,6 +106,8 @@
 	gl4cSparseTextureTests.hpp
 	gl4cSparseTexture2Tests.cpp
 	gl4cSparseTexture2Tests.hpp
+	gl4cSparseTextureClampTests.cpp
+	gl4cSparseTextureClampTests.hpp
 	gl4cParallelShaderCompileTests.cpp
 	gl4cParallelShaderCompileTests.hpp
 	gl4cPostDepthCoverageTests.cpp
diff --git a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp
index 608fc88..8531bbd 100644
--- a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp
+++ b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.cpp
@@ -47,217 +47,216 @@
 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 <INPUT_TYPE> uni_image;\n"
-								  "\n"
-								  "void main()\n"
-								  "{\n"
-								  "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
-								  "    memoryBarrier();\n"
-								  "    <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
-								  "    imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
-								  "}\n";
+const char* st2_compute_textureFill = "#version 430 core\n"
+									  "\n"
+									  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+									  "\n"
+									  "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n"
+									  "\n"
+									  "void main()\n"
+									  "{\n"
+									  "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
+									  "    memoryBarrier();\n"
+									  "    <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+									  "    imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
+									  "}\n";
 
-const char* compute_textureVerify = "#version 430 core\n"
+const char* st2_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 <OUTPUT_TYPE> uni_out_image;\n"
+										"layout (location = 2, <FORMAT>) readonly uniform <INPUT_TYPE> uni_in_image;\n"
+										"\n"
+										"void main()\n"
+										"{\n"
+										"    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
+										"    memoryBarrier();\n"
+										"    highp <RETURN_TYPE> color,\n"
+										"                        expected,\n"
+										"                        epsilon;\n"
+										"    color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
+										"    expected = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+										"    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
+										"\n"
+										"    if (all(lessThanEqual(color, expected + epsilon)) &&\n"
+										"        all(greaterThanEqual(color, expected - epsilon)))\n"
+										"    {\n"
+										"        imageStore(uni_out_image, point, uvec4(255));\n"
+										"    }\n"
+										"    else {\n"
+										"        imageStore(uni_out_image, point, uvec4(0));\n"
+										"    }\n"
+										"}\n";
+
+const char* st2_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 <OUTPUT_TYPE> uni_out_image;\n"
+									   "layout (location = 2, <FORMAT>) uniform <INPUT_TYPE> uni_in_image;\n"
+									   "\n"
+									   "layout (location = 3) uniform int widthCommitted;\n"
+									   "\n"
+									   "void main()\n"
+									   "{\n"
+									   "    <POINT_TYPE> point,\n"
+									   "                 offset;\n"
+									   "    point = <POINT_TYPE>(<POINT_DEF>);\n"
+									   "    offset = <POINT_TYPE>(0);\n"
+									   "    offset.x = widthCommitted;\n"
+									   "    memoryBarrier();\n"
+									   "    if (point.x >= widthCommitted) {\n"
+									   "        uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n"
+									   "        <DATA_TYPE> value = 127;\n"
+									   "        if (index == 0)\n"
+									   "            value = imageAtomicExchange(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                        <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 1)\n"
+									   "            value = imageAtomicCompSwap(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                        <DATA_TYPE>(0), <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 2)\n"
+									   "            value = imageAtomicAdd(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                   <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 3)\n"
+									   "            value = imageAtomicAnd(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                   <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 4)\n"
+									   "            value = imageAtomicOr(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                  <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 5)\n"
+									   "            value = imageAtomicXor(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                   <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 6)\n"
+									   "            value = imageAtomicMin(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                   <DATA_TYPE>(0x0F));\n"
+									   "        else if (index == 7)\n"
+									   "            value = imageAtomicMax(uni_in_image, point<SAMPLE_DEF>,\n"
+									   "                                   <DATA_TYPE>(0x0F));\n"
+									   "\n"
+									   "        <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\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* st2_vertex_drawBuffer = "#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 <OUTPUT_TYPE> uni_out_image;\n"
-									"layout (location = 2, <FORMAT>) readonly uniform <INPUT_TYPE> uni_in_image;\n"
+									"in vec3 vertex;\n"
+									"in vec2 inTexCoord;\n"
+									"out vec2 texCoord;\n"
 									"\n"
 									"void main()\n"
 									"{\n"
-									"    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
-									"    memoryBarrier();\n"
-									"    highp <RETURN_TYPE> color,\n"
-									"                        expected,\n"
-									"                        epsilon;\n"
-									"    color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\n"
-									"    expected = <RETURN_TYPE><RESULT_EXPECTED>;\n"
-									"    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
-									"\n"
-									"    if (all(lessThanEqual(color, expected + epsilon)) &&\n"
-									"        all(greaterThanEqual(color, expected - epsilon)))\n"
-									"    {\n"
-									"        imageStore(uni_out_image, point, uvec4(255));\n"
-									"    }\n"
-									"    else {\n"
-									"        imageStore(uni_out_image, point, uvec4(0));\n"
-									"    }\n"
+									"    texCoord = inTexCoord;\n"
+									"    gl_Position = vec4(vertex, 1);\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 <OUTPUT_TYPE> uni_out_image;\n"
-								   "layout (location = 2, <FORMAT>) uniform <INPUT_TYPE> uni_in_image;\n"
-								   "\n"
-								   "layout (location = 3) uniform int widthCommitted;\n"
-								   "\n"
-								   "void main()\n"
-								   "{\n"
-								   "    <POINT_TYPE> point,\n"
-								   "                 offset;\n"
-								   "    point = <POINT_TYPE>(<POINT_DEF>);\n"
-								   "    offset = <POINT_TYPE>(0);\n"
-								   "    offset.x = widthCommitted;\n"
-								   "    memoryBarrier();\n"
-								   "    if (point.x >= widthCommitted) {\n"
-								   "        uint index = ((point.x - widthCommitted) + point.y * 8) % 8;\n"
-								   "        <DATA_TYPE> value = 127;\n"
-								   "        if (index == 0)\n"
-								   "            value = imageAtomicExchange(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                        <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 1)\n"
-								   "            value = imageAtomicCompSwap(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                        <DATA_TYPE>(0), <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 2)\n"
-								   "            value = imageAtomicAdd(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                   <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 3)\n"
-								   "            value = imageAtomicAnd(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                   <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 4)\n"
-								   "            value = imageAtomicOr(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                  <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 5)\n"
-								   "            value = imageAtomicXor(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                   <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 6)\n"
-								   "            value = imageAtomicMin(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                   <DATA_TYPE>(0x0F));\n"
-								   "        else if (index == 7)\n"
-								   "            value = imageAtomicMax(uni_in_image, point<SAMPLE_DEF>,\n"
-								   "                                   <DATA_TYPE>(0x0F));\n"
-								   "\n"
-								   "        <RETURN_TYPE> color = imageLoad(uni_in_image, point<SAMPLE_DEF>);\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* st2_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"
+									  "out vec4 fragColor;\n"
+									  "\n"
+									  "void main()\n"
+									  "{\n"
+									  "    fragColor = texture(uni_sampler, texCoord);\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"
-								"\n"
-								"void main()\n"
-								"{\n"
-								"    texCoord = inTexCoord;\n"
-								"    gl_Position = vec4(vertex, 1);\n"
-								"}\n";
+const char* st2_compute_extensionCheck = "#version 450 core\n"
+										 "\n"
+										 "#extension <EXTENSION> : require\n"
+										 "\n"
+										 "#ifndef <EXTENSION>\n"
+										 "  #error <EXTENSION> not defined\n"
+										 "#else\n"
+										 "  #if (<EXTENSION> != 1)\n"
+										 "    #error <EXTENSION> wrong value\n"
+										 "  #endif\n"
+										 "#endif // <EXTENSION>\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* 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"
-								  "out vec4 fragColor;\n"
-								  "\n"
-								  "void main()\n"
-								  "{\n"
-								  "    fragColor = texture(uni_sampler, texCoord);\n"
-								  "}\n";
-
-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 <OUTPUT_TYPE> uni_out;\n"
-								   "layout (location = 2<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
-								   "layout (location = 3) uniform int widthCommitted;\n"
-								   "\n"
-								   "void main()\n"
-								   "{\n"
-								   "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
-								   "    i<COORD_TYPE> texSize = i<COORD_TYPE>(<SIZE_DEF>);\n"
-								   "    i<COORD_TYPE> icoord = i<COORD_TYPE>(<COORD_DEF>);\n"
-								   "    <COORD_TYPE> coord = <COORD_TYPE>(<COORD_DEF>) / <COORD_TYPE>(texSize);\n"
-								   "    <RETURN_TYPE> retValue,\n"
-								   "                  expValue,\n"
-								   "                  epsilon;\n"
-								   "    retValue = <RETURN_TYPE>(0);\n"
-								   "    expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
-								   "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
-								   "\n"
-								   "<CUBE_MAP_COORD_DEF>\n"
-								   "<OFFSET_ARRAY_DEF>\n"
-								   "\n"
-								   "    ivec2 corner1 = ivec2(1, 1);\n"
-								   "    ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
-								   "\n"
-								   "    int code = <FUNCTION>(uni_in,\n"
-								   "                          <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
-								   "                          retValue<COMPONENT_DEF>);\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";
+const char* st2_compute_lookupVerify = "#version 450 core\n"
+									   "\n"
+									   "#extension GL_ARB_sparse_texture2 : enable\n"
+									   "#extension GL_ARB_sparse_texture_clamp : 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 <OUTPUT_TYPE> uni_out;\n"
+									   "layout (location = 2<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
+									   "layout (location = 3) uniform int widthCommitted;\n"
+									   "\n"
+									   "void main()\n"
+									   "{\n"
+									   "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
+									   "    <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n"
+									   "    <ICOORD_TYPE> icoord = <ICOORD_TYPE>(<COORD_DEF>);\n"
+									   "    <COORD_TYPE> coord = <COORD_TYPE>(<COORD_DEF>) / <COORD_TYPE>(texSize);\n"
+									   "    <RETURN_TYPE> retValue,\n"
+									   "                  expValue,\n"
+									   "                  epsilon;\n"
+									   "    retValue = <RETURN_TYPE>(0);\n"
+									   "    expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+									   "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
+									   "\n"
+									   "<CUBE_MAP_COORD_DEF>\n"
+									   "<OFFSET_ARRAY_DEF>\n"
+									   "\n"
+									   "    ivec2 corner1 = ivec2(1, 1);\n"
+									   "    ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
+									   "\n"
+									   "    int code = <FUNCTION>(uni_in,\n"
+									   "                          <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
+									   "                          retValue<COMPONENT_DEF>);\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 <token> with <text> in <string>
  *
@@ -281,8 +280,8 @@
  *
  *  @param context     Rendering context
  */
-ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context)
-	: TestCase(context, "ShaderExtension", "Verifies if GL_ARB_sparse_texture2 extension is available for GLSL")
+ShaderExtensionTestCase::ShaderExtensionTestCase(deqp::Context& context, const std::string extension)
+	: TestCase(context, "ShaderExtension", "Verifies if extension is available for GLSL"), mExtension(extension)
 {
 	/* Left blank intentionally */
 }
@@ -293,7 +292,7 @@
  */
 tcu::TestNode::IterateResult ShaderExtensionTestCase::iterate()
 {
-	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
+	if (!m_context.getContextInfo().isExtensionSupported(mExtension.c_str()))
 	{
 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
 		return STOP;
@@ -301,15 +300,18 @@
 
 	const Functions& gl = m_context.getRenderContext().getFunctions();
 
+	std::string shader = st2_compute_extensionCheck;
+	replaceToken("<EXTENSION>", mExtension.c_str(), shader);
+
 	ProgramSources sources;
-	sources << ComputeSource(compute_extensionCheck);
+	sources << ComputeSource(shader);
 	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"
+						   << shader.c_str() << "InfoLog:\n"
 						   << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
 						   << tcu::TestLog::EndMessage;
 		return STOP;
@@ -804,7 +806,21 @@
 	else
 		s.epsilon = "0";
 
-	if (target == GL_TEXTURE_2D_ARRAY)
+	if (target == GL_TEXTURE_1D)
+	{
+		s.outputType = "u" + outputBase + "2D";
+		s.inputType  = prefix + inputBase + "1D";
+		s.pointType  = "int";
+		s.pointDef   = "gl_WorkGroupID.x";
+	}
+	else if (target == GL_TEXTURE_1D_ARRAY)
+	{
+		s.outputType = "u" + outputBase + "2D_ARRAY";
+		s.inputType  = prefix + inputBase + "1DArray";
+		s.pointType  = "ivec2";
+		s.pointDef   = "gl_WorkGroupID.x, gl_WorkGroupID.z";
+	}
+	else if (target == GL_TEXTURE_2D_ARRAY)
 	{
 		s.outputType = "u" + outputBase + "2DArray";
 		s.inputType  = prefix + inputBase + "2DArray";
@@ -1010,7 +1026,7 @@
 		{
 			for (GLint sample = 0; sample < mState.samples; ++sample)
 			{
-				std::string shader = compute_textureFill;
+				std::string shader = st2_compute_textureFill;
 
 				// Adjust shader source to texture format
 				TokenStrings s = createShaderTokens(target, format, sample);
@@ -1203,7 +1219,7 @@
 							  (GLvoid*)out_data);
 			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
 
-			std::string shader = compute_textureVerify;
+			std::string shader = st2_compute_textureVerify;
 
 			// Adjust shader source to texture format
 			TokenStrings s = createShaderTokens(target, format, sample);
@@ -1530,8 +1546,8 @@
 		return true;
 
 	//Prepare shaders
-	std::string vertexSource   = vertex_drawBuffer;
-	std::string fragmentSource = fragment_drawBuffer;
+	std::string vertexSource   = st2_vertex_drawBuffer;
+	std::string fragmentSource = st2_fragment_drawBuffer;
 
 	ShaderProgram program(gl, glu::makeVtxFragSources(vertexSource, fragmentSource));
 	if (!program.isOk())
@@ -1774,7 +1790,7 @@
 							  (GLvoid*)out_data);
 			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
 
-			std::string shader = compute_textureVerify;
+			std::string shader = st2_compute_textureVerify;
 
 			// Adjust shader source to texture format
 			TokenStrings s = createShaderTokens(target, format, sample);
@@ -1916,7 +1932,7 @@
 						  (GLvoid*)out_data);
 		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
 
-		std::string shader = compute_atomicVerify;
+		std::string shader = st2_compute_atomicVerify;
 
 		// Adjust shader source to texture format
 		TokenStrings s		  = createShaderTokens(target, format, sample);
@@ -2141,6 +2157,17 @@
 	/* Left blank intentionally */
 }
 
+/** Constructor.
+ *
+ *  @param context     Rendering context
+ */
+SparseTexture2LookupTestCase::SparseTexture2LookupTestCase(deqp::Context& context, const char* name,
+														   const char* description)
+	: SparseTexture2CommitmentTestCase(context, name, description)
+{
+	/* Left blank intentionally */
+}
+
 /** Initializes the test group contents. */
 void SparseTexture2LookupTestCase::init()
 {
@@ -2160,7 +2187,7 @@
 	f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
 	mFunctions.push_back(f);
 
-	f = FunctionToken("sparseTextureLodARB", "<LOD_DEF>");
+	f = FunctionToken("sparseTextureLodARB", ", <LOD>");
 	f.allowedTargets.insert(GL_TEXTURE_2D);
 	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
 	f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
@@ -2168,7 +2195,7 @@
 	f.allowedTargets.insert(GL_TEXTURE_3D);
 	mFunctions.push_back(f);
 
-	f = FunctionToken("sparseTextureOffsetARB", ", ivec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTextureOffsetARB", ", <OFFSET_TYPE><OFFSET_DIM>(0)");
 	f.allowedTargets.insert(GL_TEXTURE_2D);
 	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
 	f.allowedTargets.insert(GL_TEXTURE_3D);
@@ -2184,20 +2211,20 @@
 	f.allowedTargets.insert(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
 	mFunctions.push_back(f);
 
-	f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, ivec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTexelFetchOffsetARB", "<LOD_DEF>, <OFFSET_TYPE><OFFSET_DIM>(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", "<LOD_DEF>, ivec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTextureLodOffsetARB", ", <LOD>, <OFFSET_TYPE><OFFSET_DIM>(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<OFFSET_DIM>(0), vec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTextureGradARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0)");
 	f.allowedTargets.insert(GL_TEXTURE_2D);
 	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
 	f.allowedTargets.insert(GL_TEXTURE_CUBE_MAP);
@@ -2206,7 +2233,8 @@
 	f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
 	mFunctions.push_back(f);
 
-	f = FunctionToken("sparseTextureGradOffsetARB", ", vec<OFFSET_DIM>(0), vec<OFFSET_DIM>(0), ivec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTextureGradOffsetARB",
+					  ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0)");
 	f.allowedTargets.insert(GL_TEXTURE_2D);
 	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
 	f.allowedTargets.insert(GL_TEXTURE_3D);
@@ -2221,7 +2249,7 @@
 	f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
 	mFunctions.push_back(f);
 
-	f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, ivec<OFFSET_DIM>(0)");
+	f = FunctionToken("sparseTextureGatherOffsetARB", "<REFZ_DEF>, <OFFSET_TYPE><OFFSET_DIM>(0)");
 	f.allowedTargets.insert(GL_TEXTURE_2D);
 	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
 	f.allowedTargets.insert(GL_TEXTURE_RECTANGLE);
@@ -2242,7 +2270,7 @@
 	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);
+	//mFunctions.push_back(f);
 }
 
 /** Executes test iteration.
@@ -2375,9 +2403,25 @@
 	}
 
 	// Set coord type, coord definition and offset vector dimensions
-	s.coordType = "vec2";
-	s.offsetDim = "2";
-	if (target == GL_TEXTURE_2D_ARRAY)
+	s.coordType   = "vec2";
+	s.offsetType  = "ivec";
+	s.nOffsetType = "vec";
+	s.offsetDim   = "2";
+	if (target == GL_TEXTURE_1D)
+	{
+		s.coordType   = "float";
+		s.offsetType  = "int";
+		s.nOffsetType = "float";
+		s.offsetDim   = "";
+	}
+	else if (target == GL_TEXTURE_1D_ARRAY)
+	{
+		s.coordType   = "vec2";
+		s.offsetType  = "int";
+		s.nOffsetType = "float";
+		s.offsetDim   = "";
+	}
+	else if (target == GL_TEXTURE_2D_ARRAY)
 	{
 		s.coordType = "vec3";
 	}
@@ -2421,11 +2465,11 @@
 	{
 		if (funcName.find("GatherOffsets", 0) != std::string::npos)
 		{
-			s.offsetArrayDef = "    ivec<OFFSET_DIM> offsetsArray[4];\n"
-							   "    offsetsArray[0] = ivec<OFFSET_DIM>(0);\n"
-							   "    offsetsArray[1] = ivec<OFFSET_DIM>(0);\n"
-							   "    offsetsArray[2] = ivec<OFFSET_DIM>(0);\n"
-							   "    offsetsArray[3] = ivec<OFFSET_DIM>(0);\n";
+			s.offsetArrayDef = "    <OFFSET_TYPE><OFFSET_DIM> offsetsArray[4];\n"
+							   "    offsetsArray[0] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
+							   "    offsetsArray[1] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
+							   "    offsetsArray[2] = <OFFSET_TYPE><OFFSET_DIM>(0);\n"
+							   "    offsetsArray[3] = <OFFSET_TYPE><OFFSET_DIM>(0);\n";
 		}
 
 		if (format != GL_DEPTH_COMPONENT16)
@@ -2454,6 +2498,7 @@
 	if (target != GL_TEXTURE_RECTANGLE && target != GL_TEXTURE_2D_MULTISAMPLE &&
 		target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
 	{
+		s.lod	= de::toString(level);
 		s.lodDef = ", " + de::toString(level);
 	}
 
@@ -2469,7 +2514,11 @@
 	// Set size vector definition
 	if (format != GL_DEPTH_COMPONENT16 || funcName.find("Gather", 0) != std::string::npos)
 	{
-		if (s.coordType == "vec2")
+		if (s.coordType == "float")
+			s.sizeDef = "<TEX_WIDTH>";
+		else if (s.coordType == "vec2" && target == GL_TEXTURE_1D_ARRAY)
+			s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>";
+		else if (s.coordType == "vec2")
 			s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>";
 		else if (s.coordType == "vec3")
 			s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>";
@@ -2479,16 +2528,24 @@
 	// Set size vector for shadow samplers and non-gether functions selected
 	else
 	{
-		if (s.coordType == "vec3")
+		if (s.coordType == "vec3" && target == GL_TEXTURE_1D_ARRAY)
+			s.sizeDef = "<TEX_WIDTH>, <TEX_DEPTH>, 1";
+		else if (s.coordType == "vec3")
 			s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, 1";
 		else if (s.coordType == "vec4")
 			s.sizeDef = "<TEX_WIDTH>, <TEX_HEIGHT>, <TEX_DEPTH>, 1";
 	}
 
+	if (s.coordType != "float")
+		s.iCoordType = "i" + s.coordType;
+	else
+		s.iCoordType = "int";
+
 	return s;
 }
 
-/** Check if specific combination of target and format is allowed
+/** Check if specific combination of target and format is
+
  *
  * @param target       Target for which texture is binded
  * @param format       Texture internal format
@@ -2518,7 +2575,6 @@
  *
  * @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.
@@ -2598,7 +2654,7 @@
 
 		for (GLint sample = 0; sample < mState.samples; ++sample)
 		{
-			std::string shader = compute_textureFill;
+			std::string shader = st2_compute_textureFill;
 
 			// Adjust shader source to texture format
 			TokenStrings s = createShaderTokens(target, format, sample);
@@ -2732,7 +2788,7 @@
 						  (GLvoid*)out_data);
 		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
 
-		std::string shader = compute_lookupVerify;
+		std::string shader = st2_compute_lookupVerify;
 
 		// Adjust shader source to texture format
 		TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f);
@@ -2743,8 +2799,10 @@
 		replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), shader);
 		replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
 		replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), shader);
+		replaceToken("<LOD>", s.lod.c_str(), shader);
 		replaceToken("<LOD_DEF>", s.lodDef.c_str(), shader);
 		replaceToken("<COORD_TYPE>", s.coordType.c_str(), shader);
+		replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), shader);
 		replaceToken("<COORD_DEF>", s.coordDef.c_str(), shader);
 		replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
 		replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
@@ -2758,6 +2816,8 @@
 		replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), shader);
 		replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), shader);
 		replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), shader);
+		replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), shader);
+		replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), shader);
 		replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), shader);
 
 		replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), shader);
@@ -2797,14 +2857,14 @@
 			}
 			else
 			{
-				gl.bindImageTexture(1, //unit
+				gl.bindImageTexture(0, //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 */);
+				gl.uniform1i(2, 0 /* image_unit */);
 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
 			}
 
@@ -2821,9 +2881,9 @@
 			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::GetData");
 
 			//Verify only committed region
-			for (GLint x = 0; x < width; ++x)
+			for (GLint z = 0; z < depth; ++z)
 				for (GLint y = 0; y < height; ++y)
-					for (GLint z = 0; z < depth; ++z)
+					for (GLint x = 0; x < width; ++x)
 					{
 						GLubyte* dataRegion	= exp_data + x + y * width + z * width * height;
 						GLubyte* outDataRegion = out_data + x + y * width + z * width * height;
@@ -2834,8 +2894,9 @@
 		else
 		{
 			mLog << "Compute shader compilation failed (lookup) for target: " << target << ", format: " << format
-				 << ", infoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
-				 << ", shaderSource: " << shader.c_str() << " - ";
+				 << ", shaderInfoLog: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog
+				 << ", programInfoLog: " << program.getProgramInfo().infoLog << ", shaderSource: " << shader.c_str()
+				 << " - ";
 
 			result = false;
 		}
@@ -2858,7 +2919,7 @@
 /** Initializes the test group contents. */
 void SparseTexture2Tests::init()
 {
-	addChild(new ShaderExtensionTestCase(m_context));
+	addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture2"));
 	addChild(new StandardPageSizesTestCase(m_context));
 	addChild(new SparseTexture2AllocationTestCase(m_context));
 	addChild(new SparseTexture2CommitmentTestCase(m_context));
diff --git a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp
index d80313c..55dc0b1 100644
--- a/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp
+++ b/external/openglcts/modules/gl/gl4cSparseTexture2Tests.hpp
@@ -65,18 +65,19 @@
 
 typedef std::pair<GLint, PageSizeStruct> PageSizePair;
 
-/** Test verifies if GL_ARB_sparse_texture2 extension is available for GLSL
+/** Test verifies if extension is available for GLSL
  **/
 class ShaderExtensionTestCase : public deqp::TestCase
 {
 public:
 	/* Public methods */
-	ShaderExtensionTestCase(deqp::Context& context);
+	ShaderExtensionTestCase(deqp::Context& context, const std::string extension);
 
 	tcu::TestNode::IterateResult iterate();
 
 private:
 	/* Private members */
+	std::string mExtension;
 };
 
 /** Test verifies if values returned by GetInternalFormat* query matches Standard Virtual Page Sizes for <pname>:
@@ -202,11 +203,13 @@
 	/* Public methods */
 	SparseTexture2LookupTestCase(deqp::Context& context);
 
+	SparseTexture2LookupTestCase(deqp::Context& context, const char* name, const char* description);
+
 	void						 init();
 	tcu::TestNode::IterateResult iterate();
 
-private:
-	/* Private types */
+protected:
+	/* Protected types */
 	struct FunctionToken
 	{
 		std::string name;
@@ -227,21 +230,25 @@
 	{
 		std::string formatDef;
 		std::string sizeDef;
+		std::string lod;
 		std::string lodDef;
 		std::string coordType;
+		std::string iCoordType;
 		std::string coordDef;
 		std::string cubeMapCoordDef;
 		std::string refZDef;
 		std::string offsetDim;
+		std::string offsetType;
+		std::string nOffsetType;
 		std::string componentDef;
 		std::string offsetArrayDef;
 		std::string pointCoord;
 	};
 
-	/* Private members */
+	/* Protected members */
 	std::vector<FunctionToken> mFunctions;
 
-	/* Private methods */
+	/* Protected methods */
 	TokenStringsExt createLookupShaderTokens(GLint target, GLint format, GLint level, GLint sample,
 											 FunctionToken& funcToken);
 
@@ -269,6 +276,8 @@
 	SparseTexture2Tests& operator=(const SparseTexture2Tests& other);
 };
 
+void replaceToken(const GLchar* token, const GLchar* text, std::string& string);
+
 } /* glcts namespace */
 
 #endif // _GL4CSPARSETEXTURE2TESTS_HPP
diff --git a/external/openglcts/modules/gl/gl4cSparseTextureClampTests.cpp b/external/openglcts/modules/gl/gl4cSparseTextureClampTests.cpp
new file mode 100644
index 0000000..6109847
--- /dev/null
+++ b/external/openglcts/modules/gl/gl4cSparseTextureClampTests.cpp
@@ -0,0 +1,1117 @@
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file
+ * \brief
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file  gl4cSparseTextureClampTests.cpp
+ * \brief Conformance tests for the GL_ARB_sparse_texture2 functionality.
+ */ /*-------------------------------------------------------------------*/
+
+#include "gl4cSparseTextureClampTests.hpp"
+#include "deStringUtil.hpp"
+#include "gl4cSparseTexture2Tests.hpp"
+#include "gl4cSparseTextureTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluDefs.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+#include "tcuImageIO.hpp"
+#include "tcuTestLog.hpp"
+
+#include <cmath>
+#include <string.h>
+#include <vector>
+
+using namespace glw;
+using namespace glu;
+
+namespace gl4cts
+{
+
+const char* stc_compute_textureFill = "#version 430 core\n"
+									  "\n"
+									  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+									  "\n"
+									  "layout (location = 1) writeonly uniform highp <INPUT_TYPE> uni_image;\n"
+									  "\n"
+									  "void main()\n"
+									  "{\n"
+									  "    <POINT_TYPE> point = <POINT_TYPE>(<POINT_DEF>);\n"
+									  "    memoryBarrier();\n"
+									  "    <RETURN_TYPE> color = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+									  "    imageStore(uni_image, point<SAMPLE_DEF>, color);\n"
+									  "}\n";
+
+const char* stc_vertex_common = "#version 450\n"
+								"\n"
+								"in vec3 vertex;\n"
+								"in <COORD_TYPE> inCoord;\n"
+								"out <COORD_TYPE> texCoord;\n"
+								"\n"
+								"void main()\n"
+								"{\n"
+								"    texCoord = inCoord;\n"
+								"    gl_Position = vec4(vertex, 1);\n"
+								"}\n";
+
+const char* stc_fragment_lookupResidency = "#version 450 core\n"
+										   "\n"
+										   "#extension GL_ARB_sparse_texture2 : enable\n"
+										   "#extension GL_ARB_sparse_texture_clamp : enable\n"
+										   "\n"
+										   "in <COORD_TYPE> texCoord;\n"
+										   "out vec4 fragColor;\n"
+										   "\n"
+										   "layout (location = 1<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
+										   "layout (location = 2) uniform int widthCommitted;\n"
+										   "\n"
+										   "void main()\n"
+										   "{\n"
+										   "    <COORD_TYPE> coord = texCoord;\n"
+										   "    <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n"
+										   "    <POINT_TYPE> point = <POINT_TYPE>(coord * texSize);\n"
+										   "    <RETURN_TYPE> retValue,\n"
+										   "                  expValue,\n"
+										   "                  epsilon;\n"
+										   "    retValue = <RETURN_TYPE>(0);\n"
+										   "    expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+										   "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
+										   "\n"
+										   "<CUBE_MAP_COORD_DEF>\n"
+										   "<OFFSET_ARRAY_DEF>\n"
+										   "\n"
+										   "    ivec2 corner1 = ivec2(1, 1);\n"
+										   "    ivec2 corner2 = ivec2(texSize.x - 1, texSize.y - 1);\n"
+										   "\n"
+										   "    int code = <FUNCTION>(uni_in,\n"
+										   "                          <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
+										   "                          retValue<COMPONENT_DEF>);\n"
+										   "\n"
+										   "    fragColor = vec4(1);\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"
+										   "            fragColor = vec4(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"
+										   "            fragColor = vec4(0);\n"
+										   "        }\n"
+										   "    }\n"
+										   "}\n";
+
+const char* stc_fragment_lookupColor = "#version 450 core\n"
+									   "\n"
+									   "#extension GL_ARB_sparse_texture2 : enable\n"
+									   "#extension GL_ARB_sparse_texture_clamp : enable\n"
+									   "\n"
+									   "in <COORD_TYPE> texCoord;\n"
+									   "out vec4 fragColor;\n"
+									   "\n"
+									   "layout (location = 1<FORMAT_DEF>) uniform <INPUT_TYPE> uni_in;\n"
+									   "\n"
+									   "void main()\n"
+									   "{\n"
+									   "    <COORD_TYPE> coord = texCoord;\n"
+									   "    <ICOORD_TYPE> texSize = <ICOORD_TYPE>(<SIZE_DEF>);\n"
+									   "    <POINT_TYPE> point = <POINT_TYPE>(coord * texSize);\n"
+									   "    <RETURN_TYPE> retValue,\n"
+									   "                  expValue,\n"
+									   "                  epsilon;\n"
+									   "    retValue = <RETURN_TYPE>(0);\n"
+									   "    expValue = <RETURN_TYPE><RESULT_EXPECTED>;\n"
+									   "    epsilon = <RETURN_TYPE>(<EPSILON>);\n"
+									   "\n"
+									   "<CUBE_MAP_COORD_DEF>\n"
+									   "<OFFSET_ARRAY_DEF>\n"
+									   "\n"
+									   "<FUNCTION_DEF>\n"
+									   "\n"
+									   "    fragColor = vec4(1);\n"
+									   "\n"
+									   "    if (any(greaterThan(retValue, expValue + epsilon)) ||\n"
+									   "        any(lessThan(retValue, expValue - epsilon)))\n"
+									   "    {\n"
+									   "        fragColor = vec4(0);\n"
+									   "    }\n"
+									   "}\n";
+
+/** Constructor.
+ *
+ *  @param context     Rendering context
+ */
+SparseTextureClampLookupResidencyTestCase::SparseTextureClampLookupResidencyTestCase(deqp::Context& context)
+	: SparseTexture2LookupTestCase(
+		  context, "SparseTextureClampLookupResidency",
+		  "Verifies if sparse texture clamp lookup functions generates access residency information")
+{
+	/* Left blank intentionally */
+}
+
+/** Constructor.
+ *
+ *  @param context     Rendering context
+ */
+SparseTextureClampLookupResidencyTestCase::SparseTextureClampLookupResidencyTestCase(deqp::Context& context,
+																					 const char*	name,
+																					 const char*	description)
+	: SparseTexture2LookupTestCase(context, name, description)
+{
+	/* Left blank intentionally */
+}
+
+/** Stub init method */
+void SparseTextureClampLookupResidencyTestCase::init()
+{
+	SparseTextureCommitmentTestCase::init();
+	mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16);
+
+	FunctionToken f;
+	f = FunctionToken("sparseTextureClampARB", ", <LOD>");
+	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("sparseTextureOffsetClampARB", ", <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	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("sparseTextureGradClampARB",
+					  ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	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(
+		"sparseTextureGradOffsetClampARB",
+		", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	f.allowedTargets.insert(GL_TEXTURE_2D);
+	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
+	f.allowedTargets.insert(GL_TEXTURE_3D);
+	mFunctions.push_back(f);
+}
+
+/** Executes test iteration.
+ *
+ *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+ */
+tcu::TestNode::IterateResult SparseTextureClampLookupResidencyTestCase::iterate()
+{
+	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture_clamp"))
+	{
+		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
+		return STOP;
+	}
+
+	return SparseTexture2LookupTestCase::iterate();
+}
+
+/** 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 funcToken    Texture lookup function structure
+ *
+ * @return Returns true if target/format combination is allowed, false otherwise.
+ */
+bool SparseTextureClampLookupResidencyTestCase::funcAllowed(GLint target, GLint format, FunctionToken& funcToken)
+{
+	if (funcToken.allowedTargets.find(target) == funcToken.allowedTargets.end())
+		return false;
+
+	if (format == GL_DEPTH_COMPONENT16)
+	{
+		if (target == GL_TEXTURE_CUBE_MAP_ARRAY && funcToken.name == "sparseTextureGradClampARB")
+			return false;
+	}
+
+	return true;
+}
+
+/** 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 SparseTextureClampLookupResidencyTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format,
+																		GLuint& texture, GLint level,
+																		FunctionToken& funcToken)
+{
+	mLog << "Verify Lookup Residency 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;
+
+	std::vector<GLubyte> vecExpData;
+	std::vector<GLubyte> 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 = GL_TEXTURE_2D;
+	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");
+
+	GLuint fbo;
+	gl.genFramebuffers(1, &fbo);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
+	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, verifyTarget, verifyTexture, 0);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
+
+	gl.viewport(0, 0, width, height);
+
+	for (GLint z = 0; z < depth; ++z)
+	{
+		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, 0, GL_RED, GL_UNSIGNED_BYTE,
+							  (GLvoid*)out_data);
+			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
+
+			std::string vertex   = stc_vertex_common;
+			std::string fragment = stc_fragment_lookupResidency;
+
+			// Adjust shader source to texture format
+			TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f);
+
+			replaceToken("<COORD_TYPE>", s.coordType.c_str(), vertex);
+
+			replaceToken("<FUNCTION>", f.name.c_str(), fragment);
+			replaceToken("<ARGUMENTS>", f.arguments.c_str(), fragment);
+
+			replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), fragment);
+			replaceToken("<INPUT_TYPE>", s.inputType.c_str(), fragment);
+			replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), fragment);
+			replaceToken("<LOD>", s.lod.c_str(), fragment);
+			replaceToken("<LOD_DEF>", s.lodDef.c_str(), fragment);
+			replaceToken("<COORD_TYPE>", s.coordType.c_str(), fragment);
+			replaceToken("<ICOORD_TYPE>", s.iCoordType.c_str(), fragment);
+			replaceToken("<COORD_DEF>", s.coordDef.c_str(), fragment);
+			replaceToken("<POINT_TYPE>", s.pointType.c_str(), fragment);
+			replaceToken("<POINT_DEF>", s.pointDef.c_str(), fragment);
+			replaceToken("<RETURN_TYPE>", s.returnType.c_str(), fragment);
+			replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), fragment);
+			replaceToken("<EPSILON>", s.epsilon.c_str(), fragment);
+			replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), fragment);
+			replaceToken("<REFZ_DEF>", s.refZDef.c_str(), fragment);
+			replaceToken("<POINT_COORD>", s.pointCoord.c_str(), fragment);
+			replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), fragment);
+			replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), fragment);
+			replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), fragment);
+			replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), fragment);
+			replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), fragment);
+			replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), fragment);
+			replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), fragment);
+
+			replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), fragment);
+			replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), fragment);
+			replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), fragment);
+
+			ProgramSources sources = makeVtxFragSources(vertex.c_str(), fragment.c_str());
+
+			// 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 input sampler/image to shader
+				gl.activeTexture(GL_TEXTURE0);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
+				gl.uniform1i(1, 0 /* sampler_unit */);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
+
+				// Pass committed region width to shader
+				gl.uniform1i(2, widthCommitted /* committed region width */);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
+
+				gl.bindTexture(target, texture);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
+
+				gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+				draw(target, z, program);
+
+				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 y = 0; y < height; ++y)
+					for (GLint x = 0; x < width; ++x)
+					{
+						GLubyte* dataRegion	= exp_data + x + y * width;
+						GLubyte* outDataRegion = out_data + x + y * width;
+						if (dataRegion[0] != outDataRegion[0])
+							result = false;
+					}
+			}
+			else
+			{
+				mLog << "Shader compilation failed (lookup residency) for target: " << target << ", format: " << format
+					 << ", vertexInfoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog
+					 << ", fragmentInfoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog
+					 << ", programInfoLog: " << program.getProgramInfo().infoLog
+					 << ", fragmentSource: " << fragment.c_str() << " - ";
+
+				result = false;
+			}
+		}
+	}
+
+	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+	Texture::Delete(gl, verifyTexture);
+
+	return result;
+}
+
+void SparseTextureClampLookupResidencyTestCase::draw(GLint target, GLint layer, const ShaderProgram& program)
+{
+	const GLfloat texCoord1D[] = { 0.0f, 1.0f, 0.0f, 1.0f };
+
+	const GLfloat texCoord2D[] = {
+		0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+	};
+
+	const GLfloat texCoord3D[] = { 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 1.0f, 0.5f };
+
+	const GLfloat texCoordCubeMap[6][12] = {
+		{ 0.0f, 0.0f, 0.00f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f },
+		{ 0.0f, 0.0f, 0.17f, 1.0f, 0.0f, 0.17f, 0.0f, 1.0f, 0.17f, 1.0f, 1.0f, 0.17f },
+		{ 0.0f, 0.0f, 0.33f, 1.0f, 0.0f, 0.33f, 0.0f, 1.0f, 0.33f, 1.0f, 1.0f, 0.33f },
+		{ 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, 1.0f, 1.0f, 0.5f },
+		{ 0.0f, 0.0f, 0.67f, 1.0f, 0.0f, 0.67f, 0.0f, 1.0f, 0.67f, 1.0f, 1.0f, 0.67f },
+		{ 0.0f, 0.0f, 0.83f, 1.0f, 0.0f, 0.83f, 0.0f, 1.0f, 0.83f, 1.0f, 1.0f, 0.83f }
+	};
+
+	const GLfloat vertices[] = {
+		-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
+	};
+
+	const GLuint indices[] = { 0, 1, 2, 1, 2, 3 };
+
+	VertexArrayBinding floatCoord;
+
+	if (target == GL_TEXTURE_1D || target == GL_TEXTURE_1D_ARRAY)
+		floatCoord = glu::va::Float("inCoord", 1, 4, 0, texCoord1D);
+	else if (target == GL_TEXTURE_3D)
+		floatCoord = glu::va::Float("inCoord", 3, 4, 0, texCoord3D);
+	else if (target == GL_TEXTURE_CUBE_MAP)
+		floatCoord = glu::va::Float("inCoord", 3, 4, 0, texCoordCubeMap[layer]);
+	else
+		floatCoord = glu::va::Float("inCoord", 2, 4, 0, texCoord2D);
+
+	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("vertex", 3, 4, 0, vertices), floatCoord };
+
+	glu::draw(m_context.getRenderContext(), program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
+			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(indices), indices));
+}
+
+/** Constructor.
+ *
+ *  @param context     Rendering context
+ */
+SparseTextureClampLookupColorTestCase::SparseTextureClampLookupColorTestCase(deqp::Context& context)
+	: SparseTextureClampLookupResidencyTestCase(
+		  context, "SparseTextureClampLookupColor",
+		  "Verifies if sparse and non-sparse texture clamp lookup functions works as expected")
+{
+	/* Left blank intentionally */
+}
+
+/** Stub init method */
+void SparseTextureClampLookupColorTestCase::init()
+{
+	SparseTextureCommitmentTestCase::init();
+	mSupportedTargets.push_back(GL_TEXTURE_1D);
+	mSupportedTargets.push_back(GL_TEXTURE_1D_ARRAY);
+	mSupportedInternalFormats.push_back(GL_DEPTH_COMPONENT16);
+
+	FunctionToken f;
+	f = FunctionToken("sparseTextureClampARB", ", <LOD>");
+	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("textureClampARB", ", <LOD>");
+	f.allowedTargets.insert(GL_TEXTURE_1D);
+	f.allowedTargets.insert(GL_TEXTURE_1D_ARRAY);
+	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("sparseTextureOffsetClampARB", ", <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	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("textureOffsetClampARB", ", <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	f.allowedTargets.insert(GL_TEXTURE_1D);
+	f.allowedTargets.insert(GL_TEXTURE_1D_ARRAY);
+	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("sparseTextureGradClampARB",
+					  ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	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("textureGradClampARB", ", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	f.allowedTargets.insert(GL_TEXTURE_1D);
+	f.allowedTargets.insert(GL_TEXTURE_1D_ARRAY);
+	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(
+		"sparseTextureGradOffsetClampARB",
+		", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	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(
+		"textureGradOffsetClampARB",
+		", <NOFFSET_TYPE><OFFSET_DIM>(0), <NOFFSET_TYPE><OFFSET_DIM>(0), <OFFSET_TYPE><OFFSET_DIM>(0), <LOD>");
+	f.allowedTargets.insert(GL_TEXTURE_1D);
+	f.allowedTargets.insert(GL_TEXTURE_1D_ARRAY);
+	f.allowedTargets.insert(GL_TEXTURE_2D);
+	f.allowedTargets.insert(GL_TEXTURE_2D_ARRAY);
+	f.allowedTargets.insert(GL_TEXTURE_3D);
+	mFunctions.push_back(f);
+}
+
+/** Executes test iteration.
+ *
+ *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
+ */
+tcu::TestNode::IterateResult SparseTextureClampLookupColorTestCase::iterate()
+{
+	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture_clamp"))
+	{
+		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<glw::GLint>::const_iterator iter = mSupportedTargets.begin(); iter != mSupportedTargets.end();
+		 ++iter)
+	{
+		const GLint& target = *iter;
+
+		for (std::vector<glw::GLint>::const_iterator formIter = mSupportedInternalFormats.begin();
+			 formIter != mSupportedInternalFormats.end(); ++formIter)
+		{
+			const GLint& format = *formIter;
+
+			if (!caseAllowed(target, format))
+				continue;
+
+			for (std::vector<FunctionToken>::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;
+
+				bool isSparse = false;
+				if (funcToken.name.find("sparse", 0) != std::string::npos)
+					isSparse = true;
+
+				mLog.str("");
+				mLog << "Testing sparse texture lookup color functions for target: " << target << ", format: " << format
+					 << " - ";
+
+				if (isSparse)
+					sparseAllocateTexture(gl, target, format, texture, 3);
+				else
+					allocateTexture(gl, target, format, texture, 3);
+
+				if (format == GL_DEPTH_COMPONENT16)
+					setupDepthMode(gl, target, texture);
+
+				int l;
+				int maxLevels = 0;
+				for (l = 0; l < mState.levels; ++l)
+				{
+					if (!isSparse || commitTexturePage(gl, target, format, texture, l))
+					{
+						writeDataToTexture(gl, target, format, texture, l);
+						maxLevels = l;
+					}
+				}
+
+				for (l = 0; l <= maxLevels; ++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;
+}
+
+/** 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 SparseTextureClampLookupColorTestCase::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<GLubyte> vecData;
+		vecData.resize(texSize);
+		GLubyte* data = vecData.data();
+
+		deMemset(data, 255, texSize);
+
+		for (GLint sample = 0; sample < mState.samples; ++sample)
+		{
+			std::string shader = stc_compute_textureFill;
+
+			// Adjust shader source to texture format
+			TokenStrings s = createShaderTokens(target, format, sample);
+
+			// Change expected result as it has to be adjusted to different levels
+			s.resultExpected = generateExpectedResult(s.returnType, level);
+
+			replaceToken("<INPUT_TYPE>", s.inputType.c_str(), shader);
+			replaceToken("<POINT_TYPE>", s.pointType.c_str(), shader);
+			replaceToken("<POINT_DEF>", s.pointDef.c_str(), shader);
+			replaceToken("<RETURN_TYPE>", s.returnType.c_str(), shader);
+			replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), shader);
+			replaceToken("<SAMPLE_DEF>", 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;
+}
+
+/** 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 SparseTextureClampLookupColorTestCase::verifyLookupTextureData(const Functions& gl, GLint target, GLint format,
+																	GLuint& texture, GLint level,
+																	FunctionToken& funcToken)
+{
+	mLog << "Verify Lookup Color 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);
+
+	if (width == 0 || height == 0 || depth < mState.minDepth)
+		return true;
+
+	bool result = true;
+
+	if (target == GL_TEXTURE_CUBE_MAP)
+		depth = depth * 6;
+
+	GLint texSize = width * height;
+
+	std::vector<GLubyte> vecExpData;
+	std::vector<GLubyte> 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 = GL_TEXTURE_2D;
+	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");
+
+	GLuint fbo;
+	gl.genFramebuffers(1, &fbo);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers");
+	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, verifyTarget, verifyTexture, 0);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
+
+	gl.viewport(0, 0, width, height);
+
+	for (GLint z = 0; z < depth; ++z)
+	{
+		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, 0, GL_RED, GL_UNSIGNED_BYTE,
+							  (GLvoid*)out_data);
+			GLU_EXPECT_NO_ERROR(gl.getError(), "Texture::SubImage");
+
+			std::string vertex   = stc_vertex_common;
+			std::string fragment = stc_fragment_lookupColor;
+
+			std::string functionDef = generateFunctionDef(f.name);
+
+			// Adjust shader source to texture format
+			TokenStringsExt s = createLookupShaderTokens(target, format, level, sample, f);
+
+			// Change expected result as it has to be adjusted to different levels
+			s.resultExpected = generateExpectedResult(s.returnType, level);
+
+			replaceToken("<COORD_TYPE>", s.coordType.c_str(), vertex);
+
+			replaceToken("<FUNCTION_DEF>", functionDef.c_str(), fragment);
+			replaceToken("<FUNCTION>", f.name.c_str(), fragment);
+			replaceToken("<ARGUMENTS>", f.arguments.c_str(), fragment);
+
+			replaceToken("<OUTPUT_TYPE>", s.outputType.c_str(), fragment);
+			replaceToken("<INPUT_TYPE>", s.inputType.c_str(), fragment);
+			replaceToken("<SIZE_DEF>", s.sizeDef.c_str(), fragment);
+			replaceToken("<LOD>", s.lod.c_str(), fragment);
+			replaceToken("<LOD_DEF>", s.lodDef.c_str(), fragment);
+			replaceToken("<COORD_TYPE>", s.coordType.c_str(), fragment);
+			replaceToken("<ICOORD_TYPE>", s.coordType.c_str(), fragment);
+			replaceToken("<COORD_DEF>", s.coordDef.c_str(), fragment);
+			replaceToken("<POINT_TYPE>", s.pointType.c_str(), fragment);
+			replaceToken("<POINT_DEF>", s.pointDef.c_str(), fragment);
+			replaceToken("<RETURN_TYPE>", s.returnType.c_str(), fragment);
+			replaceToken("<RESULT_EXPECTED>", s.resultExpected.c_str(), fragment);
+			replaceToken("<EPSILON>", s.epsilon.c_str(), fragment);
+			replaceToken("<SAMPLE_DEF>", s.sampleDef.c_str(), fragment);
+			replaceToken("<REFZ_DEF>", s.refZDef.c_str(), fragment);
+			replaceToken("<POINT_COORD>", s.pointCoord.c_str(), fragment);
+			replaceToken("<COMPONENT_DEF>", s.componentDef.c_str(), fragment);
+			replaceToken("<CUBE_MAP_COORD_DEF>", s.cubeMapCoordDef.c_str(), fragment);
+			replaceToken("<OFFSET_ARRAY_DEF>", s.offsetArrayDef.c_str(), fragment);
+			replaceToken("<FORMAT_DEF>", s.formatDef.c_str(), fragment);
+			replaceToken("<OFFSET_TYPE>", s.offsetType.c_str(), fragment);
+			replaceToken("<NOFFSET_TYPE>", s.nOffsetType.c_str(), fragment);
+			replaceToken("<OFFSET_DIM>", s.offsetDim.c_str(), fragment);
+
+			replaceToken("<TEX_WIDTH>", de::toString(width).c_str(), fragment);
+			replaceToken("<TEX_HEIGHT>", de::toString(height).c_str(), fragment);
+			replaceToken("<TEX_DEPTH>", de::toString(depth).c_str(), fragment);
+
+			ProgramSources sources = makeVtxFragSources(vertex.c_str(), fragment.c_str());
+
+			// 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 input sampler/image to shader
+				gl.activeTexture(GL_TEXTURE0);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture");
+				gl.uniform1i(1, 0 /* sampler_unit */);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i");
+
+				gl.bindTexture(target, texture);
+				GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
+
+				gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+				draw(target, z, program);
+
+				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 y = 0; y < height; ++y)
+					for (GLint x = 0; x < width; ++x)
+					{
+						GLubyte* dataRegion	= exp_data + x + y * width;
+						GLubyte* outDataRegion = out_data + x + y * width;
+						if (dataRegion[0] != outDataRegion[0])
+							result = false;
+					}
+			}
+			else
+			{
+				mLog << "Shader compilation failed (lookup color) for target: " << target << ", format: " << format
+					 << ", vertexInfoLog: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog
+					 << ", fragmentInfoLog: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog
+					 << ", programInfoLog: " << program.getProgramInfo().infoLog
+					 << ", fragmentSource: " << fragment.c_str() << " - ";
+
+				result = false;
+			}
+		}
+	}
+
+	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
+
+	Texture::Delete(gl, verifyTexture);
+
+	return result;
+}
+
+/** Preparing texture. Function overridden to increase textures size.
+ *
+ * @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 SparseTextureClampLookupColorTestCase::prepareTexture(const Functions& gl, GLint target, GLint format,
+														   GLuint& texture)
+{
+	Texture::Generate(gl, texture);
+	Texture::Bind(gl, texture, target);
+
+	mState.minDepth = SparseTextureUtils::getTargetDepth(target);
+	SparseTextureUtils::getTexturePageSizes(gl, target, format, mState.pageSizeX, mState.pageSizeY, mState.pageSizeZ);
+
+	//The <width> and <height> has to be equal for cube map textures
+	if (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY)
+	{
+		if (mState.pageSizeX > mState.pageSizeY)
+			mState.pageSizeY = mState.pageSizeX;
+		else if (mState.pageSizeX < mState.pageSizeY)
+			mState.pageSizeX = mState.pageSizeY;
+	}
+
+	mState.width  = 4 * mState.pageSizeX;
+	mState.height = 4 * mState.pageSizeY;
+	mState.depth  = 4 * mState.pageSizeZ * mState.minDepth;
+
+	mState.format = glu::mapGLInternalFormat(format);
+
+	return true;
+}
+
+/** Commit texture page using texPageCommitment function. Function overridden to commit whole texture region.
+ *
+ * @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
+ *
+ * @return Returns true if commitment is done properly, false if commitment is not allowed or throws exception if error occurred.
+ */
+bool SparseTextureClampLookupColorTestCase::commitTexturePage(const Functions& gl, GLint target, GLint format,
+															  GLuint& texture, GLint level)
+{
+	mLog << "Commit Region [level: " << level << "] - ";
+
+	if (level > mState.levels - 1)
+		TCU_FAIL("Invalid level");
+
+	// Avoid not allowed commitments
+	if (!isInPageSizesRange(target, level) || !isPageSizesMultiplication(target, level))
+	{
+		mLog << "Skip commitment [level: " << level << "] - ";
+		return false;
+	}
+
+	GLint width;
+	GLint height;
+	GLint depth;
+	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
+
+	if (target == GL_TEXTURE_CUBE_MAP)
+		depth = 6 * depth;
+
+	Texture::Bind(gl, texture, target);
+	texPageCommitment(gl, target, format, texture, level, 0, 0, 0, width, height, depth, GL_TRUE);
+	GLU_EXPECT_NO_ERROR(gl.getError(), "texPageCommitment");
+
+	return true;
+}
+
+/** Check if current texture size for level is greater or equal page size in a corresponding direction
+ *
+ * @param target  Target for which texture is binded
+ * @param level   Texture mipmap level
+ *
+ * @return Returns true if the texture size condition is fulfilled, false otherwise.
+ */
+bool SparseTextureClampLookupColorTestCase::isInPageSizesRange(GLint target, GLint level)
+{
+	GLint width;
+	GLint height;
+	GLint depth;
+	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
+
+	if (target == GL_TEXTURE_CUBE_MAP)
+		depth = 6 * depth;
+
+	if (width >= mState.pageSizeX && height >= mState.pageSizeY && (mState.minDepth == 0 || depth >= mState.pageSizeZ))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+/** Check if current texture size for level is page size multiplication in a corresponding direction
+ *
+ * @param target  Target for which texture is binded
+ * @param level   Texture mipmap level
+ *
+ * @return Returns true if the texture size condition is fulfilled, false otherwise.
+ */
+bool SparseTextureClampLookupColorTestCase::isPageSizesMultiplication(GLint target, GLint level)
+{
+	GLint width;
+	GLint height;
+	GLint depth;
+	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
+
+	if (target == GL_TEXTURE_CUBE_MAP)
+		depth = 6 * depth;
+
+	if ((width % mState.pageSizeX) == 0 && (height % mState.pageSizeY) == 0 && (depth % mState.pageSizeZ) == 0)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+/** Constructor.
+ *
+ * @param funcName Tested function name.
+ *
+ * @return Returns shader source code part that uses lookup function to fetch texel from texture.
+ */
+std::string SparseTextureClampLookupColorTestCase::generateFunctionDef(std::string funcName)
+{
+	if (funcName.find("sparse", 0) != std::string::npos)
+	{
+		return std::string("    <FUNCTION>(uni_in,\n"
+						   "               <POINT_COORD><SAMPLE_DEF><ARGUMENTS>,\n"
+						   "               retValue<COMPONENT_DEF>);\n");
+	}
+	else
+	{
+		return std::string("    retValue<COMPONENT_DEF> = <FUNCTION>(uni_in,\n"
+						   "                                         <POINT_COORD><SAMPLE_DEF><ARGUMENTS>);\n");
+	}
+}
+
+/** Constructor.
+ *
+ * @param returnType Expected result variable type.
+ *
+ * @return Returns shader source token that represent expected lookup result value.
+ */
+std::string SparseTextureClampLookupColorTestCase::generateExpectedResult(std::string returnType, GLint level)
+{
+	if (returnType == "vec4")
+		return std::string("(") + de::toString(0.5f + (float)level / 10) + std::string(", 0, 0, 1)");
+	else
+		return std::string("(") + de::toString(level * 10) + std::string(", 0, 0, 1)");
+}
+
+/** Constructor.
+ *
+ *  @param context Rendering context.
+ */
+SparseTextureClampTests::SparseTextureClampTests(deqp::Context& context)
+	: TestCaseGroup(context, "sparse_texture_clamp_tests",
+					"Verify conformance of CTS_ARB_sparse_texture_clamp implementation")
+{
+}
+
+/** Initializes the test group contents. */
+void SparseTextureClampTests::init()
+{
+	addChild(new ShaderExtensionTestCase(m_context, "GL_ARB_sparse_texture_clamp"));
+	addChild(new SparseTextureClampLookupResidencyTestCase(m_context));
+	addChild(new SparseTextureClampLookupColorTestCase(m_context));
+}
+
+} /* gl4cts namespace */
diff --git a/external/openglcts/modules/gl/gl4cSparseTextureClampTests.hpp b/external/openglcts/modules/gl/gl4cSparseTextureClampTests.hpp
new file mode 100644
index 0000000..61b14f9
--- /dev/null
+++ b/external/openglcts/modules/gl/gl4cSparseTextureClampTests.hpp
@@ -0,0 +1,112 @@
+#ifndef _GL4CSPARSETEXTURECLAMPTESTS_HPP
+#define _GL4CSPARSETEXTURECLAMPTESTS_HPP
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file
+ * \brief
+ */ /*-------------------------------------------------------------------*/
+
+/**
+ */ /*!
+ * \file  gl4cSparseTextureClampTests.hpp
+ * \brief Conformance tests for the GL_ARB_sparse_texture_clamp functionality.
+ */ /*-------------------------------------------------------------------*/
+#include "glcTestCase.hpp"
+#include "glwDefs.hpp"
+#include "tcuDefs.hpp"
+
+#include "gl4cSparseTexture2Tests.hpp"
+#include "gl4cSparseTextureTests.hpp"
+
+using namespace glw;
+using namespace glu;
+
+namespace gl4cts
+{
+
+/** Test verifies if sparse texture clamp lookup functions generates access residency information
+ **/
+class SparseTextureClampLookupResidencyTestCase : public SparseTexture2LookupTestCase
+{
+public:
+	/* Public methods */
+	SparseTextureClampLookupResidencyTestCase(deqp::Context& context);
+
+	SparseTextureClampLookupResidencyTestCase(deqp::Context& context, const char* name, const char* description);
+
+	virtual void						 init();
+	virtual tcu::TestNode::IterateResult iterate();
+
+protected:
+	/* Protected methods */
+	virtual bool funcAllowed(GLint target, GLint format, FunctionToken& funcToken);
+
+	virtual bool verifyLookupTextureData(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level,
+										 FunctionToken& funcToken);
+
+	virtual void draw(GLint target, GLint layer, const ShaderProgram& program);
+};
+
+/** Test verifies if sparse and non-sparse texture clamp lookup functions works as expected
+ **/
+class SparseTextureClampLookupColorTestCase : public SparseTextureClampLookupResidencyTestCase
+{
+public:
+	/* Public methods */
+	SparseTextureClampLookupColorTestCase(deqp::Context& context);
+
+	virtual void						 init();
+	virtual tcu::TestNode::IterateResult iterate();
+
+private:
+	/* Private methods */
+	virtual bool writeDataToTexture(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level);
+	virtual bool verifyLookupTextureData(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level,
+										 FunctionToken& funcToken);
+
+	virtual bool prepareTexture(const Functions& gl, GLint target, GLint format, GLuint& texture);
+	virtual bool commitTexturePage(const Functions& gl, GLint target, GLint format, GLuint& texture, GLint level);
+
+	virtual bool isInPageSizesRange(GLint target, GLint level);
+	virtual bool isPageSizesMultiplication(GLint target, GLint level);
+
+private:
+	/* Private methods */
+	std::string generateFunctionDef(std::string funcName);
+	std::string generateExpectedResult(std::string returnType, GLint level);
+};
+
+/** Test group which encapsulates all sparse texture conformance tests */
+class SparseTextureClampTests : public deqp::TestCaseGroup
+{
+public:
+	/* Public methods */
+	SparseTextureClampTests(deqp::Context& context);
+
+	void init();
+
+private:
+	SparseTextureClampTests(const SparseTextureClampTests& other);
+	SparseTextureClampTests& operator=(const SparseTextureClampTests& other);
+};
+
+} /* glcts namespace */
+
+#endif // _GL4CSPARSETEXTURECLAMPTESTS_HPP
diff --git a/external/openglcts/modules/gl/gl4cSparseTextureTests.cpp b/external/openglcts/modules/gl/gl4cSparseTextureTests.cpp
index e07b8a6..8cd3492 100644
--- a/external/openglcts/modules/gl/gl4cSparseTextureTests.cpp
+++ b/external/openglcts/modules/gl/gl4cSparseTextureTests.cpp
@@ -105,8 +105,8 @@
 {
 	GLint depth;
 
-	if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
-		target == GL_TEXTURE_CUBE_MAP)
+	if (target == GL_TEXTURE_3D || target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY ||
+		target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || target == GL_TEXTURE_CUBE_MAP)
 	{
 		depth = 1;
 	}
@@ -152,13 +152,16 @@
 void SparseTextureUtils::getTextureLevelSize(GLint target, TextureState& state, GLint level, GLint& width,
 											 GLint& height, GLint& depth)
 {
-	width  = state.width / (int)pow(2, level);
-	height = state.height / (int)pow(2, level);
+	width = state.width / (int)pow(2, level);
+	if (target == GL_TEXTURE_1D || target == GL_TEXTURE_1D_ARRAY)
+		height = 1;
+	else
+		height = state.height / (int)pow(2, level);
 
-	if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
-	{
+	if (target == GL_TEXTURE_3D)
 		depth = state.depth / (int)pow(2, level);
-	}
+	else if (target == GL_TEXTURE_1D_ARRAY || target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY)
+		depth = state.depth;
 	else
 		depth = 1;
 }
@@ -228,6 +231,8 @@
 		gl.texStorage1D(target, levels, internal_format, width);
 		break;
 	case GL_TEXTURE_1D_ARRAY:
+		gl.texStorage2D(target, levels, internal_format, width, depth);
+		break;
 	case GL_TEXTURE_2D:
 	case GL_TEXTURE_RECTANGLE:
 	case GL_TEXTURE_CUBE_MAP:
@@ -289,6 +294,8 @@
 		gl.texSubImage1D(target, level, x, width, format, type, pixels);
 		break;
 	case GL_TEXTURE_1D_ARRAY:
+		gl.texSubImage2D(target, level, x, y, width, depth, format, type, pixels);
+		break;
 	case GL_TEXTURE_2D:
 	case GL_TEXTURE_RECTANGLE:
 		gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels);
@@ -1842,7 +1849,7 @@
 
 	mState.width  = 2 * mState.pageSizeX;
 	mState.height = 2 * mState.pageSizeY;
-	mState.depth  = mState.minDepth * mState.pageSizeZ;
+	mState.depth  = 2 * mState.pageSizeZ * mState.minDepth;
 
 	mState.format = glu::mapGLInternalFormat(format);
 
@@ -1955,8 +1962,6 @@
 		Texture::SubImage(gl, target, level, 0, 0, 0, width, height, depth, transferFormat.format,
 						  transferFormat.dataType, (GLvoid*)data);
 		GLU_EXPECT_NO_ERROR(gl.getError(), "SubImage");
-
-		delete[] data;
 	}
 
 	return true;
@@ -2112,7 +2117,7 @@
 	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
 
 	if (target == GL_TEXTURE_CUBE_MAP)
-		depth = 6 * mState.minDepth;
+		depth = 6 * depth;
 
 	GLint widthCommitted = width / 2;
 
@@ -2138,10 +2143,11 @@
 	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
 
 	if (target == GL_TEXTURE_CUBE_MAP)
-		depth = 6 * mState.minDepth;
+		depth = 6 * depth;
 
 	GLint widthCommitted = width / 2;
-	if (widthCommitted >= mState.pageSizeX && height >= mState.pageSizeY && depth >= mState.pageSizeZ)
+	if (widthCommitted >= mState.pageSizeX && height >= mState.pageSizeY &&
+		(mState.minDepth == 0 || depth >= mState.pageSizeZ))
 	{
 		return true;
 	}
@@ -2164,7 +2170,7 @@
 	SparseTextureUtils::getTextureLevelSize(target, mState, level, width, height, depth);
 
 	if (target == GL_TEXTURE_CUBE_MAP)
-		depth = 6 * mState.minDepth;
+		depth = 6 * depth;
 
 	GLint widthCommitted = width / 2;
 	if ((widthCommitted % mState.pageSizeX) == 0 && (height % mState.pageSizeY) == 0 && (depth % mState.pageSizeZ) == 0)
diff --git a/external/openglcts/modules/gl/gl4cTestPackages.cpp b/external/openglcts/modules/gl/gl4cTestPackages.cpp
index 1bdc13a..e59b552 100644
--- a/external/openglcts/modules/gl/gl4cTestPackages.cpp
+++ b/external/openglcts/modules/gl/gl4cTestPackages.cpp
@@ -52,6 +52,7 @@
 #include "gl4cShadingLanguage420PackTests.hpp"
 #include "gl4cSparseBufferTests.hpp"
 #include "gl4cSparseTexture2Tests.hpp"
+#include "gl4cSparseTextureClampTests.hpp"
 #include "gl4cSparseTextureTests.hpp"
 #include "gl4cStencilTexturingTests.hpp"
 #include "gl4cSyncTests.hpp"
@@ -330,6 +331,7 @@
 		addChild(new gl4cts::ParallelShaderCompileTests(getContext()));
 		addChild(new gl4cts::PostDepthCoverage(getContext()));
 		addChild(new gl4cts::SparseTexture2Tests(getContext()));
+		addChild(new gl4cts::SparseTextureClampTests(getContext()));
 		addChild(new gl4cts::TextureFilterMinmax(getContext()));
 	}
 	catch (...)
diff --git a/framework/opengl/wrapper/glwInitExtGL.inl b/framework/opengl/wrapper/glwInitExtGL.inl
index c190024..4a6b5e5 100644
--- a/framework/opengl/wrapper/glwInitExtGL.inl
+++ b/framework/opengl/wrapper/glwInitExtGL.inl
@@ -291,6 +291,265 @@
 	gl->vertexArrayVertexOffsetEXT						= (glVertexArrayVertexOffsetEXTFunc)						loader->get("glVertexArrayVertexOffsetEXT");
 }
 
+if (de::contains(extSet, "GL_EXT_direct_state_access"))
+{
+	gl->bindMultiTextureEXT								= (glBindMultiTextureEXTFunc)								loader->get("glBindMultiTextureEXT");
+	gl->checkNamedFramebufferStatus						= (glCheckNamedFramebufferStatusFunc)						loader->get("glCheckNamedFramebufferStatusEXT");
+	gl->clearNamedBufferData							= (glClearNamedBufferDataFunc)								loader->get("glClearNamedBufferDataEXT");
+	gl->clearNamedBufferSubData							= (glClearNamedBufferSubDataFunc)							loader->get("glClearNamedBufferSubDataEXT");
+	gl->clientAttribDefaultEXT							= (glClientAttribDefaultEXTFunc)							loader->get("glClientAttribDefaultEXT");
+	gl->compressedMultiTexImage1DEXT					= (glCompressedMultiTexImage1DEXTFunc)						loader->get("glCompressedMultiTexImage1DEXT");
+	gl->compressedMultiTexImage2DEXT					= (glCompressedMultiTexImage2DEXTFunc)						loader->get("glCompressedMultiTexImage2DEXT");
+	gl->compressedMultiTexImage3DEXT					= (glCompressedMultiTexImage3DEXTFunc)						loader->get("glCompressedMultiTexImage3DEXT");
+	gl->compressedMultiTexSubImage1DEXT					= (glCompressedMultiTexSubImage1DEXTFunc)					loader->get("glCompressedMultiTexSubImage1DEXT");
+	gl->compressedMultiTexSubImage2DEXT					= (glCompressedMultiTexSubImage2DEXTFunc)					loader->get("glCompressedMultiTexSubImage2DEXT");
+	gl->compressedMultiTexSubImage3DEXT					= (glCompressedMultiTexSubImage3DEXTFunc)					loader->get("glCompressedMultiTexSubImage3DEXT");
+	gl->compressedTextureImage1DEXT						= (glCompressedTextureImage1DEXTFunc)						loader->get("glCompressedTextureImage1DEXT");
+	gl->compressedTextureImage2DEXT						= (glCompressedTextureImage2DEXTFunc)						loader->get("glCompressedTextureImage2DEXT");
+	gl->compressedTextureImage3DEXT						= (glCompressedTextureImage3DEXTFunc)						loader->get("glCompressedTextureImage3DEXT");
+	gl->compressedTextureSubImage1DEXT					= (glCompressedTextureSubImage1DEXTFunc)					loader->get("glCompressedTextureSubImage1DEXT");
+	gl->compressedTextureSubImage2DEXT					= (glCompressedTextureSubImage2DEXTFunc)					loader->get("glCompressedTextureSubImage2DEXT");
+	gl->compressedTextureSubImage3DEXT					= (glCompressedTextureSubImage3DEXTFunc)					loader->get("glCompressedTextureSubImage3DEXT");
+	gl->copyMultiTexImage1DEXT							= (glCopyMultiTexImage1DEXTFunc)							loader->get("glCopyMultiTexImage1DEXT");
+	gl->copyMultiTexImage2DEXT							= (glCopyMultiTexImage2DEXTFunc)							loader->get("glCopyMultiTexImage2DEXT");
+	gl->copyMultiTexSubImage1DEXT						= (glCopyMultiTexSubImage1DEXTFunc)							loader->get("glCopyMultiTexSubImage1DEXT");
+	gl->copyMultiTexSubImage2DEXT						= (glCopyMultiTexSubImage2DEXTFunc)							loader->get("glCopyMultiTexSubImage2DEXT");
+	gl->copyMultiTexSubImage3DEXT						= (glCopyMultiTexSubImage3DEXTFunc)							loader->get("glCopyMultiTexSubImage3DEXT");
+	gl->copyTextureImage1DEXT							= (glCopyTextureImage1DEXTFunc)								loader->get("glCopyTextureImage1DEXT");
+	gl->copyTextureImage2DEXT							= (glCopyTextureImage2DEXTFunc)								loader->get("glCopyTextureImage2DEXT");
+	gl->copyTextureSubImage1DEXT						= (glCopyTextureSubImage1DEXTFunc)							loader->get("glCopyTextureSubImage1DEXT");
+	gl->copyTextureSubImage2DEXT						= (glCopyTextureSubImage2DEXTFunc)							loader->get("glCopyTextureSubImage2DEXT");
+	gl->copyTextureSubImage3DEXT						= (glCopyTextureSubImage3DEXTFunc)							loader->get("glCopyTextureSubImage3DEXT");
+	gl->disableClientStateIndexedEXT					= (glDisableClientStateIndexedEXTFunc)						loader->get("glDisableClientStateIndexedEXT");
+	gl->disableClientStateiEXT							= (glDisableClientStateiEXTFunc)							loader->get("glDisableClientStateiEXT");
+	gl->disableIndexedEXT								= (glDisableIndexedEXTFunc)									loader->get("glDisableIndexedEXT");
+	gl->disableVertexArrayAttrib						= (glDisableVertexArrayAttribFunc)							loader->get("glDisableVertexArrayAttribEXT");
+	gl->disableVertexArrayEXT							= (glDisableVertexArrayEXTFunc)								loader->get("glDisableVertexArrayEXT");
+	gl->enableClientStateIndexedEXT						= (glEnableClientStateIndexedEXTFunc)						loader->get("glEnableClientStateIndexedEXT");
+	gl->enableClientStateiEXT							= (glEnableClientStateiEXTFunc)								loader->get("glEnableClientStateiEXT");
+	gl->enableIndexedEXT								= (glEnableIndexedEXTFunc)									loader->get("glEnableIndexedEXT");
+	gl->enableVertexArrayAttrib							= (glEnableVertexArrayAttribFunc)							loader->get("glEnableVertexArrayAttribEXT");
+	gl->enableVertexArrayEXT							= (glEnableVertexArrayEXTFunc)								loader->get("glEnableVertexArrayEXT");
+	gl->flushMappedNamedBufferRange						= (glFlushMappedNamedBufferRangeFunc)						loader->get("glFlushMappedNamedBufferRangeEXT");
+	gl->framebufferDrawBufferEXT						= (glFramebufferDrawBufferEXTFunc)							loader->get("glFramebufferDrawBufferEXT");
+	gl->framebufferDrawBuffersEXT						= (glFramebufferDrawBuffersEXTFunc)							loader->get("glFramebufferDrawBuffersEXT");
+	gl->framebufferReadBufferEXT						= (glFramebufferReadBufferEXTFunc)							loader->get("glFramebufferReadBufferEXT");
+	gl->generateMultiTexMipmapEXT						= (glGenerateMultiTexMipmapEXTFunc)							loader->get("glGenerateMultiTexMipmapEXT");
+	gl->generateTextureMipmap							= (glGenerateTextureMipmapFunc)								loader->get("glGenerateTextureMipmapEXT");
+	gl->getBooleanIndexedvEXT							= (glGetBooleanIndexedvEXTFunc)								loader->get("glGetBooleanIndexedvEXT");
+	gl->getCompressedMultiTexImageEXT					= (glGetCompressedMultiTexImageEXTFunc)						loader->get("glGetCompressedMultiTexImageEXT");
+	gl->getCompressedTextureImage						= (glGetCompressedTextureImageFunc)							loader->get("glGetCompressedTextureImageEXT");
+	gl->getDoubleIndexedvEXT							= (glGetDoubleIndexedvEXTFunc)								loader->get("glGetDoubleIndexedvEXT");
+	gl->getDoublei_v									= (glGetDoublei_vFunc)										loader->get("glGetDoublei_vEXT");
+	gl->getFloatIndexedvEXT								= (glGetFloatIndexedvEXTFunc)								loader->get("glGetFloatIndexedvEXT");
+	gl->getFloati_v										= (glGetFloati_vFunc)										loader->get("glGetFloati_vEXT");
+	gl->getFramebufferParameteriv						= (glGetFramebufferParameterivFunc)							loader->get("glGetFramebufferParameterivEXT");
+	gl->getIntegerIndexedvEXT							= (glGetIntegerIndexedvEXTFunc)								loader->get("glGetIntegerIndexedvEXT");
+	gl->getMultiTexEnvfvEXT								= (glGetMultiTexEnvfvEXTFunc)								loader->get("glGetMultiTexEnvfvEXT");
+	gl->getMultiTexEnvivEXT								= (glGetMultiTexEnvivEXTFunc)								loader->get("glGetMultiTexEnvivEXT");
+	gl->getMultiTexGendvEXT								= (glGetMultiTexGendvEXTFunc)								loader->get("glGetMultiTexGendvEXT");
+	gl->getMultiTexGenfvEXT								= (glGetMultiTexGenfvEXTFunc)								loader->get("glGetMultiTexGenfvEXT");
+	gl->getMultiTexGenivEXT								= (glGetMultiTexGenivEXTFunc)								loader->get("glGetMultiTexGenivEXT");
+	gl->getMultiTexImageEXT								= (glGetMultiTexImageEXTFunc)								loader->get("glGetMultiTexImageEXT");
+	gl->getMultiTexLevelParameterfvEXT					= (glGetMultiTexLevelParameterfvEXTFunc)					loader->get("glGetMultiTexLevelParameterfvEXT");
+	gl->getMultiTexLevelParameterivEXT					= (glGetMultiTexLevelParameterivEXTFunc)					loader->get("glGetMultiTexLevelParameterivEXT");
+	gl->getMultiTexParameterIivEXT						= (glGetMultiTexParameterIivEXTFunc)						loader->get("glGetMultiTexParameterIivEXT");
+	gl->getMultiTexParameterIuivEXT						= (glGetMultiTexParameterIuivEXTFunc)						loader->get("glGetMultiTexParameterIuivEXT");
+	gl->getMultiTexParameterfvEXT						= (glGetMultiTexParameterfvEXTFunc)							loader->get("glGetMultiTexParameterfvEXT");
+	gl->getMultiTexParameterivEXT						= (glGetMultiTexParameterivEXTFunc)							loader->get("glGetMultiTexParameterivEXT");
+	gl->getNamedBufferParameteriv						= (glGetNamedBufferParameterivFunc)							loader->get("glGetNamedBufferParameterivEXT");
+	gl->getNamedBufferPointerv							= (glGetNamedBufferPointervFunc)							loader->get("glGetNamedBufferPointervEXT");
+	gl->getNamedBufferSubData							= (glGetNamedBufferSubDataFunc)								loader->get("glGetNamedBufferSubDataEXT");
+	gl->getNamedFramebufferAttachmentParameteriv		= (glGetNamedFramebufferAttachmentParameterivFunc)			loader->get("glGetNamedFramebufferAttachmentParameterivEXT");
+	gl->getNamedFramebufferParameteriv					= (glGetNamedFramebufferParameterivFunc)					loader->get("glGetNamedFramebufferParameterivEXT");
+	gl->getNamedProgramLocalParameterIivEXT				= (glGetNamedProgramLocalParameterIivEXTFunc)				loader->get("glGetNamedProgramLocalParameterIivEXT");
+	gl->getNamedProgramLocalParameterIuivEXT			= (glGetNamedProgramLocalParameterIuivEXTFunc)				loader->get("glGetNamedProgramLocalParameterIuivEXT");
+	gl->getNamedProgramLocalParameterdvEXT				= (glGetNamedProgramLocalParameterdvEXTFunc)				loader->get("glGetNamedProgramLocalParameterdvEXT");
+	gl->getNamedProgramLocalParameterfvEXT				= (glGetNamedProgramLocalParameterfvEXTFunc)				loader->get("glGetNamedProgramLocalParameterfvEXT");
+	gl->getNamedProgramStringEXT						= (glGetNamedProgramStringEXTFunc)							loader->get("glGetNamedProgramStringEXT");
+	gl->getNamedProgramivEXT							= (glGetNamedProgramivEXTFunc)								loader->get("glGetNamedProgramivEXT");
+	gl->getNamedRenderbufferParameteriv					= (glGetNamedRenderbufferParameterivFunc)					loader->get("glGetNamedRenderbufferParameterivEXT");
+	gl->getPointerIndexedvEXT							= (glGetPointerIndexedvEXTFunc)								loader->get("glGetPointerIndexedvEXT");
+	gl->getPointeri_vEXT								= (glGetPointeri_vEXTFunc)									loader->get("glGetPointeri_vEXT");
+	gl->getTextureImage									= (glGetTextureImageFunc)									loader->get("glGetTextureImageEXT");
+	gl->getTextureLevelParameterfv						= (glGetTextureLevelParameterfvFunc)						loader->get("glGetTextureLevelParameterfvEXT");
+	gl->getTextureLevelParameteriv						= (glGetTextureLevelParameterivFunc)						loader->get("glGetTextureLevelParameterivEXT");
+	gl->getTextureParameterIiv							= (glGetTextureParameterIivFunc)							loader->get("glGetTextureParameterIivEXT");
+	gl->getTextureParameterIuiv							= (glGetTextureParameterIuivFunc)							loader->get("glGetTextureParameterIuivEXT");
+	gl->getTextureParameterfv							= (glGetTextureParameterfvFunc)								loader->get("glGetTextureParameterfvEXT");
+	gl->getTextureParameteriv							= (glGetTextureParameterivFunc)								loader->get("glGetTextureParameterivEXT");
+	gl->getVertexArrayIntegeri_vEXT						= (glGetVertexArrayIntegeri_vEXTFunc)						loader->get("glGetVertexArrayIntegeri_vEXT");
+	gl->getVertexArrayIntegervEXT						= (glGetVertexArrayIntegervEXTFunc)							loader->get("glGetVertexArrayIntegervEXT");
+	gl->getVertexArrayPointeri_vEXT						= (glGetVertexArrayPointeri_vEXTFunc)						loader->get("glGetVertexArrayPointeri_vEXT");
+	gl->getVertexArrayPointervEXT						= (glGetVertexArrayPointervEXTFunc)							loader->get("glGetVertexArrayPointervEXT");
+	gl->isEnabledIndexedEXT								= (glIsEnabledIndexedEXTFunc)								loader->get("glIsEnabledIndexedEXT");
+	gl->mapNamedBuffer									= (glMapNamedBufferFunc)									loader->get("glMapNamedBufferEXT");
+	gl->mapNamedBufferRange								= (glMapNamedBufferRangeFunc)								loader->get("glMapNamedBufferRangeEXT");
+	gl->matrixFrustumEXT								= (glMatrixFrustumEXTFunc)									loader->get("glMatrixFrustumEXT");
+	gl->matrixLoadIdentityEXT							= (glMatrixLoadIdentityEXTFunc)								loader->get("glMatrixLoadIdentityEXT");
+	gl->matrixLoadTransposedEXT							= (glMatrixLoadTransposedEXTFunc)							loader->get("glMatrixLoadTransposedEXT");
+	gl->matrixLoadTransposefEXT							= (glMatrixLoadTransposefEXTFunc)							loader->get("glMatrixLoadTransposefEXT");
+	gl->matrixLoaddEXT									= (glMatrixLoaddEXTFunc)									loader->get("glMatrixLoaddEXT");
+	gl->matrixLoadfEXT									= (glMatrixLoadfEXTFunc)									loader->get("glMatrixLoadfEXT");
+	gl->matrixMultTransposedEXT							= (glMatrixMultTransposedEXTFunc)							loader->get("glMatrixMultTransposedEXT");
+	gl->matrixMultTransposefEXT							= (glMatrixMultTransposefEXTFunc)							loader->get("glMatrixMultTransposefEXT");
+	gl->matrixMultdEXT									= (glMatrixMultdEXTFunc)									loader->get("glMatrixMultdEXT");
+	gl->matrixMultfEXT									= (glMatrixMultfEXTFunc)									loader->get("glMatrixMultfEXT");
+	gl->matrixOrthoEXT									= (glMatrixOrthoEXTFunc)									loader->get("glMatrixOrthoEXT");
+	gl->matrixPopEXT									= (glMatrixPopEXTFunc)										loader->get("glMatrixPopEXT");
+	gl->matrixPushEXT									= (glMatrixPushEXTFunc)										loader->get("glMatrixPushEXT");
+	gl->matrixRotatedEXT								= (glMatrixRotatedEXTFunc)									loader->get("glMatrixRotatedEXT");
+	gl->matrixRotatefEXT								= (glMatrixRotatefEXTFunc)									loader->get("glMatrixRotatefEXT");
+	gl->matrixScaledEXT									= (glMatrixScaledEXTFunc)									loader->get("glMatrixScaledEXT");
+	gl->matrixScalefEXT									= (glMatrixScalefEXTFunc)									loader->get("glMatrixScalefEXT");
+	gl->matrixTranslatedEXT								= (glMatrixTranslatedEXTFunc)								loader->get("glMatrixTranslatedEXT");
+	gl->matrixTranslatefEXT								= (glMatrixTranslatefEXTFunc)								loader->get("glMatrixTranslatefEXT");
+	gl->multiTexBufferEXT								= (glMultiTexBufferEXTFunc)									loader->get("glMultiTexBufferEXT");
+	gl->multiTexCoordPointerEXT							= (glMultiTexCoordPointerEXTFunc)							loader->get("glMultiTexCoordPointerEXT");
+	gl->multiTexEnvfEXT									= (glMultiTexEnvfEXTFunc)									loader->get("glMultiTexEnvfEXT");
+	gl->multiTexEnvfvEXT								= (glMultiTexEnvfvEXTFunc)									loader->get("glMultiTexEnvfvEXT");
+	gl->multiTexEnviEXT									= (glMultiTexEnviEXTFunc)									loader->get("glMultiTexEnviEXT");
+	gl->multiTexEnvivEXT								= (glMultiTexEnvivEXTFunc)									loader->get("glMultiTexEnvivEXT");
+	gl->multiTexGendEXT									= (glMultiTexGendEXTFunc)									loader->get("glMultiTexGendEXT");
+	gl->multiTexGendvEXT								= (glMultiTexGendvEXTFunc)									loader->get("glMultiTexGendvEXT");
+	gl->multiTexGenfEXT									= (glMultiTexGenfEXTFunc)									loader->get("glMultiTexGenfEXT");
+	gl->multiTexGenfvEXT								= (glMultiTexGenfvEXTFunc)									loader->get("glMultiTexGenfvEXT");
+	gl->multiTexGeniEXT									= (glMultiTexGeniEXTFunc)									loader->get("glMultiTexGeniEXT");
+	gl->multiTexGenivEXT								= (glMultiTexGenivEXTFunc)									loader->get("glMultiTexGenivEXT");
+	gl->multiTexImage1DEXT								= (glMultiTexImage1DEXTFunc)								loader->get("glMultiTexImage1DEXT");
+	gl->multiTexImage2DEXT								= (glMultiTexImage2DEXTFunc)								loader->get("glMultiTexImage2DEXT");
+	gl->multiTexImage3DEXT								= (glMultiTexImage3DEXTFunc)								loader->get("glMultiTexImage3DEXT");
+	gl->multiTexParameterIivEXT							= (glMultiTexParameterIivEXTFunc)							loader->get("glMultiTexParameterIivEXT");
+	gl->multiTexParameterIuivEXT						= (glMultiTexParameterIuivEXTFunc)							loader->get("glMultiTexParameterIuivEXT");
+	gl->multiTexParameterfEXT							= (glMultiTexParameterfEXTFunc)								loader->get("glMultiTexParameterfEXT");
+	gl->multiTexParameterfvEXT							= (glMultiTexParameterfvEXTFunc)							loader->get("glMultiTexParameterfvEXT");
+	gl->multiTexParameteriEXT							= (glMultiTexParameteriEXTFunc)								loader->get("glMultiTexParameteriEXT");
+	gl->multiTexParameterivEXT							= (glMultiTexParameterivEXTFunc)							loader->get("glMultiTexParameterivEXT");
+	gl->multiTexRenderbufferEXT							= (glMultiTexRenderbufferEXTFunc)							loader->get("glMultiTexRenderbufferEXT");
+	gl->multiTexSubImage1DEXT							= (glMultiTexSubImage1DEXTFunc)								loader->get("glMultiTexSubImage1DEXT");
+	gl->multiTexSubImage2DEXT							= (glMultiTexSubImage2DEXTFunc)								loader->get("glMultiTexSubImage2DEXT");
+	gl->multiTexSubImage3DEXT							= (glMultiTexSubImage3DEXTFunc)								loader->get("glMultiTexSubImage3DEXT");
+	gl->namedBufferData									= (glNamedBufferDataFunc)									loader->get("glNamedBufferDataEXT");
+	gl->namedBufferStorage								= (glNamedBufferStorageFunc)								loader->get("glNamedBufferStorageEXT");
+	gl->namedBufferSubData								= (glNamedBufferSubDataFunc)								loader->get("glNamedBufferSubDataEXT");
+	gl->namedCopyBufferSubDataEXT						= (glNamedCopyBufferSubDataEXTFunc)							loader->get("glNamedCopyBufferSubDataEXT");
+	gl->namedFramebufferParameteri						= (glNamedFramebufferParameteriFunc)						loader->get("glNamedFramebufferParameteriEXT");
+	gl->namedFramebufferRenderbuffer					= (glNamedFramebufferRenderbufferFunc)						loader->get("glNamedFramebufferRenderbufferEXT");
+	gl->namedFramebufferTexture1DEXT					= (glNamedFramebufferTexture1DEXTFunc)						loader->get("glNamedFramebufferTexture1DEXT");
+	gl->namedFramebufferTexture2DEXT					= (glNamedFramebufferTexture2DEXTFunc)						loader->get("glNamedFramebufferTexture2DEXT");
+	gl->namedFramebufferTexture3DEXT					= (glNamedFramebufferTexture3DEXTFunc)						loader->get("glNamedFramebufferTexture3DEXT");
+	gl->namedFramebufferTexture							= (glNamedFramebufferTextureFunc)							loader->get("glNamedFramebufferTextureEXT");
+	gl->namedFramebufferTextureFaceEXT					= (glNamedFramebufferTextureFaceEXTFunc)					loader->get("glNamedFramebufferTextureFaceEXT");
+	gl->namedFramebufferTextureLayer					= (glNamedFramebufferTextureLayerFunc)						loader->get("glNamedFramebufferTextureLayerEXT");
+	gl->namedProgramLocalParameter4dEXT					= (glNamedProgramLocalParameter4dEXTFunc)					loader->get("glNamedProgramLocalParameter4dEXT");
+	gl->namedProgramLocalParameter4dvEXT				= (glNamedProgramLocalParameter4dvEXTFunc)					loader->get("glNamedProgramLocalParameter4dvEXT");
+	gl->namedProgramLocalParameter4fEXT					= (glNamedProgramLocalParameter4fEXTFunc)					loader->get("glNamedProgramLocalParameter4fEXT");
+	gl->namedProgramLocalParameter4fvEXT				= (glNamedProgramLocalParameter4fvEXTFunc)					loader->get("glNamedProgramLocalParameter4fvEXT");
+	gl->namedProgramLocalParameterI4iEXT				= (glNamedProgramLocalParameterI4iEXTFunc)					loader->get("glNamedProgramLocalParameterI4iEXT");
+	gl->namedProgramLocalParameterI4ivEXT				= (glNamedProgramLocalParameterI4ivEXTFunc)					loader->get("glNamedProgramLocalParameterI4ivEXT");
+	gl->namedProgramLocalParameterI4uiEXT				= (glNamedProgramLocalParameterI4uiEXTFunc)					loader->get("glNamedProgramLocalParameterI4uiEXT");
+	gl->namedProgramLocalParameterI4uivEXT				= (glNamedProgramLocalParameterI4uivEXTFunc)				loader->get("glNamedProgramLocalParameterI4uivEXT");
+	gl->namedProgramLocalParameters4fvEXT				= (glNamedProgramLocalParameters4fvEXTFunc)					loader->get("glNamedProgramLocalParameters4fvEXT");
+	gl->namedProgramLocalParametersI4ivEXT				= (glNamedProgramLocalParametersI4ivEXTFunc)				loader->get("glNamedProgramLocalParametersI4ivEXT");
+	gl->namedProgramLocalParametersI4uivEXT				= (glNamedProgramLocalParametersI4uivEXTFunc)				loader->get("glNamedProgramLocalParametersI4uivEXT");
+	gl->namedProgramStringEXT							= (glNamedProgramStringEXTFunc)								loader->get("glNamedProgramStringEXT");
+	gl->namedRenderbufferStorage						= (glNamedRenderbufferStorageFunc)							loader->get("glNamedRenderbufferStorageEXT");
+	gl->namedRenderbufferStorageMultisampleCoverageEXT	= (glNamedRenderbufferStorageMultisampleCoverageEXTFunc)	loader->get("glNamedRenderbufferStorageMultisampleCoverageEXT");
+	gl->namedRenderbufferStorageMultisample				= (glNamedRenderbufferStorageMultisampleFunc)				loader->get("glNamedRenderbufferStorageMultisampleEXT");
+	gl->programUniform1d								= (glProgramUniform1dFunc)									loader->get("glProgramUniform1dEXT");
+	gl->programUniform1dv								= (glProgramUniform1dvFunc)									loader->get("glProgramUniform1dvEXT");
+	gl->programUniform1f								= (glProgramUniform1fFunc)									loader->get("glProgramUniform1fEXT");
+	gl->programUniform1fv								= (glProgramUniform1fvFunc)									loader->get("glProgramUniform1fvEXT");
+	gl->programUniform1i								= (glProgramUniform1iFunc)									loader->get("glProgramUniform1iEXT");
+	gl->programUniform1iv								= (glProgramUniform1ivFunc)									loader->get("glProgramUniform1ivEXT");
+	gl->programUniform1ui								= (glProgramUniform1uiFunc)									loader->get("glProgramUniform1uiEXT");
+	gl->programUniform1uiv								= (glProgramUniform1uivFunc)								loader->get("glProgramUniform1uivEXT");
+	gl->programUniform2d								= (glProgramUniform2dFunc)									loader->get("glProgramUniform2dEXT");
+	gl->programUniform2dv								= (glProgramUniform2dvFunc)									loader->get("glProgramUniform2dvEXT");
+	gl->programUniform2f								= (glProgramUniform2fFunc)									loader->get("glProgramUniform2fEXT");
+	gl->programUniform2fv								= (glProgramUniform2fvFunc)									loader->get("glProgramUniform2fvEXT");
+	gl->programUniform2i								= (glProgramUniform2iFunc)									loader->get("glProgramUniform2iEXT");
+	gl->programUniform2iv								= (glProgramUniform2ivFunc)									loader->get("glProgramUniform2ivEXT");
+	gl->programUniform2ui								= (glProgramUniform2uiFunc)									loader->get("glProgramUniform2uiEXT");
+	gl->programUniform2uiv								= (glProgramUniform2uivFunc)								loader->get("glProgramUniform2uivEXT");
+	gl->programUniform3d								= (glProgramUniform3dFunc)									loader->get("glProgramUniform3dEXT");
+	gl->programUniform3dv								= (glProgramUniform3dvFunc)									loader->get("glProgramUniform3dvEXT");
+	gl->programUniform3f								= (glProgramUniform3fFunc)									loader->get("glProgramUniform3fEXT");
+	gl->programUniform3fv								= (glProgramUniform3fvFunc)									loader->get("glProgramUniform3fvEXT");
+	gl->programUniform3i								= (glProgramUniform3iFunc)									loader->get("glProgramUniform3iEXT");
+	gl->programUniform3iv								= (glProgramUniform3ivFunc)									loader->get("glProgramUniform3ivEXT");
+	gl->programUniform3ui								= (glProgramUniform3uiFunc)									loader->get("glProgramUniform3uiEXT");
+	gl->programUniform3uiv								= (glProgramUniform3uivFunc)								loader->get("glProgramUniform3uivEXT");
+	gl->programUniform4d								= (glProgramUniform4dFunc)									loader->get("glProgramUniform4dEXT");
+	gl->programUniform4dv								= (glProgramUniform4dvFunc)									loader->get("glProgramUniform4dvEXT");
+	gl->programUniform4f								= (glProgramUniform4fFunc)									loader->get("glProgramUniform4fEXT");
+	gl->programUniform4fv								= (glProgramUniform4fvFunc)									loader->get("glProgramUniform4fvEXT");
+	gl->programUniform4i								= (glProgramUniform4iFunc)									loader->get("glProgramUniform4iEXT");
+	gl->programUniform4iv								= (glProgramUniform4ivFunc)									loader->get("glProgramUniform4ivEXT");
+	gl->programUniform4ui								= (glProgramUniform4uiFunc)									loader->get("glProgramUniform4uiEXT");
+	gl->programUniform4uiv								= (glProgramUniform4uivFunc)								loader->get("glProgramUniform4uivEXT");
+	gl->programUniformMatrix2dv							= (glProgramUniformMatrix2dvFunc)							loader->get("glProgramUniformMatrix2dvEXT");
+	gl->programUniformMatrix2fv							= (glProgramUniformMatrix2fvFunc)							loader->get("glProgramUniformMatrix2fvEXT");
+	gl->programUniformMatrix2x3dv						= (glProgramUniformMatrix2x3dvFunc)							loader->get("glProgramUniformMatrix2x3dvEXT");
+	gl->programUniformMatrix2x3fv						= (glProgramUniformMatrix2x3fvFunc)							loader->get("glProgramUniformMatrix2x3fvEXT");
+	gl->programUniformMatrix2x4dv						= (glProgramUniformMatrix2x4dvFunc)							loader->get("glProgramUniformMatrix2x4dvEXT");
+	gl->programUniformMatrix2x4fv						= (glProgramUniformMatrix2x4fvFunc)							loader->get("glProgramUniformMatrix2x4fvEXT");
+	gl->programUniformMatrix3dv							= (glProgramUniformMatrix3dvFunc)							loader->get("glProgramUniformMatrix3dvEXT");
+	gl->programUniformMatrix3fv							= (glProgramUniformMatrix3fvFunc)							loader->get("glProgramUniformMatrix3fvEXT");
+	gl->programUniformMatrix3x2dv						= (glProgramUniformMatrix3x2dvFunc)							loader->get("glProgramUniformMatrix3x2dvEXT");
+	gl->programUniformMatrix3x2fv						= (glProgramUniformMatrix3x2fvFunc)							loader->get("glProgramUniformMatrix3x2fvEXT");
+	gl->programUniformMatrix3x4dv						= (glProgramUniformMatrix3x4dvFunc)							loader->get("glProgramUniformMatrix3x4dvEXT");
+	gl->programUniformMatrix3x4fv						= (glProgramUniformMatrix3x4fvFunc)							loader->get("glProgramUniformMatrix3x4fvEXT");
+	gl->programUniformMatrix4dv							= (glProgramUniformMatrix4dvFunc)							loader->get("glProgramUniformMatrix4dvEXT");
+	gl->programUniformMatrix4fv							= (glProgramUniformMatrix4fvFunc)							loader->get("glProgramUniformMatrix4fvEXT");
+	gl->programUniformMatrix4x2dv						= (glProgramUniformMatrix4x2dvFunc)							loader->get("glProgramUniformMatrix4x2dvEXT");
+	gl->programUniformMatrix4x2fv						= (glProgramUniformMatrix4x2fvFunc)							loader->get("glProgramUniformMatrix4x2fvEXT");
+	gl->programUniformMatrix4x3dv						= (glProgramUniformMatrix4x3dvFunc)							loader->get("glProgramUniformMatrix4x3dvEXT");
+	gl->programUniformMatrix4x3fv						= (glProgramUniformMatrix4x3fvFunc)							loader->get("glProgramUniformMatrix4x3fvEXT");
+	gl->pushClientAttribDefaultEXT						= (glPushClientAttribDefaultEXTFunc)						loader->get("glPushClientAttribDefaultEXT");
+	gl->textureBuffer									= (glTextureBufferFunc)										loader->get("glTextureBufferEXT");
+	gl->textureBufferRange								= (glTextureBufferRangeFunc)								loader->get("glTextureBufferRangeEXT");
+	gl->textureImage1DEXT								= (glTextureImage1DEXTFunc)									loader->get("glTextureImage1DEXT");
+	gl->textureImage2DEXT								= (glTextureImage2DEXTFunc)									loader->get("glTextureImage2DEXT");
+	gl->textureImage3DEXT								= (glTextureImage3DEXTFunc)									loader->get("glTextureImage3DEXT");
+	gl->texturePageCommitmentEXT						= (glTexturePageCommitmentEXTFunc)							loader->get("glTexturePageCommitmentEXT");
+	gl->textureParameterIiv								= (glTextureParameterIivFunc)								loader->get("glTextureParameterIivEXT");
+	gl->textureParameterIuiv							= (glTextureParameterIuivFunc)								loader->get("glTextureParameterIuivEXT");
+	gl->textureParameterf								= (glTextureParameterfFunc)									loader->get("glTextureParameterfEXT");
+	gl->textureParameterfv								= (glTextureParameterfvFunc)								loader->get("glTextureParameterfvEXT");
+	gl->textureParameteri								= (glTextureParameteriFunc)									loader->get("glTextureParameteriEXT");
+	gl->textureParameteriv								= (glTextureParameterivFunc)								loader->get("glTextureParameterivEXT");
+	gl->textureRenderbufferEXT							= (glTextureRenderbufferEXTFunc)							loader->get("glTextureRenderbufferEXT");
+	gl->textureStorage1DEXT								= (glTextureStorage1DEXTFunc)								loader->get("glTextureStorage1DEXT");
+	gl->textureStorage2DEXT								= (glTextureStorage2DEXTFunc)								loader->get("glTextureStorage2DEXT");
+	gl->textureStorage2DMultisample						= (glTextureStorage2DMultisampleFunc)						loader->get("glTextureStorage2DMultisampleEXT");
+	gl->textureStorage3DEXT								= (glTextureStorage3DEXTFunc)								loader->get("glTextureStorage3DEXT");
+	gl->textureStorage3DMultisample						= (glTextureStorage3DMultisampleFunc)						loader->get("glTextureStorage3DMultisampleEXT");
+	gl->textureSubImage1DEXT							= (glTextureSubImage1DEXTFunc)								loader->get("glTextureSubImage1DEXT");
+	gl->textureSubImage2DEXT							= (glTextureSubImage2DEXTFunc)								loader->get("glTextureSubImage2DEXT");
+	gl->textureSubImage3DEXT							= (glTextureSubImage3DEXTFunc)								loader->get("glTextureSubImage3DEXT");
+	gl->unmapNamedBuffer								= (glUnmapNamedBufferFunc)									loader->get("glUnmapNamedBufferEXT");
+	gl->vertexArrayBindVertexBufferEXT					= (glVertexArrayBindVertexBufferEXTFunc)					loader->get("glVertexArrayBindVertexBufferEXT");
+	gl->vertexArrayColorOffsetEXT						= (glVertexArrayColorOffsetEXTFunc)							loader->get("glVertexArrayColorOffsetEXT");
+	gl->vertexArrayEdgeFlagOffsetEXT					= (glVertexArrayEdgeFlagOffsetEXTFunc)						loader->get("glVertexArrayEdgeFlagOffsetEXT");
+	gl->vertexArrayFogCoordOffsetEXT					= (glVertexArrayFogCoordOffsetEXTFunc)						loader->get("glVertexArrayFogCoordOffsetEXT");
+	gl->vertexArrayIndexOffsetEXT						= (glVertexArrayIndexOffsetEXTFunc)							loader->get("glVertexArrayIndexOffsetEXT");
+	gl->vertexArrayMultiTexCoordOffsetEXT				= (glVertexArrayMultiTexCoordOffsetEXTFunc)					loader->get("glVertexArrayMultiTexCoordOffsetEXT");
+	gl->vertexArrayNormalOffsetEXT						= (glVertexArrayNormalOffsetEXTFunc)						loader->get("glVertexArrayNormalOffsetEXT");
+	gl->vertexArraySecondaryColorOffsetEXT				= (glVertexArraySecondaryColorOffsetEXTFunc)				loader->get("glVertexArraySecondaryColorOffsetEXT");
+	gl->vertexArrayTexCoordOffsetEXT					= (glVertexArrayTexCoordOffsetEXTFunc)						loader->get("glVertexArrayTexCoordOffsetEXT");
+	gl->vertexArrayVertexAttribBindingEXT				= (glVertexArrayVertexAttribBindingEXTFunc)					loader->get("glVertexArrayVertexAttribBindingEXT");
+	gl->vertexArrayVertexAttribDivisorEXT				= (glVertexArrayVertexAttribDivisorEXTFunc)					loader->get("glVertexArrayVertexAttribDivisorEXT");
+	gl->vertexArrayVertexAttribFormatEXT				= (glVertexArrayVertexAttribFormatEXTFunc)					loader->get("glVertexArrayVertexAttribFormatEXT");
+	gl->vertexArrayVertexAttribIFormatEXT				= (glVertexArrayVertexAttribIFormatEXTFunc)					loader->get("glVertexArrayVertexAttribIFormatEXT");
+	gl->vertexArrayVertexAttribIOffsetEXT				= (glVertexArrayVertexAttribIOffsetEXTFunc)					loader->get("glVertexArrayVertexAttribIOffsetEXT");
+	gl->vertexArrayVertexAttribLFormatEXT				= (glVertexArrayVertexAttribLFormatEXTFunc)					loader->get("glVertexArrayVertexAttribLFormatEXT");
+	gl->vertexArrayVertexAttribLOffsetEXT				= (glVertexArrayVertexAttribLOffsetEXTFunc)					loader->get("glVertexArrayVertexAttribLOffsetEXT");
+	gl->vertexArrayVertexAttribOffsetEXT				= (glVertexArrayVertexAttribOffsetEXTFunc)					loader->get("glVertexArrayVertexAttribOffsetEXT");
+	gl->vertexArrayVertexBindingDivisorEXT				= (glVertexArrayVertexBindingDivisorEXTFunc)				loader->get("glVertexArrayVertexBindingDivisorEXT");
+	gl->vertexArrayVertexOffsetEXT						= (glVertexArrayVertexOffsetEXTFunc)						loader->get("glVertexArrayVertexOffsetEXT");
+}
+
 if (de::contains(extSet, "GL_EXT_debug_marker"))
 {
 	gl->insertEventMarkerEXT	= (glInsertEventMarkerEXTFunc)	loader->get("glInsertEventMarkerEXT");