Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.1 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2015 The Android Open Source Project
      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 Negative Shader Image Load Store Tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fNegativeShaderImageLoadStoreTests.hpp"
     25 
     26 #include "deUniquePtr.hpp"
     27 
     28 #include "glwEnums.hpp"
     29 
     30 #include "gluShaderProgram.hpp"
     31 
     32 #include "glsTextureTestUtil.hpp"
     33 
     34 #include "tcuStringTemplate.hpp"
     35 #include "tcuTexture.hpp"
     36 #include "tcuTestLog.hpp"
     37 
     38 namespace deqp
     39 {
     40 namespace gles31
     41 {
     42 namespace Functional
     43 {
     44 namespace NegativeTestShared
     45 {
     46 namespace
     47 {
     48 
     49 enum MemoryQualifier
     50 {
     51 	MEMORY_NONE = 0,
     52 	MEMORY_READONLY,
     53 	MEMORY_WRITEONLY,
     54 	MEMORY_BOTH,
     55 
     56 	MEMORY_LAST
     57 };
     58 
     59 enum ImageOperation
     60 {
     61 	IMAGE_OPERATION_STORE = 0,
     62 	IMAGE_OPERATION_LOAD,
     63 	IMAGE_OPERATION_ATOMIC_ADD,
     64 	IMAGE_OPERATION_ATOMIC_MIN,
     65 	IMAGE_OPERATION_ATOMIC_MAX,
     66 	IMAGE_OPERATION_ATOMIC_AND,
     67 	IMAGE_OPERATION_ATOMIC_OR,
     68 	IMAGE_OPERATION_ATOMIC_XOR,
     69 	IMAGE_OPERATION_ATOMIC_EXCHANGE,
     70 	IMAGE_OPERATION_ATOMIC_COMP_SWAP,
     71 
     72 	IMAGE_OPERATION_LAST
     73 };
     74 
     75 static const glu::ShaderType s_shaders[] =
     76 {
     77 	glu::SHADERTYPE_VERTEX,
     78 	glu::SHADERTYPE_FRAGMENT,
     79 	glu::SHADERTYPE_GEOMETRY,
     80 	glu::SHADERTYPE_TESSELLATION_CONTROL,
     81 	glu::SHADERTYPE_TESSELLATION_EVALUATION,
     82 	glu::SHADERTYPE_COMPUTE
     83 };
     84 
     85 static const gls::TextureTestUtil::TextureType s_imageTypes[] =
     86 {
     87 	gls::TextureTestUtil::TEXTURETYPE_2D,
     88 	gls::TextureTestUtil::TEXTURETYPE_3D,
     89 	gls::TextureTestUtil::TEXTURETYPE_CUBE,
     90 	gls::TextureTestUtil::TEXTURETYPE_2D_ARRAY,
     91 	gls::TextureTestUtil::TEXTURETYPE_BUFFER,
     92 	gls::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY
     93 };
     94 
     95 std::string getShaderImageLayoutQualifier (const tcu::TextureFormat& format)
     96 {
     97 	std::ostringstream qualifier;
     98 
     99 	switch (format.order)
    100 	{
    101 		case tcu::TextureFormat::RGBA:	qualifier << "rgba";	break;
    102 		case tcu::TextureFormat::R:		qualifier << "r";		break;
    103 		default:
    104 			DE_ASSERT(false);
    105 			return std::string("");
    106 	}
    107 
    108 	switch (format.type)
    109 	{
    110 		case tcu::TextureFormat::FLOAT: 			qualifier << "32f";			break;
    111 		case tcu::TextureFormat::HALF_FLOAT: 		qualifier << "16f";			break;
    112 		case tcu::TextureFormat::UNORM_INT8: 		qualifier << "8";			break;
    113 		case tcu::TextureFormat::SNORM_INT8: 		qualifier << "8_snorm";		break;
    114 		case tcu::TextureFormat::SIGNED_INT32: 		qualifier << "32i";			break;
    115 		case tcu::TextureFormat::SIGNED_INT16: 		qualifier << "16i";			break;
    116 		case tcu::TextureFormat::SIGNED_INT8: 		qualifier << "8i";			break;
    117 		case tcu::TextureFormat::UNSIGNED_INT32: 	qualifier << "32ui";		break;
    118 		case tcu::TextureFormat::UNSIGNED_INT16: 	qualifier << "16ui";		break;
    119 		case tcu::TextureFormat::UNSIGNED_INT8: 	qualifier << "8ui";			break;
    120 		default:
    121 			DE_ASSERT(false);
    122 			return std::string("");
    123 	}
    124 
    125 	return qualifier.str();
    126 }
    127 
    128 std::string getShaderImageTypeDeclaration (const tcu::TextureFormat& format, gls::TextureTestUtil::TextureType imageType)
    129 {
    130 	std::ostringstream declaration;
    131 
    132 	switch (format.type)
    133 	{
    134 		case tcu::TextureFormat::FLOAT:
    135 		case tcu::TextureFormat::HALF_FLOAT:
    136 		case tcu::TextureFormat::UNORM_INT8:
    137 		case tcu::TextureFormat::SNORM_INT8: 		declaration << "";		break;
    138 
    139 		case tcu::TextureFormat::SIGNED_INT32:
    140 		case tcu::TextureFormat::SIGNED_INT16:
    141 		case tcu::TextureFormat::SIGNED_INT8:		declaration << "i";		break;
    142 
    143 		case tcu::TextureFormat::UNSIGNED_INT32:
    144 		case tcu::TextureFormat::UNSIGNED_INT16:
    145 		case tcu::TextureFormat::UNSIGNED_INT8:		declaration << "u";		break;
    146 
    147 		default:
    148 			DE_ASSERT(false);
    149 			return std::string("");
    150 	}
    151 
    152 	declaration << "image";
    153 
    154 	switch(imageType)
    155 	{
    156 		case gls::TextureTestUtil::TEXTURETYPE_2D:			declaration << "2D";			break;
    157 		case gls::TextureTestUtil::TEXTURETYPE_3D:			declaration << "3D";			break;
    158 		case gls::TextureTestUtil::TEXTURETYPE_CUBE:		declaration << "Cube";			break;
    159 		case gls::TextureTestUtil::TEXTURETYPE_2D_ARRAY:	declaration << "2DArray";		break;
    160 		case gls::TextureTestUtil::TEXTURETYPE_BUFFER:		declaration << "Buffer";		break;
    161 		case gls::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:	declaration << "CubeArray";		break;
    162 		default:
    163 			DE_ASSERT(false);
    164 			return std::string("");
    165 	}
    166 
    167 	return declaration.str();
    168 }
    169 
    170 std::string getShaderImageTypeExtensionString (gls::TextureTestUtil::TextureType imageType)
    171 {
    172 	std::string extension;
    173 
    174 	switch(imageType)
    175 	{
    176 		case gls::TextureTestUtil::TEXTURETYPE_2D:
    177 		case gls::TextureTestUtil::TEXTURETYPE_3D:
    178 		case gls::TextureTestUtil::TEXTURETYPE_CUBE:
    179 		case gls::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
    180 			extension = "";
    181 			break;
    182 
    183 		case gls::TextureTestUtil::TEXTURETYPE_BUFFER:
    184 			extension = "#extension GL_EXT_texture_buffer : enable";
    185 			break;
    186 
    187 		case gls::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:
    188 			extension = "#extension GL_EXT_texture_cube_map_array : enable";
    189 			break;
    190 
    191 		default:
    192 			DE_ASSERT(false);
    193 			return std::string("");
    194 	}
    195 
    196 	return extension;
    197 }
    198 
    199 std::string getShaderImageParamP (gls::TextureTestUtil::TextureType imageType)
    200 {
    201 	switch(imageType)
    202 	{
    203 		case gls::TextureTestUtil::TEXTURETYPE_2D:
    204 			return "ivec2(1, 1)";
    205 
    206 		case gls::TextureTestUtil::TEXTURETYPE_3D:
    207 		case gls::TextureTestUtil::TEXTURETYPE_CUBE:
    208 		case gls::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
    209 		case gls::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:
    210 			return "ivec3(1, 1, 1)";
    211 
    212 		case gls::TextureTestUtil::TEXTURETYPE_BUFFER:
    213 			return "1";
    214 
    215 		default:
    216 			DE_ASSERT(false);
    217 			return std::string("");
    218 	}
    219 }
    220 
    221 std::string getOtherFunctionArguments (const tcu::TextureFormat& format, ImageOperation function)
    222 {
    223 	std::ostringstream data;
    224 	data << ", ";
    225 
    226 	bool isFloat = false;
    227 
    228 	switch(format.type)
    229 	{
    230 		case tcu::TextureFormat::FLOAT:
    231 		case tcu::TextureFormat::HALF_FLOAT:
    232 		case tcu::TextureFormat::UNORM_INT8:
    233 		case tcu::TextureFormat::SNORM_INT8:
    234 			data << "";
    235 			isFloat = true;
    236 			break;
    237 
    238 		case tcu::TextureFormat::SIGNED_INT32:
    239 		case tcu::TextureFormat::SIGNED_INT16:
    240 		case tcu::TextureFormat::SIGNED_INT8:
    241 			data << "i";
    242 			break;
    243 
    244 		case tcu::TextureFormat::UNSIGNED_INT32:
    245 		case tcu::TextureFormat::UNSIGNED_INT16:
    246 		case tcu::TextureFormat::UNSIGNED_INT8:
    247 			data << "u";
    248 			break;
    249 
    250 		default:
    251 			DE_ASSERT(false);
    252 			return std::string("");
    253 	}
    254 
    255 	switch (function)
    256 	{
    257 		case IMAGE_OPERATION_LOAD:
    258 			return "";
    259 
    260 		case IMAGE_OPERATION_STORE:
    261 			data << "vec4(1, 1, 1, 1)";
    262 			break;
    263 
    264 		case IMAGE_OPERATION_ATOMIC_ADD:
    265 		case IMAGE_OPERATION_ATOMIC_MIN:
    266 		case IMAGE_OPERATION_ATOMIC_MAX:
    267 		case IMAGE_OPERATION_ATOMIC_AND:
    268 		case IMAGE_OPERATION_ATOMIC_OR:
    269 		case IMAGE_OPERATION_ATOMIC_XOR:
    270 			return ", 1";
    271 
    272 		case IMAGE_OPERATION_ATOMIC_EXCHANGE:
    273 			return isFloat ? ", 1.0" : ", 1";
    274 
    275 		case IMAGE_OPERATION_ATOMIC_COMP_SWAP:
    276 			return ", 1, 1";
    277 
    278 		default:
    279 			DE_ASSERT(false);
    280 			return std::string("");
    281 	}
    282 	return data.str();
    283 }
    284 
    285 std::string getMemoryQualifier (MemoryQualifier memory)
    286 {
    287 	switch (memory)
    288 	{
    289 		case MEMORY_NONE:
    290 			return std::string("");
    291 
    292 		case MEMORY_WRITEONLY:
    293 			return std::string("writeonly");
    294 
    295 		case MEMORY_READONLY:
    296 			return std::string("readonly");
    297 
    298 		case MEMORY_BOTH:
    299 			return std::string("writeonly readonly");
    300 
    301 		default:
    302 			DE_ASSERT(DE_FALSE);
    303 	}
    304 
    305 	return std::string("");
    306 }
    307 
    308 std::string getShaderImageFunctionExtensionString (ImageOperation function)
    309 {
    310 	switch (function)
    311 	{
    312 		case IMAGE_OPERATION_STORE:
    313 		case IMAGE_OPERATION_LOAD:
    314 			return std::string("");
    315 
    316 		case IMAGE_OPERATION_ATOMIC_ADD:
    317 		case IMAGE_OPERATION_ATOMIC_MIN:
    318 		case IMAGE_OPERATION_ATOMIC_MAX:
    319 		case IMAGE_OPERATION_ATOMIC_AND:
    320 		case IMAGE_OPERATION_ATOMIC_OR:
    321 		case IMAGE_OPERATION_ATOMIC_XOR:
    322 		case IMAGE_OPERATION_ATOMIC_EXCHANGE:
    323 		case IMAGE_OPERATION_ATOMIC_COMP_SWAP:
    324 			return std::string("#extension GL_OES_shader_image_atomic : enable");
    325 
    326 		default:
    327 			DE_ASSERT(DE_FALSE);
    328 	}
    329 	return std::string("");
    330 }
    331 
    332 std::string getFunctionName (ImageOperation function)
    333 {
    334 	switch (function)
    335 	{
    336 		case IMAGE_OPERATION_STORE:				return std::string("imageStore");
    337 		case IMAGE_OPERATION_LOAD:				return std::string("imageLoad");
    338 		case IMAGE_OPERATION_ATOMIC_ADD:		return std::string("imageAtomicAdd");
    339 		case IMAGE_OPERATION_ATOMIC_MIN:		return std::string("imageAtomicMin");
    340 		case IMAGE_OPERATION_ATOMIC_MAX:		return std::string("imageAtomicMax");
    341 		case IMAGE_OPERATION_ATOMIC_AND:		return std::string("imageAtomicAnd");
    342 		case IMAGE_OPERATION_ATOMIC_OR:			return std::string("imageAtomicOr");
    343 		case IMAGE_OPERATION_ATOMIC_XOR:		return std::string("imageAtomicXor");
    344 		case IMAGE_OPERATION_ATOMIC_EXCHANGE:	return std::string("imageAtomicExchange");
    345 		case IMAGE_OPERATION_ATOMIC_COMP_SWAP:	return std::string("imageAtomicCompSwap");
    346 		default:
    347 			DE_ASSERT(DE_FALSE);
    348 	}
    349 	return std::string("");
    350 }
    351 
    352 std::string generateShaderSource (ImageOperation function, MemoryQualifier memory, gls::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format, glu::ShaderType shaderType)
    353 {
    354 	const char* shaderTemplate = 	"${GLSL_VERSION_DECL}\n"
    355 									"${GLSL_TYPE_EXTENSION}\n"
    356 									"${GLSL_FUNCTION_EXTENSION}\n"
    357 									"${GEOMETRY_SHADER_LAYOUT}\n"
    358 									"layout(${LAYOUT_FORMAT}, binding = 0) highp uniform ${MEMORY_QUALIFIER} ${IMAGE_TYPE} u_img0;\n"
    359 									"void main(void)\n"
    360 									"{\n"
    361 									" ${FUNCTION_NAME}(u_img0, ${IMAGE_PARAM_P}${FUNCTION_ARGUMENTS});\n"
    362 									"}\n";
    363 
    364 	std::map<std::string, std::string> params;
    365 
    366 	params["GLSL_VERSION_DECL"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
    367 	params["GLSL_TYPE_EXTENSION"] = getShaderImageTypeExtensionString(imageType);
    368 	params["GLSL_FUNCTION_EXTENSION"] = getShaderImageFunctionExtensionString(function);
    369 	params["GEOMETRY_SHADER_LAYOUT"] = getGLShaderType(shaderType) == GL_GEOMETRY_SHADER ? "layout(max_vertices = 3) out;" : "";
    370 	params["LAYOUT_FORMAT"] = getShaderImageLayoutQualifier(format);
    371 	params["MEMORY_QUALIFIER"] = getMemoryQualifier(memory);
    372 	params["IMAGE_TYPE"] = getShaderImageTypeDeclaration(format, imageType);
    373 	params["FUNCTION_NAME"] = getFunctionName(function);
    374 	params["IMAGE_PARAM_P"] = getShaderImageParamP(imageType);
    375 	params["FUNCTION_ARGUMENTS"] = getOtherFunctionArguments(format, function);
    376 
    377 	return tcu::StringTemplate(shaderTemplate).specialize(params);
    378 }
    379 
    380 void testShader (NegativeTestContext& ctx, ImageOperation function, MemoryQualifier memory, gls::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format)
    381 {
    382 	tcu::TestLog& log = ctx.getLog();
    383 	ctx.beginSection(getFunctionName(function) + " " + getMemoryQualifier(memory) + " " + getShaderImageLayoutQualifier(format));
    384 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaders); ndx++)
    385 	{
    386 		if (ctx.isShaderSupported(s_shaders[ndx]))
    387 		{
    388 			ctx.beginSection(std::string("Verify shader: ") + glu::getShaderTypeName(s_shaders[ndx]));
    389 			std::string 				shaderSource(generateShaderSource(function, memory, imageType, format, s_shaders[ndx]));
    390 			const glu::ShaderProgram	program(ctx.getRenderContext(), glu::ProgramSources() << glu::ShaderSource(s_shaders[ndx], shaderSource));
    391 			if (program.getShaderInfo(s_shaders[ndx]).compileOk)
    392 			{
    393 				log << program;
    394 				log << tcu::TestLog::Message << "Expected program to fail, but compilation passed." << tcu::TestLog::EndMessage;
    395 				ctx.fail("Shader was not expected to compile.");
    396 			}
    397 			ctx.endSection();
    398 		}
    399 	}
    400 	ctx.endSection();
    401 }
    402 
    403 void image_store (NegativeTestContext& ctx)
    404 {
    405 	const tcu::TextureFormat formats[] =
    406 	{
    407 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::FLOAT),
    408 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::HALF_FLOAT),
    409 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::FLOAT),
    410 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8),
    411 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SNORM_INT8),
    412 
    413 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT32),
    414 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT16),
    415 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT8),
    416 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT32),
    417 
    418 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT32),
    419 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT16),
    420 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT8),
    421 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::UNSIGNED_INT32)
    422 	};
    423 
    424 	const MemoryQualifier memoryOptions[] =
    425 	{
    426 		MEMORY_READONLY,
    427 		MEMORY_BOTH
    428 	};
    429 
    430 	ctx.beginSection("It is an error to pass a readonly image to imageStore.");
    431 	for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
    432 	{
    433 		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
    434 		{
    435 			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++typeNdx)
    436 			{
    437 				testShader(ctx, IMAGE_OPERATION_STORE, memoryOptions[memoryNdx], s_imageTypes[typeNdx], formats[fmtNdx]);
    438 			}
    439 		}
    440 	}
    441 	ctx.endSection();
    442 }
    443 
    444 void image_load (NegativeTestContext& ctx)
    445 {
    446 	const tcu::TextureFormat formats[] =
    447 	{
    448 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::FLOAT),
    449 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::HALF_FLOAT),
    450 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::FLOAT),
    451 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8),
    452 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SNORM_INT8),
    453 
    454 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT32),
    455 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT16),
    456 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT8),
    457 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT32),
    458 
    459 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT32),
    460 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT16),
    461 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT8),
    462 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::UNSIGNED_INT32)
    463 	};
    464 
    465 	const MemoryQualifier memoryOptions[] =
    466 	{
    467 		MEMORY_WRITEONLY,
    468 		MEMORY_BOTH
    469 	};
    470 
    471 	ctx.beginSection("It is an error to pass a writeonly image to imageLoad.");
    472 	for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
    473 	{
    474 		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
    475 		{
    476 			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++typeNdx)
    477 			{
    478 				testShader(ctx, IMAGE_OPERATION_LOAD, memoryOptions[memoryNdx], s_imageTypes[typeNdx], formats[fmtNdx]);
    479 			}
    480 		}
    481 	}
    482 	ctx.endSection();
    483 }
    484 
    485 void image_atomic (NegativeTestContext& ctx)
    486 {
    487 	const tcu::TextureFormat formats[] =
    488 	{
    489 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT32),
    490 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT16),
    491 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT8),
    492 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT32),
    493 
    494 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT32),
    495 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT16),
    496 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT8),
    497 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::UNSIGNED_INT32)
    498 	};
    499 
    500 	const MemoryQualifier memoryOptions[] =
    501 	{
    502 		MEMORY_READONLY,
    503 		MEMORY_WRITEONLY,
    504 		MEMORY_BOTH
    505 	};
    506 
    507 	const ImageOperation imageOperations[] =
    508 	{
    509 		IMAGE_OPERATION_ATOMIC_ADD,
    510 		IMAGE_OPERATION_ATOMIC_MIN,
    511 		IMAGE_OPERATION_ATOMIC_MAX,
    512 		IMAGE_OPERATION_ATOMIC_AND,
    513 		IMAGE_OPERATION_ATOMIC_OR,
    514 		IMAGE_OPERATION_ATOMIC_XOR,
    515 		IMAGE_OPERATION_ATOMIC_COMP_SWAP
    516 	};
    517 
    518 	ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*.");
    519 	for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
    520 	{
    521 		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
    522 		{
    523 			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++typeNdx)
    524 			{
    525 				for (int functionNdx = 0; functionNdx < DE_LENGTH_OF_ARRAY(imageOperations); ++functionNdx)
    526 				{
    527 					testShader(ctx, imageOperations[functionNdx], memoryOptions[memoryNdx], s_imageTypes[typeNdx], formats[fmtNdx]);
    528 				}
    529 			}
    530 		}
    531 	}
    532 	ctx.endSection();
    533 }
    534 
    535 void image_atomic_exchange (NegativeTestContext& ctx)
    536 {
    537 	const tcu::TextureFormat formats[] =
    538 	{
    539 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::FLOAT),
    540 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::HALF_FLOAT),
    541 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::FLOAT),
    542 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8),
    543 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SNORM_INT8),
    544 
    545 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT32),
    546 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT16),
    547 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::SIGNED_INT8),
    548 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::SIGNED_INT32),
    549 
    550 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT32),
    551 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT16),
    552 		tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNSIGNED_INT8),
    553 		tcu::TextureFormat(tcu::TextureFormat::R,		tcu::TextureFormat::UNSIGNED_INT32)
    554 	};
    555 
    556 	const MemoryQualifier memoryOptions[] =
    557 	{
    558 		MEMORY_READONLY,
    559 		MEMORY_WRITEONLY,
    560 		MEMORY_BOTH
    561 	};
    562 
    563 	ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*.");
    564 	for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
    565 	{
    566 		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
    567 		{
    568 			for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++typeNdx)
    569 			{
    570 				testShader(ctx, IMAGE_OPERATION_ATOMIC_EXCHANGE, memoryOptions[memoryNdx], s_imageTypes[typeNdx], formats[fmtNdx]);
    571 			}
    572 		}
    573 	}
    574 	ctx.endSection();
    575 }
    576 
    577 } // anonymous
    578 
    579 std::vector<FunctionContainer> getNegativeShaderImageLoadStoreTestFunctions (void)
    580 {
    581 	const FunctionContainer funcs[] =
    582 	{
    583 		{image_store,				"image_store",				"Test incorrect usage of imageStore()"			},
    584 		{image_load,				"image_load",				"Test incorrect usage of imageLoad()"			},
    585 		{image_atomic,				"image_atomic",				"Test incorrect usage of imageAtomic*()"		},
    586 		{image_atomic_exchange,		"image_atomic_exchange",	"Test incorrect usage of imageAtomicExchange()"	},
    587 	};
    588 
    589 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
    590 }
    591 
    592 } // NegativeTestShared
    593 } // Functional
    594 } // gles31
    595 } // deqp
    596