Merge aosp/upstream-vulkan-cts-1.0-dev into aosp/master
[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 std::string getShaderImageLayoutQualifier (const tcu::TextureFormat& format)
86 {
87         std::ostringstream qualifier;
88
89         switch (format.order)
90         {
91                 case tcu::TextureFormat::RGBA:  qualifier << "rgba";    break;
92                 case tcu::TextureFormat::R:             qualifier << "r";               break;
93                 default:
94                         DE_ASSERT(false);
95                         return std::string("");
96         }
97
98         switch (format.type)
99         {
100                 case tcu::TextureFormat::FLOAT:                         qualifier << "32f";                     break;
101                 case tcu::TextureFormat::HALF_FLOAT:            qualifier << "16f";                     break;
102                 case tcu::TextureFormat::UNORM_INT8:            qualifier << "8";                       break;
103                 case tcu::TextureFormat::SNORM_INT8:            qualifier << "8_snorm";         break;
104                 case tcu::TextureFormat::SIGNED_INT32:          qualifier << "32i";                     break;
105                 case tcu::TextureFormat::SIGNED_INT16:          qualifier << "16i";                     break;
106                 case tcu::TextureFormat::SIGNED_INT8:           qualifier << "8i";                      break;
107                 case tcu::TextureFormat::UNSIGNED_INT32:        qualifier << "32ui";            break;
108                 case tcu::TextureFormat::UNSIGNED_INT16:        qualifier << "16ui";            break;
109                 case tcu::TextureFormat::UNSIGNED_INT8:         qualifier << "8ui";                     break;
110                 default:
111                         DE_ASSERT(false);
112                         return std::string("");
113         }
114
115         return qualifier.str();
116 }
117
118 std::string getShaderImageTypeDeclaration (const tcu::TextureFormat& format, glu::TextureTestUtil::TextureType imageType)
119 {
120         std::ostringstream declaration;
121
122         switch (format.type)
123         {
124                 case tcu::TextureFormat::FLOAT:
125                 case tcu::TextureFormat::HALF_FLOAT:
126                 case tcu::TextureFormat::UNORM_INT8:
127                 case tcu::TextureFormat::SNORM_INT8:            declaration << "";              break;
128
129                 case tcu::TextureFormat::SIGNED_INT32:
130                 case tcu::TextureFormat::SIGNED_INT16:
131                 case tcu::TextureFormat::SIGNED_INT8:           declaration << "i";             break;
132
133                 case tcu::TextureFormat::UNSIGNED_INT32:
134                 case tcu::TextureFormat::UNSIGNED_INT16:
135                 case tcu::TextureFormat::UNSIGNED_INT8:         declaration << "u";             break;
136
137                 default:
138                         DE_ASSERT(false);
139                         return std::string("");
140         }
141
142         declaration << "image";
143
144         switch(imageType)
145         {
146                 case glu::TextureTestUtil::TEXTURETYPE_2D:                      declaration << "2D";                    break;
147                 case glu::TextureTestUtil::TEXTURETYPE_3D:                      declaration << "3D";                    break;
148                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:            declaration << "Cube";                  break;
149                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:        declaration << "2DArray";               break;
150                 case glu::TextureTestUtil::TEXTURETYPE_BUFFER:          declaration << "Buffer";                break;
151                 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:      declaration << "CubeArray";             break;
152                 default:
153                         DE_ASSERT(false);
154                         return std::string("");
155         }
156
157         return declaration.str();
158 }
159
160 std::string getShaderImageTypeExtensionString (glu::TextureTestUtil::TextureType imageType)
161 {
162         std::string extension;
163
164         switch(imageType)
165         {
166                 case glu::TextureTestUtil::TEXTURETYPE_2D:
167                 case glu::TextureTestUtil::TEXTURETYPE_3D:
168                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:
169                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
170                         extension = "";
171                         break;
172
173                 case glu::TextureTestUtil::TEXTURETYPE_BUFFER:
174                         extension = "#extension GL_EXT_texture_buffer : enable";
175                         break;
176
177                 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:
178                         extension = "#extension GL_EXT_texture_cube_map_array : enable";
179                         break;
180
181                 default:
182                         DE_ASSERT(false);
183                         return std::string("");
184         }
185
186         return extension;
187 }
188
189 std::string getShaderImageParamP (glu::TextureTestUtil::TextureType imageType)
190 {
191         switch(imageType)
192         {
193                 case glu::TextureTestUtil::TEXTURETYPE_2D:
194                         return "ivec2(1, 1)";
195
196                 case glu::TextureTestUtil::TEXTURETYPE_3D:
197                 case glu::TextureTestUtil::TEXTURETYPE_CUBE:
198                 case glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY:
199                 case glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY:
200                         return "ivec3(1, 1, 1)";
201
202                 case glu::TextureTestUtil::TEXTURETYPE_BUFFER:
203                         return "1";
204
205                 default:
206                         DE_ASSERT(false);
207                         return std::string("");
208         }
209 }
210
211 std::string getOtherFunctionArguments (const tcu::TextureFormat& format, ImageOperation function)
212 {
213         std::ostringstream data;
214         data << ", ";
215
216         bool isFloat = false;
217
218         switch(format.type)
219         {
220                 case tcu::TextureFormat::FLOAT:
221                 case tcu::TextureFormat::HALF_FLOAT:
222                 case tcu::TextureFormat::UNORM_INT8:
223                 case tcu::TextureFormat::SNORM_INT8:
224                         data << "";
225                         isFloat = true;
226                         break;
227
228                 case tcu::TextureFormat::SIGNED_INT32:
229                 case tcu::TextureFormat::SIGNED_INT16:
230                 case tcu::TextureFormat::SIGNED_INT8:
231                         data << "i";
232                         break;
233
234                 case tcu::TextureFormat::UNSIGNED_INT32:
235                 case tcu::TextureFormat::UNSIGNED_INT16:
236                 case tcu::TextureFormat::UNSIGNED_INT8:
237                         data << "u";
238                         break;
239
240                 default:
241                         DE_ASSERT(false);
242                         return std::string("");
243         }
244
245         switch (function)
246         {
247                 case IMAGE_OPERATION_LOAD:
248                         return "";
249
250                 case IMAGE_OPERATION_STORE:
251                         data << "vec4(1, 1, 1, 1)";
252                         break;
253
254                 case IMAGE_OPERATION_ATOMIC_ADD:
255                 case IMAGE_OPERATION_ATOMIC_MIN:
256                 case IMAGE_OPERATION_ATOMIC_MAX:
257                 case IMAGE_OPERATION_ATOMIC_AND:
258                 case IMAGE_OPERATION_ATOMIC_OR:
259                 case IMAGE_OPERATION_ATOMIC_XOR:
260                         return ", 1";
261
262                 case IMAGE_OPERATION_ATOMIC_EXCHANGE:
263                         return isFloat ? ", 1.0" : ", 1";
264
265                 case IMAGE_OPERATION_ATOMIC_COMP_SWAP:
266                         return ", 1, 1";
267
268                 default:
269                         DE_ASSERT(false);
270                         return std::string("");
271         }
272         return data.str();
273 }
274
275 std::string getMemoryQualifier (MemoryQualifier memory)
276 {
277         switch (memory)
278         {
279                 case MEMORY_NONE:
280                         return std::string("");
281
282                 case MEMORY_WRITEONLY:
283                         return std::string("writeonly");
284
285                 case MEMORY_READONLY:
286                         return std::string("readonly");
287
288                 case MEMORY_BOTH:
289                         return std::string("writeonly readonly");
290
291                 default:
292                         DE_ASSERT(DE_FALSE);
293         }
294
295         return std::string("");
296 }
297
298 std::string getShaderImageFunctionExtensionString (ImageOperation function)
299 {
300         switch (function)
301         {
302                 case IMAGE_OPERATION_STORE:
303                 case IMAGE_OPERATION_LOAD:
304                         return std::string("");
305
306                 case IMAGE_OPERATION_ATOMIC_ADD:
307                 case IMAGE_OPERATION_ATOMIC_MIN:
308                 case IMAGE_OPERATION_ATOMIC_MAX:
309                 case IMAGE_OPERATION_ATOMIC_AND:
310                 case IMAGE_OPERATION_ATOMIC_OR:
311                 case IMAGE_OPERATION_ATOMIC_XOR:
312                 case IMAGE_OPERATION_ATOMIC_EXCHANGE:
313                 case IMAGE_OPERATION_ATOMIC_COMP_SWAP:
314                         return std::string("#extension GL_OES_shader_image_atomic : enable");
315
316                 default:
317                         DE_ASSERT(DE_FALSE);
318         }
319         return std::string("");
320 }
321
322 std::string getFunctionName (ImageOperation function)
323 {
324         switch (function)
325         {
326                 case IMAGE_OPERATION_STORE:                             return std::string("imageStore");
327                 case IMAGE_OPERATION_LOAD:                              return std::string("imageLoad");
328                 case IMAGE_OPERATION_ATOMIC_ADD:                return std::string("imageAtomicAdd");
329                 case IMAGE_OPERATION_ATOMIC_MIN:                return std::string("imageAtomicMin");
330                 case IMAGE_OPERATION_ATOMIC_MAX:                return std::string("imageAtomicMax");
331                 case IMAGE_OPERATION_ATOMIC_AND:                return std::string("imageAtomicAnd");
332                 case IMAGE_OPERATION_ATOMIC_OR:                 return std::string("imageAtomicOr");
333                 case IMAGE_OPERATION_ATOMIC_XOR:                return std::string("imageAtomicXor");
334                 case IMAGE_OPERATION_ATOMIC_EXCHANGE:   return std::string("imageAtomicExchange");
335                 case IMAGE_OPERATION_ATOMIC_COMP_SWAP:  return std::string("imageAtomicCompSwap");
336                 default:
337                         DE_ASSERT(DE_FALSE);
338         }
339         return std::string("");
340 }
341
342 std::string generateShaderSource (ImageOperation function, MemoryQualifier memory, glu::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format, glu::ShaderType shaderType)
343 {
344         const char* shaderTemplate =    "${GLSL_VERSION_DECL}\n"
345                                                                         "${GLSL_TYPE_EXTENSION}\n"
346                                                                         "${GLSL_FUNCTION_EXTENSION}\n"
347                                                                         "${GEOMETRY_SHADER_LAYOUT}\n"
348                                                                         "layout(${LAYOUT_FORMAT}, binding = 0) highp uniform ${MEMORY_QUALIFIER} ${IMAGE_TYPE} u_img0;\n"
349                                                                         "void main(void)\n"
350                                                                         "{\n"
351                                                                         " ${FUNCTION_NAME}(u_img0, ${IMAGE_PARAM_P}${FUNCTION_ARGUMENTS});\n"
352                                                                         "}\n";
353
354         std::map<std::string, std::string> params;
355
356         params["GLSL_VERSION_DECL"] = getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
357         params["GLSL_TYPE_EXTENSION"] = getShaderImageTypeExtensionString(imageType);
358         params["GLSL_FUNCTION_EXTENSION"] = getShaderImageFunctionExtensionString(function);
359         params["GEOMETRY_SHADER_LAYOUT"] = getGLShaderType(shaderType) == GL_GEOMETRY_SHADER ? "layout(max_vertices = 3) out;" : "";
360         params["LAYOUT_FORMAT"] = getShaderImageLayoutQualifier(format);
361         params["MEMORY_QUALIFIER"] = getMemoryQualifier(memory);
362         params["IMAGE_TYPE"] = getShaderImageTypeDeclaration(format, imageType);
363         params["FUNCTION_NAME"] = getFunctionName(function);
364         params["IMAGE_PARAM_P"] = getShaderImageParamP(imageType);
365         params["FUNCTION_ARGUMENTS"] = getOtherFunctionArguments(format, function);
366
367         return tcu::StringTemplate(shaderTemplate).specialize(params);
368 }
369
370 void testShader (NegativeTestContext& ctx, ImageOperation function, MemoryQualifier memory, glu::TextureTestUtil::TextureType imageType, const tcu::TextureFormat& format)
371 {
372         tcu::TestLog& log = ctx.getLog();
373         ctx.beginSection(getFunctionName(function) + " " + getMemoryQualifier(memory) + " " + getShaderImageLayoutQualifier(format));
374         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaders); ndx++)
375         {
376                 if (ctx.isShaderSupported(s_shaders[ndx]))
377                 {
378                         ctx.beginSection(std::string("Verify shader: ") + glu::getShaderTypeName(s_shaders[ndx]));
379                         std::string                                     shaderSource(generateShaderSource(function, memory, imageType, format, s_shaders[ndx]));
380                         const glu::ShaderProgram        program(ctx.getRenderContext(), glu::ProgramSources() << glu::ShaderSource(s_shaders[ndx], shaderSource));
381                         if (program.getShaderInfo(s_shaders[ndx]).compileOk)
382                         {
383                                 log << program;
384                                 log << tcu::TestLog::Message << "Expected program to fail, but compilation passed." << tcu::TestLog::EndMessage;
385                                 ctx.fail("Shader was not expected to compile.");
386                         }
387                         ctx.endSection();
388                 }
389         }
390         ctx.endSection();
391 }
392
393 void image_store (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType)
394 {
395         const tcu::TextureFormat formats[] =
396         {
397                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::FLOAT),
398                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::HALF_FLOAT),
399                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::FLOAT),
400                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNORM_INT8),
401                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SNORM_INT8),
402
403                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT32),
404                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT16),
405                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT8),
406                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT32),
407
408                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT32),
409                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT16),
410                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT8),
411                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::UNSIGNED_INT32)
412         };
413
414         const MemoryQualifier memoryOptions[] =
415         {
416                 MEMORY_READONLY,
417                 MEMORY_BOTH
418         };
419
420         ctx.beginSection("It is an error to pass a readonly image to imageStore.");
421         for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
422         {
423                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
424                 {
425                         testShader(ctx, IMAGE_OPERATION_STORE, memoryOptions[memoryNdx], imageType, formats[fmtNdx]);
426                 }
427         }
428         ctx.endSection();
429 }
430
431 void image_load (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType)
432 {
433         const tcu::TextureFormat formats[] =
434         {
435                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::FLOAT),
436                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::HALF_FLOAT),
437                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::FLOAT),
438                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNORM_INT8),
439                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SNORM_INT8),
440
441                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT32),
442                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT16),
443                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT8),
444                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT32),
445
446                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT32),
447                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT16),
448                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT8),
449                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::UNSIGNED_INT32)
450         };
451
452         const MemoryQualifier memoryOptions[] =
453         {
454                 MEMORY_WRITEONLY,
455                 MEMORY_BOTH
456         };
457
458         ctx.beginSection("It is an error to pass a writeonly image to imageLoad.");
459         for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
460         {
461                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
462                 {
463                         testShader(ctx, IMAGE_OPERATION_LOAD, memoryOptions[memoryNdx], imageType, formats[fmtNdx]);
464                 }
465         }
466         ctx.endSection();
467 }
468
469 void image_atomic (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType)
470 {
471         const tcu::TextureFormat formats[] =
472         {
473                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT32),
474                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT16),
475                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT8),
476                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT32),
477
478                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT32),
479                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT16),
480                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT8),
481                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::UNSIGNED_INT32)
482         };
483
484         const MemoryQualifier memoryOptions[] =
485         {
486                 MEMORY_READONLY,
487                 MEMORY_WRITEONLY,
488                 MEMORY_BOTH
489         };
490
491         const ImageOperation imageOperations[] =
492         {
493                 IMAGE_OPERATION_ATOMIC_ADD,
494                 IMAGE_OPERATION_ATOMIC_MIN,
495                 IMAGE_OPERATION_ATOMIC_MAX,
496                 IMAGE_OPERATION_ATOMIC_AND,
497                 IMAGE_OPERATION_ATOMIC_OR,
498                 IMAGE_OPERATION_ATOMIC_XOR,
499                 IMAGE_OPERATION_ATOMIC_COMP_SWAP
500         };
501
502         ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*.");
503         for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
504         {
505                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
506                 {
507                         for (int functionNdx = 0; functionNdx < DE_LENGTH_OF_ARRAY(imageOperations); ++functionNdx)
508                         {
509                                 testShader(ctx, imageOperations[functionNdx], memoryOptions[memoryNdx], imageType, formats[fmtNdx]);
510                         }
511                 }
512         }
513         ctx.endSection();
514 }
515
516 void image_atomic_exchange (NegativeTestContext& ctx, glu::TextureTestUtil::TextureType imageType)
517 {
518         const tcu::TextureFormat formats[] =
519         {
520                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::FLOAT),
521                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::HALF_FLOAT),
522                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::FLOAT),
523                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNORM_INT8),
524                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SNORM_INT8),
525
526                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT32),
527                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT16),
528                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::SIGNED_INT8),
529                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::SIGNED_INT32),
530
531                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT32),
532                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT16),
533                 tcu::TextureFormat(tcu::TextureFormat::RGBA,    tcu::TextureFormat::UNSIGNED_INT8),
534                 tcu::TextureFormat(tcu::TextureFormat::R,               tcu::TextureFormat::UNSIGNED_INT32)
535         };
536
537         const MemoryQualifier memoryOptions[] =
538         {
539                 MEMORY_READONLY,
540                 MEMORY_WRITEONLY,
541                 MEMORY_BOTH
542         };
543
544         ctx.beginSection("It is an error to pass a writeonly and/or readonly image to imageAtomic*.");
545         for (int memoryNdx = 0; memoryNdx < DE_LENGTH_OF_ARRAY(memoryOptions); ++memoryNdx)
546         {
547                 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(formats); ++fmtNdx)
548                 {
549                         testShader(ctx, IMAGE_OPERATION_ATOMIC_EXCHANGE, memoryOptions[memoryNdx], imageType, formats[fmtNdx]);
550                 }
551         }
552         ctx.endSection();
553 }
554
555 // Re-routing function template for generating the standard negative
556 // test function signature with texture type added.
557
558 template <int Type>
559 void loadFuncWrapper (NegativeTestContext& ctx)
560 {
561         image_load(ctx, (glu::TextureTestUtil::TextureType)Type);
562 }
563
564 template <int Type>
565 void storeFuncWrapper (NegativeTestContext& ctx)
566 {
567         image_store(ctx, (glu::TextureTestUtil::TextureType)Type);
568 }
569
570 template <int Type>
571 void atomicFuncWrapper (NegativeTestContext& ctx)
572 {
573         image_atomic(ctx, (glu::TextureTestUtil::TextureType)Type);
574 }
575
576 template <int Type>
577 void atomicExchangeFuncWrapper (NegativeTestContext& ctx)
578 {
579         image_atomic_exchange(ctx, (glu::TextureTestUtil::TextureType)Type);
580 }
581
582 } // anonymous
583
584 // Set of texture types to create tests for.
585 #define CREATE_TEST_FUNC_PER_TEXTURE_TYPE(NAME, FUNC) const FunctionContainer NAME[] =                                                                  \
586         {                                                                                                                                                                                                                                       \
587                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_2D>,                    "texture_2d",   "Texture2D negative tests."},                   \
588                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_3D>,                    "texture_3d",   "Texture3D negative tests."},                   \
589                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_CUBE>,                  "cube",                 "Cube texture negative tests."},                \
590                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY>,              "2d_array",             "2D array texture negative tests."},    \
591                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_BUFFER>,                "buffer",               "Buffer negative tests."},                              \
592                 {FUNC<glu::TextureTestUtil::TEXTURETYPE_CUBE_ARRAY>,    "cube_array",   "Cube array texture negative tests."}   \
593         }
594
595 std::vector<FunctionContainer> getNegativeShaderImageLoadTestFunctions (void)
596 {
597         CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, loadFuncWrapper);
598         return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
599 }
600
601 std::vector<FunctionContainer> getNegativeShaderImageStoreTestFunctions (void)
602 {
603         CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, storeFuncWrapper);
604         return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
605 }
606
607 std::vector<FunctionContainer> getNegativeShaderImageAtomicTestFunctions (void)
608 {
609         CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, atomicFuncWrapper);
610         return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
611 }
612
613 std::vector<FunctionContainer> getNegativeShaderImageAtomicExchangeTestFunctions (void)
614 {
615         CREATE_TEST_FUNC_PER_TEXTURE_TYPE(funcs, atomicExchangeFuncWrapper);
616         return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
617 }
618
619 } // NegativeTestShared
620 } // Functional
621 } // gles31
622 } // deqp