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