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
getShaderImageLayoutQualifier(const tcu::TextureFormat & format)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
getShaderImageTypeDeclaration(const tcu::TextureFormat & format,gls::TextureTestUtil::TextureType imageType)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
getShaderImageTypeExtensionString(gls::TextureTestUtil::TextureType imageType)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
getShaderImageParamP(gls::TextureTestUtil::TextureType imageType)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
getOtherFunctionArguments(const tcu::TextureFormat & format,ImageOperation function)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
getMemoryQualifier(MemoryQualifier memory)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
getShaderImageFunctionExtensionString(ImageOperation function)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
getFunctionName(ImageOperation function)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
generateShaderSource(ImageOperation function,MemoryQualifier memory,gls::TextureTestUtil::TextureType imageType,const tcu::TextureFormat & format,glu::ShaderType shaderType)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
testShader(NegativeTestContext & ctx,ImageOperation function,MemoryQualifier memory,gls::TextureTestUtil::TextureType imageType,const tcu::TextureFormat & format)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
image_store(NegativeTestContext & ctx)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
image_load(NegativeTestContext & ctx)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
image_atomic(NegativeTestContext & ctx)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
image_atomic_exchange(NegativeTestContext & ctx)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
getNegativeShaderImageLoadStoreTestFunctions(void)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