Add new files to Android.mk
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fNegativeShaderImageLoadStoreTests.cpp
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 glu::TextureTestUtil::TextureType s_imageTypes[] =
86 {
87         glu::TextureTestUtil::TEXTURETYPE_2D,
88         glu::TextureTestUtil::TEXTURETYPE_3D,
89         glu::TextureTestUtil::TEXTURETYPE_CUBE,
90         glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY,
91         glu::TextureTestUtil::TEXTURETYPE_BUFFER,
92         glu::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, glu::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 glu::TextureTestUtil::TEXTURETYPE_2D:                      declaration << "2D";                    break;
157                 case glu::TextureTestUtil::TEXTURETYPE_3D:                      declaration << "3D";                    break;
158                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:            declaration << "Cube";                  break;
159                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:        declaration << "2DArray";               break;
160                 case glu::TextureTestUtil::TEXTURETYPE_BUFFER:          declaration << "Buffer";                break;
161                 case glu::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 (glu::TextureTestUtil::TextureType imageType)
171 {
172         std::string extension;
173
174         switch(imageType)
175         {
176                 case glu::TextureTestUtil::TEXTURETYPE_2D:
177                 case glu::TextureTestUtil::TEXTURETYPE_3D:
178                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:
179                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
180                         extension = "";
181                         break;
182
183                 case glu::TextureTestUtil::TEXTURETYPE_BUFFER:
184                         extension = "#extension GL_EXT_texture_buffer : enable";
185                         break;
186
187                 case glu::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 (glu::TextureTestUtil::TextureType imageType)
200 {
201         switch(imageType)
202         {
203                 case glu::TextureTestUtil::TEXTURETYPE_2D:
204                         return "ivec2(1, 1)";
205
206                 case glu::TextureTestUtil::TEXTURETYPE_3D:
207                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:
208                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
209                 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:
210                         return "ivec3(1, 1, 1)";
211
212                 case glu::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, glu::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, glu::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