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