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
getShaderImageLayoutQualifier(const tcu::TextureFormat & format)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
getShaderImageTypeDeclaration(const tcu::TextureFormat & format,glu::TextureTestUtil::TextureType imageType)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
getShaderImageTypeExtensionString(glu::TextureTestUtil::TextureType imageType)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
getShaderImageParamP(glu::TextureTestUtil::TextureType imageType)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
getOtherFunctionArguments(const tcu::TextureFormat & format,ImageOperation function)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
getMemoryQualifier(MemoryQualifier memory)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
getShaderImageFunctionExtensionString(ImageOperation function)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
getFunctionName(ImageOperation function)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
generateShaderSource(ImageOperation function,MemoryQualifier memory,glu::TextureTestUtil::TextureType imageType,const tcu::TextureFormat & format,glu::ShaderType shaderType)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
testShader(NegativeTestContext & ctx,ImageOperation function,MemoryQualifier memory,glu::TextureTestUtil::TextureType imageType,const tcu::TextureFormat & format)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
image_store(NegativeTestContext & ctx,glu::TextureTestUtil::TextureType imageType)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
image_load(NegativeTestContext & ctx,glu::TextureTestUtil::TextureType imageType)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
image_atomic(NegativeTestContext & ctx,glu::TextureTestUtil::TextureType imageType)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
image_atomic_exchange(NegativeTestContext & ctx,glu::TextureTestUtil::TextureType imageType)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>
loadFuncWrapper(NegativeTestContext & ctx)559 void loadFuncWrapper (NegativeTestContext& ctx)
560 {
561 image_load(ctx, (glu::TextureTestUtil::TextureType)Type);
562 }
563
564 template <int Type>
storeFuncWrapper(NegativeTestContext & ctx)565 void storeFuncWrapper (NegativeTestContext& ctx)
566 {
567 image_store(ctx, (glu::TextureTestUtil::TextureType)Type);
568 }
569
570 template <int Type>
atomicFuncWrapper(NegativeTestContext & ctx)571 void atomicFuncWrapper (NegativeTestContext& ctx)
572 {
573 image_atomic(ctx, (glu::TextureTestUtil::TextureType)Type);
574 }
575
576 template <int Type>
atomicExchangeFuncWrapper(NegativeTestContext & ctx)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
getNegativeShaderImageLoadTestFunctions(void)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
getNegativeShaderImageStoreTestFunctions(void)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
getNegativeShaderImageAtomicTestFunctions(void)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
getNegativeShaderImageAtomicExchangeTestFunctions(void)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
623