5efc4b52d1fc9f1e75f359dc0bcd042d4afafd91
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cShaderImageLoadStoreTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23
24 #include "gl4cShaderImageLoadStoreTests.hpp"
25 #include "gluContextInfo.hpp"
26 #include "glwEnums.hpp"
27 #include "tcuMatrix.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "tcuVectorUtil.hpp"
30 #include <assert.h>
31 #include <climits>
32 #include <cstdarg>
33 #include <deque>
34 #include <iomanip>
35 #include <map>
36 #include <sstream>
37 #include <tcuFloat.hpp>
38
39 namespace gl4cts
40 {
41 using namespace glw;
42
43 namespace
44 {
45 typedef tcu::Vec2  vec2;
46 typedef tcu::Vec4  vec4;
47 typedef tcu::IVec4 ivec4;
48 typedef tcu::UVec4 uvec4;
49 typedef tcu::Mat4  mat4;
50
51 class ShaderImageLoadStoreBase : public deqp::SubcaseBase
52 {
53         virtual std::string Title()
54         {
55                 return "";
56         }
57
58         virtual std::string Purpose()
59         {
60                 return "";
61         }
62
63         virtual std::string Method()
64         {
65                 return "";
66         }
67
68         virtual std::string PassCriteria()
69         {
70                 return "";
71         }
72
73 public:
74         bool SupportedInVS(int requiredVS)
75         {
76                 GLint imagesVS;
77                 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &imagesVS);
78                 if (imagesVS >= requiredVS)
79                         return true;
80                 else
81                 {
82                         std::ostringstream reason;
83                         reason << "Required " << requiredVS << " VS image uniforms but only " << imagesVS << " available."
84                                    << std::endl;
85                         OutputNotSupported(reason.str());
86                         return false;
87                 }
88         }
89
90         bool SupportedInTCS(int requiredTCS)
91         {
92                 GLint imagesTCS;
93                 glGetIntegerv(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, &imagesTCS);
94                 if (imagesTCS >= requiredTCS)
95                         return true;
96                 else
97                 {
98                         std::ostringstream reason;
99                         reason << "Required " << requiredTCS << " TCS image uniforms but only " << imagesTCS << " available."
100                                    << std::endl;
101                         OutputNotSupported(reason.str());
102                         return false;
103                 }
104         }
105
106         bool SupportedInTES(int requiredTES)
107         {
108                 GLint imagesTES;
109                 glGetIntegerv(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, &imagesTES);
110                 if (imagesTES >= requiredTES)
111                         return true;
112                 else
113                 {
114                         std::ostringstream reason;
115                         reason << "Required " << requiredTES << " TES image uniforms but only " << imagesTES << " available."
116                                    << std::endl;
117                         OutputNotSupported(reason.str());
118                         return false;
119                 }
120         }
121
122         bool SupportedInGS(int requiredGS)
123         {
124                 GLint imagesGS;
125                 glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &imagesGS);
126                 if (imagesGS >= requiredGS)
127                         return true;
128                 else
129                 {
130                         std::ostringstream reason;
131                         reason << "Required " << requiredGS << " GS image uniforms but only " << imagesGS << " available."
132                                    << std::endl;
133                         OutputNotSupported(reason.str());
134                         return false;
135                 }
136         }
137
138         bool SupportedInGeomStages(int required)
139         {
140                 return SupportedInVS(required) && SupportedInTCS(required) && SupportedInTES(required) &&
141                            SupportedInGS(required);
142         }
143
144         bool SupportedInStage(int stage, int required)
145         {
146                 switch (stage)
147                 {
148                 case 0:
149                         return SupportedInVS(required);
150                 case 1:
151                         return SupportedInTCS(required);
152                 case 2:
153                         return SupportedInTES(required);
154                 case 3:
155                         return SupportedInGS(required);
156                 default:
157                         return true;
158                 }
159         }
160
161         bool SupportedSamples(int required)
162         {
163                 int i;
164                 glGetIntegerv(GL_MAX_IMAGE_SAMPLES, &i);
165                 if (i >= required)
166                         return true;
167                 else
168                 {
169                         std::ostringstream reason;
170                         reason << "Required " << required << " image samples but only " << i << " available." << std::endl;
171                         OutputNotSupported(reason.str());
172                         return false;
173                 }
174         }
175
176         int getWindowWidth()
177         {
178                 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
179                 return renderTarget.getWidth();
180         }
181
182         int getWindowHeight()
183         {
184                 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
185                 return renderTarget.getHeight();
186         }
187
188         inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon)
189         {
190                 if (fabs(c0[0] - c1[0]) > epsilon[0])
191                         return false;
192                 if (fabs(c0[1] - c1[1]) > epsilon[1])
193                         return false;
194                 if (fabs(c0[2] - c1[2]) > epsilon[2])
195                         return false;
196                 if (fabs(c0[3] - c1[3]) > epsilon[3])
197                         return false;
198                 return true;
199         }
200
201         bool IsEqual(vec4 a, vec4 b)
202         {
203                 return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
204         }
205
206         bool Equal(const vec4& v0, const vec4& v1, GLenum internalformat)
207         {
208                 if (internalformat == GL_RGBA16_SNORM || internalformat == GL_RG16_SNORM || internalformat == GL_R16_SNORM)
209                 {
210                         return ColorEqual(v0, v1, vec4(0.0001f));
211                 }
212                 else if (internalformat == GL_RGBA8_SNORM || internalformat == GL_RG8_SNORM || internalformat == GL_R8_SNORM)
213                 {
214                         return ColorEqual(v0, v1, vec4(0.01f));
215                 }
216                 return (v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2]) && (v0[3] == v1[3]);
217         }
218
219         bool Equal(const ivec4& a, const ivec4& b, GLenum)
220         {
221                 return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
222         }
223
224         bool Equal(const uvec4& a, const uvec4& b, GLenum)
225         {
226                 return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
227         }
228
229         template <class T>
230         std::string ToString(T v)
231         {
232                 std::ostringstream s;
233                 s << "[";
234                 for (int i = 0; i < 4; ++i)
235                         s << v[i] << (i == 3 ? "" : ",");
236                 s << "]";
237                 return s.str();
238         }
239
240         bool ValidateReadBuffer(int x, int y, int w, int h, const vec4& expected)
241         {
242                 bool                                     status           = true;
243                 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
244                 const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
245                 vec4                                     g_color_eps  = vec4(
246                         1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
247                         1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
248
249                 std::vector<vec4> fb(w * h);
250                 glReadPixels(x, y, w, h, GL_RGBA, GL_FLOAT, &fb[0]);
251
252                 for (int yy = 0; yy < h; ++yy)
253                 {
254                         for (int xx = 0; xx < w; ++xx)
255                         {
256                                 const int idx = yy * w + xx;
257                                 if (!ColorEqual(fb[idx], expected, g_color_eps))
258                                 {
259                                         m_context.getTestContext().getLog()
260                                                 << tcu::TestLog::Message << "First bad color: " << ToString(fb[idx])
261                                                 << tcu::TestLog::EndMessage;
262                                         status = false;
263                                         return status;
264                                 }
265                         }
266                 }
267                 return status;
268         }
269
270         bool CompileShader(GLuint shader)
271         {
272                 glCompileShader(shader);
273
274                 GLint status;
275                 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
276                 if (status == GL_FALSE)
277                 {
278                         GLsizei length;
279                         GLchar  log[1024];
280                         glGetShaderInfoLog(shader, sizeof(log), &length, log);
281                         if (length > 1)
282                         {
283                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
284                                                                                                         << log << tcu::TestLog::EndMessage;
285                         }
286                         return false;
287                 }
288                 return true;
289         }
290
291         bool LinkProgram(GLuint program)
292         {
293                 glLinkProgram(program);
294
295                 GLint status;
296                 glGetProgramiv(program, GL_LINK_STATUS, &status);
297                 if (status == GL_FALSE)
298                 {
299                         GLsizei length;
300                         GLchar  log[1024];
301                         glGetProgramInfoLog(program, sizeof(log), &length, log);
302                         if (length > 1)
303                         {
304                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
305                                                                                                         << log << tcu::TestLog::EndMessage;
306                         }
307                         return false;
308                 }
309                 return true;
310         }
311
312         GLuint BuildProgram(const char* src_vs, const char* src_tcs, const char* src_tes, const char* src_gs,
313                                                 const char* src_fs, bool* result = NULL)
314         {
315                 const GLuint p = glCreateProgram();
316
317                 if (src_vs)
318                 {
319                         GLuint sh = glCreateShader(GL_VERTEX_SHADER);
320                         glAttachShader(p, sh);
321                         glDeleteShader(sh);
322                         glShaderSource(sh, 1, &src_vs, NULL);
323                         if (!CompileShader(sh))
324                         {
325                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_vs << tcu::TestLog::EndMessage;
326                                 if (result)
327                                         *result = false;
328                                 return p;
329                         }
330                 }
331                 if (src_tcs)
332                 {
333                         GLuint sh = glCreateShader(GL_TESS_CONTROL_SHADER);
334                         glAttachShader(p, sh);
335                         glDeleteShader(sh);
336                         glShaderSource(sh, 1, &src_tcs, NULL);
337                         if (!CompileShader(sh))
338                         {
339                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_tcs << tcu::TestLog::EndMessage;
340                                 if (result)
341                                         *result = false;
342                                 return p;
343                         }
344                 }
345                 if (src_tes)
346                 {
347                         GLuint sh = glCreateShader(GL_TESS_EVALUATION_SHADER);
348                         glAttachShader(p, sh);
349                         glDeleteShader(sh);
350                         glShaderSource(sh, 1, &src_tes, NULL);
351                         if (!CompileShader(sh))
352                         {
353                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_tes << tcu::TestLog::EndMessage;
354                                 if (result)
355                                         *result = false;
356                                 return p;
357                         }
358                 }
359                 if (src_gs)
360                 {
361                         GLuint sh = glCreateShader(GL_GEOMETRY_SHADER);
362                         glAttachShader(p, sh);
363                         glDeleteShader(sh);
364                         glShaderSource(sh, 1, &src_gs, NULL);
365                         if (!CompileShader(sh))
366                         {
367                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_gs << tcu::TestLog::EndMessage;
368                                 if (result)
369                                         *result = false;
370                                 return p;
371                         }
372                 }
373                 if (src_fs)
374                 {
375                         GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
376                         glAttachShader(p, sh);
377                         glDeleteShader(sh);
378                         glShaderSource(sh, 1, &src_fs, NULL);
379                         if (!CompileShader(sh))
380                         {
381                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_fs << tcu::TestLog::EndMessage;
382                                 if (result)
383                                         *result = false;
384                                 return p;
385                         }
386                 }
387                 if (!LinkProgram(p))
388                 {
389                         if (src_vs)
390                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_vs << tcu::TestLog::EndMessage;
391                         if (src_tcs)
392                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_tcs << tcu::TestLog::EndMessage;
393                         if (src_tes)
394                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_tes << tcu::TestLog::EndMessage;
395                         if (src_gs)
396                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_gs << tcu::TestLog::EndMessage;
397                         if (src_fs)
398                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << src_fs << tcu::TestLog::EndMessage;
399                         if (result)
400                                 *result = false;
401                         return p;
402                 }
403
404                 return p;
405         }
406
407         GLuint BuildShaderProgram(GLenum type, const char* src)
408         {
409                 const GLuint p = glCreateShaderProgramv(type, 1, &src);
410
411                 GLint status;
412                 glGetProgramiv(p, GL_LINK_STATUS, &status);
413                 if (status == GL_FALSE)
414                 {
415                         GLchar log[1024];
416                         glGetProgramInfoLog(p, sizeof(log), NULL, log);
417                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
418                                                                                                 << log << "\n"
419                                                                                                 << src << tcu::TestLog::EndMessage;
420                 }
421
422                 return p;
423         }
424
425         void CreateFullViewportQuad(GLuint* vao, GLuint* vbo, GLuint* ebo)
426         {
427                 assert(vao && vbo);
428
429                 // interleaved data (vertex, color0 (green), color1 (blue), color2 (red))
430                 const float v[] = {
431                         -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,  1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f,
432                         0.0f,  0.0f,  0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,  0.0f, 1.0f,
433                         1.0f,  0.0f,  0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,  0.0f, 0.0f, 1.0f, 1.0f, 0.0f,  0.0f,
434                 };
435                 glGenBuffers(1, vbo);
436                 glBindBuffer(GL_ARRAY_BUFFER, *vbo);
437                 glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
438                 glBindBuffer(GL_ARRAY_BUFFER, 0);
439
440                 if (ebo)
441                 {
442                         std::vector<GLushort> index_data(4);
443                         for (int i = 0; i < 4; ++i)
444                         {
445                                 index_data[i] = static_cast<GLushort>(i);
446                         }
447                         glGenBuffers(1, ebo);
448                         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo);
449                         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 4, &index_data[0], GL_STATIC_DRAW);
450                         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
451                 }
452
453                 glGenVertexArrays(1, vao);
454                 glBindVertexArray(*vao);
455                 glBindBuffer(GL_ARRAY_BUFFER, *vbo);
456                 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 11, 0);
457                 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 2));
458                 glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 5));
459                 glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 8));
460                 glBindBuffer(GL_ARRAY_BUFFER, 0);
461                 glEnableVertexAttribArray(0);
462                 glEnableVertexAttribArray(1);
463                 glEnableVertexAttribArray(2);
464                 glEnableVertexAttribArray(3);
465                 if (ebo)
466                 {
467                         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo);
468                 }
469                 glBindVertexArray(0);
470         }
471
472         std::string FormatEnumToString(GLenum e)
473         {
474                 switch (e)
475                 {
476                 case GL_RGBA32F:
477                         return "rgba32f";
478                 case GL_RGBA16F:
479                         return "rgba16f";
480                 case GL_RG32F:
481                         return "rg32f";
482                 case GL_RG16F:
483                         return "rg16f";
484                 case GL_R11F_G11F_B10F:
485                         return "r11f_g11f_b10f";
486                 case GL_R32F:
487                         return "r32f";
488                 case GL_R16F:
489                         return "r16f";
490
491                 case GL_RGBA32UI:
492                         return "rgba32ui";
493                 case GL_RGBA16UI:
494                         return "rgba16ui";
495                 case GL_RGB10_A2UI:
496                         return "rgb10_a2ui";
497                 case GL_RGBA8UI:
498                         return "rgba8ui";
499                 case GL_RG32UI:
500                         return "rg32ui";
501                 case GL_RG16UI:
502                         return "rg16ui";
503                 case GL_RG8UI:
504                         return "rg8ui";
505                 case GL_R32UI:
506                         return "r32ui";
507                 case GL_R16UI:
508                         return "r16ui";
509                 case GL_R8UI:
510                         return "r8ui";
511
512                 case GL_RGBA32I:
513                         return "rgba32i";
514                 case GL_RGBA16I:
515                         return "rgba16i";
516                 case GL_RGBA8I:
517                         return "rgba8i";
518                 case GL_RG32I:
519                         return "rg32i";
520                 case GL_RG16I:
521                         return "rg16i";
522                 case GL_RG8I:
523                         return "rg8i";
524                 case GL_R32I:
525                         return "r32i";
526                 case GL_R16I:
527                         return "r16i";
528                 case GL_R8I:
529                         return "r8i";
530
531                 case GL_RGBA16:
532                         return "rgba16";
533                 case GL_RGB10_A2:
534                         return "rgb10_a2";
535                 case GL_RGBA8:
536                         return "rgba8";
537                 case GL_RG16:
538                         return "rg16";
539                 case GL_RG8:
540                         return "rg8";
541                 case GL_R16:
542                         return "r16";
543                 case GL_R8:
544                         return "r8";
545
546                 case GL_RGBA16_SNORM:
547                         return "rgba16_snorm";
548                 case GL_RGBA8_SNORM:
549                         return "rgba8_snorm";
550                 case GL_RG16_SNORM:
551                         return "rg16_snorm";
552                 case GL_RG8_SNORM:
553                         return "rg8_snorm";
554                 case GL_R16_SNORM:
555                         return "r16_snorm";
556                 case GL_R8_SNORM:
557                         return "r8_snorm";
558                 }
559
560                 assert(0);
561                 return "";
562         }
563
564         const char* StageName(int stage)
565         {
566                 switch (stage)
567                 {
568                 case 0:
569                         return "Vertex Shader";
570                 case 1:
571                         return "Tessellation Control Shader";
572                 case 2:
573                         return "Tessellation Evaluation Shader";
574                 case 3:
575                         return "Geometry Shader";
576                 case 4:
577                         return "Compute Shader";
578                 }
579                 assert(0);
580                 return NULL;
581         }
582
583         template <typename T>
584         GLenum Format();
585
586         template <typename T>
587         GLenum Type();
588
589         template <typename T>
590         std::string TypePrefix();
591
592         template <typename T>
593         GLenum ImageType(GLenum target);
594
595         void ClearBuffer(GLenum buffer, GLint drawbuffer, const vec4& color)
596         {
597                 glClearBufferfv(buffer, drawbuffer, &color[0]);
598         }
599
600         void ClearBuffer(GLenum buffer, GLint drawbuffer, const ivec4& color)
601         {
602                 glClearBufferiv(buffer, drawbuffer, &color[0]);
603         }
604
605         void ClearBuffer(GLenum buffer, GLint drawbuffer, const uvec4& color)
606         {
607                 glClearBufferuiv(buffer, drawbuffer, &color[0]);
608         }
609
610         bool CheckUniform(GLuint program, const std::string& name, const std::map<std::string, GLuint>& name_index_map,
611                                           GLint size, GLenum type)
612         {
613                 std::map<std::string, GLuint>::const_iterator iter = name_index_map.find(name);
614                 assert(iter != name_index_map.end());
615
616                 GLchar  name_gl[32];
617                 GLsizei length_gl;
618                 GLint   size_gl;
619                 GLenum  type_gl;
620
621                 glGetActiveUniform(program, iter->second, sizeof(name_gl), &length_gl, &size_gl, &type_gl, name_gl);
622
623                 if (std::string(name_gl) != name)
624                 {
625                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Uniform name is " << name_gl
626                                                                                                 << " should be " << name << tcu::TestLog::EndMessage;
627                         return false;
628                 }
629                 if (length_gl != static_cast<GLsizei>(name.length()))
630                 {
631                         m_context.getTestContext().getLog()
632                                 << tcu::TestLog::Message << "Uniform length is " << length_gl << " should be " << name << "(" << name_gl
633                                 << ")" << tcu::TestLog::EndMessage;
634                         return false;
635                 }
636                 if (size_gl != size)
637                 {
638                         m_context.getTestContext().getLog()
639                                 << tcu::TestLog::Message << "Uniform size is " << size_gl << " should be " << size << "(" << name_gl
640                                 << ")" << tcu::TestLog::EndMessage;
641                         return false;
642                 }
643                 if (type_gl != type)
644                 {
645                         m_context.getTestContext().getLog()
646                                 << tcu::TestLog::Message << "Uniform type is " << type_gl << " should be " << type << "(" << name_gl
647                                 << ")" << tcu::TestLog::EndMessage;
648                         return false;
649                 }
650
651                 return true;
652         }
653
654         bool CheckMax(GLenum pname, GLint min_value)
655         {
656                 GLboolean b;
657                 GLint    i;
658                 GLfloat   f;
659                 GLdouble  d;
660                 GLint64   i64;
661
662                 glGetIntegerv(pname, &i);
663                 if (i < min_value)
664                         return false;
665
666                 glGetBooleanv(pname, &b);
667                 if (b != (i ? GL_TRUE : GL_FALSE))
668                         return false;
669
670                 glGetFloatv(pname, &f);
671                 if (static_cast<GLint>(f) < min_value)
672                         return false;
673
674                 glGetDoublev(pname, &d);
675                 if (static_cast<GLint>(d) < min_value)
676                         return false;
677
678                 glGetInteger64v(pname, &i64);
679                 if (static_cast<GLint>(i64) < min_value)
680                         return false;
681
682                 return true;
683         }
684
685         bool CheckBinding(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
686                                           GLenum format)
687         {
688                 GLint    i;
689                 GLboolean b;
690
691                 glGetIntegeri_v(GL_IMAGE_BINDING_NAME, unit, &i);
692                 if (static_cast<GLuint>(i) != texture)
693                 {
694                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_NAME is " << i
695                                                                                                 << " should be " << texture << tcu::TestLog::EndMessage;
696                         return false;
697                 }
698                 glGetBooleani_v(GL_IMAGE_BINDING_NAME, unit, &b);
699                 if (b != (i ? GL_TRUE : GL_FALSE))
700                 {
701                         m_context.getTestContext().getLog()
702                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_NAME (as boolean) is " << b << " should be "
703                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
704                         return false;
705                 }
706
707                 glGetIntegeri_v(GL_IMAGE_BINDING_LEVEL, unit, &i);
708                 if (i != level)
709                 {
710                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LEVEL is " << i
711                                                                                                 << " should be " << level << tcu::TestLog::EndMessage;
712                         return false;
713                 }
714                 glGetBooleani_v(GL_IMAGE_BINDING_LEVEL, unit, &b);
715                 if (b != (i ? GL_TRUE : GL_FALSE))
716                 {
717                         m_context.getTestContext().getLog()
718                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_LEVEL (as boolean) is " << b << " should be "
719                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
720                         return false;
721                 }
722
723                 glGetIntegeri_v(GL_IMAGE_BINDING_LAYERED, unit, &i);
724                 if (i != layered)
725                 {
726                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYERED is " << i
727                                                                                                 << " should be " << layered << tcu::TestLog::EndMessage;
728                         return false;
729                 }
730                 glGetBooleani_v(GL_IMAGE_BINDING_LAYERED, unit, &b);
731                 if (b != (i ? GL_TRUE : GL_FALSE))
732                 {
733                         m_context.getTestContext().getLog()
734                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYERED (as boolean) is " << b << " should be "
735                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
736                         return false;
737                 }
738
739                 glGetIntegeri_v(GL_IMAGE_BINDING_LAYER, unit, &i);
740                 if (i != layer)
741                 {
742                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYER is " << i
743                                                                                                 << " should be " << layer << tcu::TestLog::EndMessage;
744                         return false;
745                 }
746                 glGetBooleani_v(GL_IMAGE_BINDING_LAYER, unit, &b);
747                 if (b != (i ? GL_TRUE : GL_FALSE))
748                 {
749                         m_context.getTestContext().getLog()
750                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYER (as boolean) is " << b << " should be "
751                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
752                         return false;
753                 }
754
755                 glGetIntegeri_v(GL_IMAGE_BINDING_ACCESS, unit, &i);
756                 if (static_cast<GLenum>(i) != access)
757                 {
758                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_ACCESS is " << i
759                                                                                                 << " should be " << access << tcu::TestLog::EndMessage;
760                         return false;
761                 }
762                 glGetBooleani_v(GL_IMAGE_BINDING_ACCESS, unit, &b);
763                 if (b != (i ? GL_TRUE : GL_FALSE))
764                 {
765                         m_context.getTestContext().getLog()
766                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_ACCESS (as boolean) is " << b << " should be "
767                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
768                         return false;
769                 }
770
771                 glGetIntegeri_v(GL_IMAGE_BINDING_FORMAT, unit, &i);
772                 if (static_cast<GLenum>(i) != format)
773                 {
774                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_FORMAT is " << i
775                                                                                                 << " should be " << format << tcu::TestLog::EndMessage;
776                         return false;
777                 }
778                 glGetBooleani_v(GL_IMAGE_BINDING_FORMAT, unit, &b);
779                 if (b != (i ? GL_TRUE : GL_FALSE))
780                 {
781                         m_context.getTestContext().getLog()
782                                 << tcu::TestLog::Message << "GL_IMAGE_BINDING_FORMAT (as boolean) is " << b << " should be "
783                                 << (i ? GL_TRUE : GL_FALSE) << tcu::TestLog::EndMessage;
784                         return false;
785                 }
786
787                 return true;
788         }
789         const char* EnumToString(GLenum e)
790         {
791                 switch (e)
792                 {
793                 case GL_TEXTURE_1D:
794                         return "GL_TEXTURE_1D";
795                 case GL_TEXTURE_2D:
796                         return "GL_TEXTURE_2D";
797                 case GL_TEXTURE_3D:
798                         return "GL_TEXTURE_3D";
799                 case GL_TEXTURE_RECTANGLE:
800                         return "GL_TEXTURE_RECTANGLE";
801                 case GL_TEXTURE_CUBE_MAP:
802                         return "GL_TEXTURE_CUBE_MAP";
803                 case GL_TEXTURE_1D_ARRAY:
804                         return "GL_TEXTURE_1D_ARRAY";
805                 case GL_TEXTURE_2D_ARRAY:
806                         return "GL_TEXTURE_2D_ARRAY";
807                 case GL_TEXTURE_CUBE_MAP_ARRAY:
808                         return "GL_TEXTURE_CUBE_MAP_ARRAY";
809
810                 default:
811                         assert(0);
812                         break;
813                 }
814                 return NULL;
815         }
816 };
817
818 template <>
819 GLenum ShaderImageLoadStoreBase::Format<vec4>()
820 {
821         return GL_RGBA;
822 }
823
824 template <>
825 GLenum ShaderImageLoadStoreBase::Format<ivec4>()
826 {
827         return GL_RGBA_INTEGER;
828 }
829
830 template <>
831 GLenum ShaderImageLoadStoreBase::Format<uvec4>()
832 {
833         return GL_RGBA_INTEGER;
834 }
835
836 template <>
837 GLenum ShaderImageLoadStoreBase::Format<GLint>()
838 {
839         return GL_RED_INTEGER;
840 }
841
842 template <>
843 GLenum ShaderImageLoadStoreBase::Format<GLuint>()
844 {
845         return GL_RED_INTEGER;
846 }
847
848 template <>
849 GLenum ShaderImageLoadStoreBase::Type<vec4>()
850 {
851         return GL_FLOAT;
852 }
853
854 template <>
855 GLenum ShaderImageLoadStoreBase::Type<ivec4>()
856 {
857         return GL_INT;
858 }
859
860 template <>
861 GLenum ShaderImageLoadStoreBase::Type<uvec4>()
862 {
863         return GL_UNSIGNED_INT;
864 }
865
866 template <>
867 GLenum ShaderImageLoadStoreBase::Type<GLint>()
868 {
869         return GL_INT;
870 }
871
872 template <>
873 GLenum ShaderImageLoadStoreBase::Type<GLuint>()
874 {
875         return GL_UNSIGNED_INT;
876 }
877
878 template <>
879 std::string ShaderImageLoadStoreBase::TypePrefix<vec4>()
880 {
881         return "";
882 }
883
884 template <>
885 std::string ShaderImageLoadStoreBase::TypePrefix<ivec4>()
886 {
887         return "i";
888 }
889
890 template <>
891 std::string ShaderImageLoadStoreBase::TypePrefix<uvec4>()
892 {
893         return "u";
894 }
895
896 template <>
897 std::string ShaderImageLoadStoreBase::TypePrefix<GLint>()
898 {
899         return "i";
900 }
901
902 template <>
903 std::string ShaderImageLoadStoreBase::TypePrefix<GLuint>()
904 {
905         return "u";
906 }
907
908 template <>
909 GLenum ShaderImageLoadStoreBase::ImageType<vec4>(GLenum target)
910 {
911         switch (target)
912         {
913         case GL_TEXTURE_1D:
914                 return GL_IMAGE_1D;
915         case GL_TEXTURE_2D:
916                 return GL_IMAGE_2D;
917         case GL_TEXTURE_3D:
918                 return GL_IMAGE_3D;
919         case GL_TEXTURE_RECTANGLE:
920                 return GL_IMAGE_2D_RECT;
921         case GL_TEXTURE_CUBE_MAP:
922                 return GL_IMAGE_CUBE;
923         case GL_TEXTURE_BUFFER:
924                 return GL_IMAGE_BUFFER;
925         case GL_TEXTURE_1D_ARRAY:
926                 return GL_IMAGE_1D_ARRAY;
927         case GL_TEXTURE_2D_ARRAY:
928                 return GL_IMAGE_2D_ARRAY;
929         case GL_TEXTURE_CUBE_MAP_ARRAY:
930                 return GL_IMAGE_CUBE_MAP_ARRAY;
931         case GL_TEXTURE_2D_MULTISAMPLE:
932                 return GL_IMAGE_2D_MULTISAMPLE;
933         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
934                 return GL_IMAGE_2D_MULTISAMPLE_ARRAY;
935         }
936         assert(0);
937         return 0;
938 }
939
940 template <>
941 GLenum ShaderImageLoadStoreBase::ImageType<ivec4>(GLenum target)
942 {
943         switch (target)
944         {
945         case GL_TEXTURE_1D:
946                 return GL_INT_IMAGE_1D;
947         case GL_TEXTURE_2D:
948                 return GL_INT_IMAGE_2D;
949         case GL_TEXTURE_3D:
950                 return GL_INT_IMAGE_3D;
951         case GL_TEXTURE_RECTANGLE:
952                 return GL_INT_IMAGE_2D_RECT;
953         case GL_TEXTURE_CUBE_MAP:
954                 return GL_INT_IMAGE_CUBE;
955         case GL_TEXTURE_BUFFER:
956                 return GL_INT_IMAGE_BUFFER;
957         case GL_TEXTURE_1D_ARRAY:
958                 return GL_INT_IMAGE_1D_ARRAY;
959         case GL_TEXTURE_2D_ARRAY:
960                 return GL_INT_IMAGE_2D_ARRAY;
961         case GL_TEXTURE_CUBE_MAP_ARRAY:
962                 return GL_INT_IMAGE_CUBE_MAP_ARRAY;
963         case GL_TEXTURE_2D_MULTISAMPLE:
964                 return GL_INT_IMAGE_2D_MULTISAMPLE;
965         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
966                 return GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY;
967         }
968         assert(0);
969         return 0;
970 }
971
972 template <>
973 GLenum ShaderImageLoadStoreBase::ImageType<uvec4>(GLenum target)
974 {
975         switch (target)
976         {
977         case GL_TEXTURE_1D:
978                 return GL_UNSIGNED_INT_IMAGE_1D;
979         case GL_TEXTURE_2D:
980                 return GL_UNSIGNED_INT_IMAGE_2D;
981         case GL_TEXTURE_3D:
982                 return GL_UNSIGNED_INT_IMAGE_3D;
983         case GL_TEXTURE_RECTANGLE:
984                 return GL_UNSIGNED_INT_IMAGE_2D_RECT;
985         case GL_TEXTURE_CUBE_MAP:
986                 return GL_UNSIGNED_INT_IMAGE_CUBE;
987         case GL_TEXTURE_BUFFER:
988                 return GL_UNSIGNED_INT_IMAGE_BUFFER;
989         case GL_TEXTURE_1D_ARRAY:
990                 return GL_UNSIGNED_INT_IMAGE_1D_ARRAY;
991         case GL_TEXTURE_2D_ARRAY:
992                 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
993         case GL_TEXTURE_CUBE_MAP_ARRAY:
994                 return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
995         case GL_TEXTURE_2D_MULTISAMPLE:
996                 return GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE;
997         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
998                 return GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY;
999         }
1000         assert(0);
1001         return 0;
1002 }
1003
1004 //-----------------------------------------------------------------------------
1005 // 1.1.1 BasicAPIGet
1006 //-----------------------------------------------------------------------------
1007 class BasicAPIGet : public ShaderImageLoadStoreBase
1008 {
1009         virtual long Run()
1010         {
1011                 if (!CheckMax(GL_MAX_IMAGE_UNITS, 8))
1012                 {
1013                         m_context.getTestContext().getLog()
1014                                 << tcu::TestLog::Message << "GL_MAX_IMAGE_UNITS value is invalid." << tcu::TestLog::EndMessage;
1015                         return ERROR;
1016                 }
1017                 if (!CheckMax(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, 8))
1018                 {
1019                         m_context.getTestContext().getLog()
1020                                 << tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES value is invalid."
1021                                 << tcu::TestLog::EndMessage;
1022                         return ERROR;
1023                 }
1024                 if (!CheckMax(GL_MAX_IMAGE_SAMPLES, 0))
1025                 {
1026                         m_context.getTestContext().getLog()
1027                                 << tcu::TestLog::Message << "GL_MAX_IMAGE_SAMPLES value is invalid." << tcu::TestLog::EndMessage;
1028                         return ERROR;
1029                 }
1030                 if (!CheckMax(GL_MAX_VERTEX_IMAGE_UNIFORMS, 0))
1031                 {
1032                         m_context.getTestContext().getLog()
1033                                 << tcu::TestLog::Message << "GL_MAX_VERTEX_IMAGE_UNIFORMS value is invalid."
1034                                 << tcu::TestLog::EndMessage;
1035                         return ERROR;
1036                 }
1037                 if (!CheckMax(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, 0))
1038                 {
1039                         m_context.getTestContext().getLog()
1040                                 << tcu::TestLog::Message << "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS value is invalid."
1041                                 << tcu::TestLog::EndMessage;
1042                         return ERROR;
1043                 }
1044                 if (!CheckMax(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, 0))
1045                 {
1046                         m_context.getTestContext().getLog()
1047                                 << tcu::TestLog::Message << "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS value is invalid."
1048                                 << tcu::TestLog::EndMessage;
1049                         return ERROR;
1050                 }
1051                 if (!CheckMax(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, 0))
1052                 {
1053                         m_context.getTestContext().getLog()
1054                                 << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS value is invalid."
1055                                 << tcu::TestLog::EndMessage;
1056                         return ERROR;
1057                 }
1058                 if (!CheckMax(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, 8))
1059                 {
1060                         m_context.getTestContext().getLog()
1061                                 << tcu::TestLog::Message << "GL_MAX_FRAGMENT_IMAGE_UNIFORMS value is invalid."
1062                                 << tcu::TestLog::EndMessage;
1063                         return ERROR;
1064                 }
1065                 if (!CheckMax(GL_MAX_COMBINED_IMAGE_UNIFORMS, 8))
1066                 {
1067                         m_context.getTestContext().getLog()
1068                                 << tcu::TestLog::Message << "GL_MAX_COMBINED_IMAGE_UNIFORMS value is invalid."
1069                                 << tcu::TestLog::EndMessage;
1070                         return ERROR;
1071                 }
1072                 return NO_ERROR;
1073         }
1074 };
1075 //-----------------------------------------------------------------------------
1076 // 1.1.2 BasicAPIBind
1077 //-----------------------------------------------------------------------------
1078 class BasicAPIBind : public ShaderImageLoadStoreBase
1079 {
1080         GLuint m_texture;
1081
1082         virtual long Setup()
1083         {
1084                 m_texture = 0;
1085                 return NO_ERROR;
1086         }
1087
1088         virtual long Run()
1089         {
1090                 for (GLuint index = 0; index < 8; ++index)
1091                 {
1092                         if (!CheckBinding(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8))
1093                         {
1094                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Binding point " << index
1095                                                                                                         << " has invalid default state." << tcu::TestLog::EndMessage;
1096                                 return ERROR;
1097                         }
1098                 }
1099
1100                 glGenTextures(1, &m_texture);
1101                 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
1102                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R32F, 16, 16, 4, 0, GL_RED, GL_FLOAT, NULL);
1103                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, 8, 8, 4, 0, GL_RED, GL_FLOAT, NULL);
1104                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_R32F, 4, 4, 4, 0, GL_RED, GL_FLOAT, NULL);
1105                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 3, GL_R32F, 2, 2, 4, 0, GL_RED, GL_FLOAT, NULL);
1106                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 4, GL_R32F, 1, 1, 4, 0, GL_RED, GL_FLOAT, NULL);
1107                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1108
1109                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
1110                 if (!CheckBinding(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F))
1111                         return ERROR;
1112
1113                 glBindImageTexture(1, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8);
1114                 if (!CheckBinding(1, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8))
1115                         return ERROR;
1116
1117                 glBindImageTexture(4, m_texture, 3, GL_FALSE, 2, GL_READ_ONLY, GL_RG16);
1118                 if (!CheckBinding(4, m_texture, 3, GL_FALSE, 2, GL_READ_ONLY, GL_RG16))
1119                         return ERROR;
1120
1121                 glBindImageTexture(7, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I);
1122                 if (!CheckBinding(7, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I))
1123                         return ERROR;
1124
1125                 glDeleteTextures(1, &m_texture);
1126                 m_texture = 0;
1127
1128                 for (GLuint index = 0; index < 8; ++index)
1129                 {
1130                         GLint name;
1131                         glGetIntegeri_v(GL_IMAGE_BINDING_NAME, index, &name);
1132                         if (name != 0)
1133                         {
1134                                 m_context.getTestContext().getLog()
1135                                         << tcu::TestLog::Message << "Binding point " << index
1136                                         << " should be set to 0 after texture deletion." << tcu::TestLog::EndMessage;
1137                                 return ERROR;
1138                         }
1139                 }
1140
1141                 return NO_ERROR;
1142         }
1143
1144         virtual long Cleanup()
1145         {
1146                 glDeleteTextures(1, &m_texture);
1147                 return NO_ERROR;
1148         }
1149 };
1150 //-----------------------------------------------------------------------------
1151 // 1.1.3 BasicAPIBarrier
1152 //-----------------------------------------------------------------------------
1153 class BasicAPIBarrier : public ShaderImageLoadStoreBase
1154 {
1155         virtual long Run()
1156         {
1157                 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
1158                 glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);
1159                 glMemoryBarrier(GL_UNIFORM_BARRIER_BIT);
1160                 glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
1161                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
1162                 glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
1163                 glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
1164                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
1165                 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1166                 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
1167                 glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);
1168                 glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
1169
1170                 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1171                                                 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1172                                                 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1173                                                 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT);
1174
1175                 glMemoryBarrier(GL_ALL_BARRIER_BITS);
1176
1177                 return NO_ERROR;
1178         }
1179 };
1180 //-----------------------------------------------------------------------------
1181 // 1.1.4 BasicAPITexParam
1182 //-----------------------------------------------------------------------------
1183 class BasicAPITexParam : public ShaderImageLoadStoreBase
1184 {
1185         GLuint m_texture;
1186
1187         virtual long Setup()
1188         {
1189                 m_texture = 0;
1190                 return NO_ERROR;
1191         }
1192
1193         virtual long Run()
1194         {
1195                 glGenTextures(1, &m_texture);
1196                 glBindTexture(GL_TEXTURE_2D, m_texture);
1197                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, 16, 16, 0, GL_RED, GL_FLOAT, NULL);
1198
1199                 GLint   i;
1200                 GLfloat f;
1201                 GLuint  ui;
1202
1203                 glGetTexParameteriv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &i);
1204                 if (i != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
1205                 {
1206                         m_context.getTestContext().getLog()
1207                                 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
1208                                 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
1209                                 << tcu::TestLog::EndMessage;
1210                         return ERROR;
1211                 }
1212                 glGetTexParameterfv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &f);
1213                 if (static_cast<GLenum>(f) != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
1214                 {
1215                         m_context.getTestContext().getLog()
1216                                 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
1217                                 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
1218                                 << tcu::TestLog::EndMessage;
1219                         return ERROR;
1220                 }
1221                 glGetTexParameterIiv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &i);
1222                 if (i != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
1223                 {
1224                         m_context.getTestContext().getLog()
1225                                 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
1226                                 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
1227                                 << tcu::TestLog::EndMessage;
1228                         return ERROR;
1229                 }
1230                 glGetTexParameterIuiv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &ui);
1231                 if (ui != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
1232                 {
1233                         m_context.getTestContext().getLog()
1234                                 << tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
1235                                 << "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
1236                                 << tcu::TestLog::EndMessage;
1237                         return ERROR;
1238                 }
1239
1240                 return NO_ERROR;
1241         }
1242
1243         virtual long Cleanup()
1244         {
1245                 glDeleteTextures(1, &m_texture);
1246                 return NO_ERROR;
1247         }
1248 };
1249 //-----------------------------------------------------------------------------
1250 // 1.2.1 BasicAllFormatsStore
1251 //-----------------------------------------------------------------------------
1252 class BasicAllFormatsStore : public ShaderImageLoadStoreBase
1253 {
1254         GLuint m_vao;
1255         GLuint m_vbo;
1256
1257         virtual long Setup()
1258         {
1259                 m_vao = 0;
1260                 m_vbo = 0;
1261                 return NO_ERROR;
1262         }
1263
1264         virtual long Run()
1265         {
1266                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
1267
1268                 if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1269                         return ERROR;
1270                 if (!Write(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1271                         return ERROR;
1272                 if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1273                         return ERROR;
1274
1275                 if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1276                         return ERROR;
1277                 if (!Write(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1278                         return ERROR;
1279                 if (!Write(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1280                         return ERROR;
1281
1282                 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1283                         return ERROR;
1284                 if (!Write(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1285                         return ERROR;
1286                 if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1287                         return ERROR;
1288
1289                 if (!Write(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
1290                         return ERROR;
1291
1292                 if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1293                         return ERROR;
1294                 if (!Write(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1295                         return ERROR;
1296                 if (!Write(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1297                         return ERROR;
1298
1299                 if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1300                         return ERROR;
1301                 if (!Write(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1302                         return ERROR;
1303                 if (!Write(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1304                         return ERROR;
1305
1306                 if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1307                         return ERROR;
1308                 if (!Write(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1309                         return ERROR;
1310                 if (!Write(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1311                         return ERROR;
1312                 if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1313                         return ERROR;
1314
1315                 if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1316                         return ERROR;
1317                 if (!Write(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1318                         return ERROR;
1319                 if (!Write(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1320                         return ERROR;
1321
1322                 if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1323                         return ERROR;
1324                 if (!Write(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1325                         return ERROR;
1326                 if (!Write(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1327                         return ERROR;
1328
1329                 if (!Write(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
1330                         return ERROR;
1331                 if (!Write(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
1332                         return ERROR;
1333                 if (!Write(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1334                         return ERROR;
1335                 if (!Write(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1336                         return ERROR;
1337
1338                 if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
1339                         return ERROR;
1340                 if (!Write(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1341                         return ERROR;
1342                 if (!Write(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1343                         return ERROR;
1344
1345                 if (!Write(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1346                         return ERROR;
1347                 if (!Write(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1348                         return ERROR;
1349                 if (!Write(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1350                         return ERROR;
1351
1352                 if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1353                         return ERROR;
1354                 if (!Write(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1355                         return ERROR;
1356                 if (!Write(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1357                         return ERROR;
1358
1359                 return NO_ERROR;
1360         }
1361
1362         template <typename T>
1363         bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
1364         {
1365                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
1366                                                          "  gl_Position = i_position;" NL "}";
1367                 const GLuint   program = BuildProgram(src_vs, NULL, NULL, NULL, GenFS(internalformat, write_value).c_str());
1368                 const int         kSize   = 16;
1369                 std::vector<T> data(kSize * kSize);
1370                 GLuint             texture;
1371                 glGenTextures(1, &texture);
1372
1373                 for (GLuint unit = 0; unit < 8; ++unit)
1374                 {
1375                         glBindTexture(GL_TEXTURE_2D, texture);
1376                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1377                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1378                         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
1379                         glBindTexture(GL_TEXTURE_2D, 0);
1380
1381                         glViewport(0, 0, kSize, kSize);
1382                         glUseProgram(program);
1383                         glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
1384                         glBindVertexArray(m_vao);
1385                         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1386
1387                         glBindTexture(GL_TEXTURE_2D, texture);
1388                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
1389                         glGetTexImage(GL_TEXTURE_2D, 0, Format<T>(), Type<T>(), &data[0]);
1390
1391                         for (int i = 0; i < kSize * kSize; ++i)
1392                         {
1393                                 if (!Equal(data[i], expected_value, internalformat))
1394                                 {
1395                                         glDeleteTextures(1, &texture);
1396                                         glUseProgram(0);
1397                                         glDeleteProgram(program);
1398                                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Value is: " << ToString(data[i])
1399                                                                                                                 << ". Value should be: " << ToString(expected_value)
1400                                                                                                                 << ". Format is: " << FormatEnumToString(internalformat)
1401                                                                                                                 << ". Unit is: " << unit << tcu::TestLog::EndMessage;
1402                                         return false;
1403                                 }
1404                         }
1405
1406                         if (unit < 7)
1407                         {
1408                                 glUniform1i(glGetUniformLocation(program, "g_image"), static_cast<GLint>(unit + 1));
1409                         }
1410                 }
1411
1412                 glDeleteTextures(1, &texture);
1413                 glUseProgram(0);
1414                 glDeleteProgram(program);
1415
1416                 return true;
1417         }
1418
1419         virtual long Cleanup()
1420         {
1421                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
1422                 glDeleteVertexArrays(1, &m_vao);
1423                 glDeleteBuffers(1, &m_vbo);
1424                 return NO_ERROR;
1425         }
1426
1427         template <typename T>
1428         std::string GenFS(GLenum internalformat, const T& value)
1429         {
1430                 std::ostringstream os;
1431                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
1432                    << TypePrefix<T>() << "image2D g_image;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
1433                                                                  "  imageStore(g_image, coord, "
1434                    << TypePrefix<T>() << "vec4" << value << ");" NL "  discard;" NL "}";
1435                 return os.str();
1436         }
1437 };
1438 //-----------------------------------------------------------------------------
1439 // 1.2.2 BasicAllFormatsLoad
1440 //-----------------------------------------------------------------------------
1441 class BasicAllFormatsLoad : public ShaderImageLoadStoreBase
1442 {
1443         GLuint m_vao;
1444         GLuint m_vbo;
1445
1446         virtual long Setup()
1447         {
1448                 m_vao = 0;
1449                 m_vbo = 0;
1450                 return NO_ERROR;
1451         }
1452
1453         virtual long Run()
1454         {
1455                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
1456
1457                 if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1458                         return ERROR;
1459                 if (!Read(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1460                         return ERROR;
1461                 if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1462                         return ERROR;
1463
1464                 if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1465                         return ERROR;
1466                 if (!Read(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1467                         return ERROR;
1468                 if (!Read(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1469                         return ERROR;
1470
1471                 if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1472                         return ERROR;
1473                 if (!Read(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1474                         return ERROR;
1475                 if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1476                         return ERROR;
1477
1478                 if (!Read(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
1479                         return ERROR;
1480
1481                 if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1482                         return ERROR;
1483                 if (!Read(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1484                         return ERROR;
1485                 if (!Read(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1486                         return ERROR;
1487
1488                 if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1489                         return ERROR;
1490                 if (!Read(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1491                         return ERROR;
1492                 if (!Read(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1493                         return ERROR;
1494
1495                 if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1496                         return ERROR;
1497                 if (!Read(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1498                         return ERROR;
1499                 if (!Read(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1500                         return ERROR;
1501                 if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1502                         return ERROR;
1503
1504                 if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1505                         return ERROR;
1506                 if (!Read(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1507                         return ERROR;
1508                 if (!Read(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1509                         return ERROR;
1510
1511                 if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1512                         return ERROR;
1513                 if (!Read(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1514                         return ERROR;
1515                 if (!Read(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1516                         return ERROR;
1517
1518                 if (!Read(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
1519                         return ERROR;
1520                 if (!Read(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
1521                         return ERROR;
1522                 if (!Read(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1523                         return ERROR;
1524                 if (!Read(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1525                         return ERROR;
1526
1527                 if (!Read(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
1528                         return ERROR;
1529                 if (!Read(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1530                         return ERROR;
1531                 if (!Read(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1532                         return ERROR;
1533
1534                 if (!Read(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1535                         return ERROR;
1536                 if (!Read(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1537                         return ERROR;
1538                 if (!Read(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1539                         return ERROR;
1540
1541                 if (!Read(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1542                         return ERROR;
1543                 if (!Read(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1544                         return ERROR;
1545                 if (!Read(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1546                         return ERROR;
1547
1548                 return NO_ERROR;
1549         }
1550
1551         template <typename T>
1552         bool Read(GLenum internalformat, const T& value, const T& expected_value)
1553         {
1554                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
1555                                                          "  gl_Position = i_position;" NL "}";
1556                 const GLuint   program = BuildProgram(src_vs, NULL, NULL, NULL, GenFS(internalformat, expected_value).c_str());
1557                 const int         kSize   = 16;
1558                 std::vector<T> data(kSize * kSize, value);
1559                 GLuint             texture;
1560                 glGenTextures(1, &texture);
1561
1562                 for (GLuint unit = 0; unit < 8; ++unit)
1563                 {
1564                         glBindTexture(GL_TEXTURE_2D, texture);
1565                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1566                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1567                         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
1568                         glBindTexture(GL_TEXTURE_2D, 0);
1569
1570                         glViewport(0, 0, kSize, kSize);
1571                         glClear(GL_COLOR_BUFFER_BIT);
1572                         glUseProgram(program);
1573                         glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
1574                         glBindVertexArray(m_vao);
1575                         glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1576
1577                         if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
1578                         {
1579                                 glDeleteTextures(1, &texture);
1580                                 glUseProgram(0);
1581                                 glDeleteProgram(program);
1582                                 m_context.getTestContext().getLog()
1583                                         << tcu::TestLog::Message << "Bad load value. Format is: " << FormatEnumToString(internalformat)
1584                                         << ". Unit is: " << unit << tcu::TestLog::EndMessage;
1585                                 return false;
1586                         }
1587
1588                         if (unit < 7)
1589                         {
1590                                 glUniform1i(glGetUniformLocation(program, "g_image"), static_cast<GLint>(unit + 1));
1591                         }
1592                 }
1593
1594                 glDeleteTextures(1, &texture);
1595                 glUseProgram(0);
1596                 glDeleteProgram(program);
1597
1598                 return true;
1599         }
1600
1601         virtual long Cleanup()
1602         {
1603                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
1604                 glDeleteVertexArrays(1, &m_vao);
1605                 glDeleteBuffers(1, &m_vbo);
1606                 return NO_ERROR;
1607         }
1608
1609         template <typename T>
1610         std::string GenFS(GLenum internalformat, const T& expected_value)
1611         {
1612                 std::ostringstream os;
1613                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
1614                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
1615                    << "image2D g_image;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  "
1616                    << TypePrefix<T>() << "vec4 v = imageLoad(g_image, coord);" NL "  if (v != " << TypePrefix<T>() << "vec4"
1617                    << expected_value
1618                    << ") o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "  else o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
1619                 return os.str();
1620         }
1621 };
1622 //-----------------------------------------------------------------------------
1623 // 1.2.3 BasicAllFormatsStoreGeometryStages
1624 //-----------------------------------------------------------------------------
1625 class BasicAllFormatsStoreGeometryStages : public ShaderImageLoadStoreBase
1626 {
1627         GLuint m_vao;
1628
1629         virtual long Setup()
1630         {
1631                 glGenVertexArrays(1, &m_vao);
1632                 return NO_ERROR;
1633         }
1634
1635         virtual long Run()
1636         {
1637                 if (!SupportedInGeomStages(1))
1638                         return NOT_SUPPORTED;
1639                 glEnable(GL_RASTERIZER_DISCARD);
1640
1641                 if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1642                         return ERROR;
1643                 if (!Write(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1644                         return ERROR;
1645                 if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1646                         return ERROR;
1647
1648                 if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1649                         return ERROR;
1650                 if (!Write(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1651                         return ERROR;
1652                 if (!Write(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1653                         return ERROR;
1654
1655                 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1656                         return ERROR;
1657                 if (!Write(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1658                         return ERROR;
1659                 if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1660                         return ERROR;
1661
1662                 if (!Write(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
1663                         return ERROR;
1664
1665                 if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1666                         return ERROR;
1667                 if (!Write(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1668                         return ERROR;
1669                 if (!Write(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1670                         return ERROR;
1671
1672                 if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1673                         return ERROR;
1674                 if (!Write(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1675                         return ERROR;
1676                 if (!Write(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1677                         return ERROR;
1678
1679                 if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1680                         return ERROR;
1681                 if (!Write(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1682                         return ERROR;
1683                 if (!Write(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1684                         return ERROR;
1685                 if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1686                         return ERROR;
1687
1688                 if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1689                         return ERROR;
1690                 if (!Write(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1691                         return ERROR;
1692                 if (!Write(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1693                         return ERROR;
1694
1695                 if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1696                         return ERROR;
1697                 if (!Write(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1698                         return ERROR;
1699                 if (!Write(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1700                         return ERROR;
1701
1702                 if (!Write(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
1703                         return ERROR;
1704                 if (!Write(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
1705                         return ERROR;
1706                 if (!Write(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1707                         return ERROR;
1708                 if (!Write(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1709                         return ERROR;
1710
1711                 if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
1712                         return ERROR;
1713                 if (!Write(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1714                         return ERROR;
1715                 if (!Write(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1716                         return ERROR;
1717
1718                 if (!Write(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1719                         return ERROR;
1720                 if (!Write(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1721                         return ERROR;
1722                 if (!Write(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1723                         return ERROR;
1724
1725                 if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1726                         return ERROR;
1727                 if (!Write(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1728                         return ERROR;
1729                 if (!Write(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1730                         return ERROR;
1731
1732                 return NO_ERROR;
1733         }
1734
1735         template <typename T>
1736         bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
1737         {
1738                 const GLuint program =
1739                         BuildProgram(GenVS(internalformat, write_value).c_str(), GenTCS(internalformat, write_value).c_str(),
1740                                                  GenTES(internalformat, write_value).c_str(), GenGS(internalformat, write_value).c_str(), NULL);
1741                 const int         kSize = 1;
1742                 std::vector<T> data(kSize * kSize);
1743                 GLuint             texture[4];
1744                 glGenTextures(4, texture);
1745
1746                 for (int i = 0; i < 4; ++i)
1747                 {
1748                         glBindTexture(GL_TEXTURE_2D_ARRAY, texture[i]);
1749                         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1750                         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1751                         glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, kSize, kSize, 1, 0, Format<T>(), Type<T>(), &data[0]);
1752                 }
1753                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1754
1755                 glUseProgram(program);
1756                 glUniform1i(glGetUniformLocation(program, "g_image0"), 0);
1757                 glUniform1i(glGetUniformLocation(program, "g_image1"), 1);
1758                 glUniform1i(glGetUniformLocation(program, "g_image2"), 2);
1759                 glUniform1i(glGetUniformLocation(program, "g_image3"), 3);
1760                 for (GLuint i = 0; i < 4; ++i)
1761                 {
1762                         glBindImageTexture(i, texture[i], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
1763                 }
1764                 glBindVertexArray(m_vao);
1765                 glPatchParameteri(GL_PATCH_VERTICES, 1);
1766                 glDrawArrays(GL_PATCHES, 0, 1);
1767                 glPatchParameteri(GL_PATCH_VERTICES, 3);
1768
1769                 for (int i = 0; i < 4; ++i)
1770                 {
1771                         glBindTexture(GL_TEXTURE_2D_ARRAY, texture[i]);
1772                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
1773                         glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, Format<T>(), Type<T>(), &data[0]);
1774
1775                         if (!Equal(data[0], expected_value, internalformat))
1776                         {
1777                                 glDeleteTextures(4, texture);
1778                                 glUseProgram(0);
1779                                 glDeleteProgram(program);
1780                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Value is: " << ToString(data[0])
1781                                                                                                         << ". Value should be: " << ToString(expected_value)
1782                                                                                                         << ". Format is: " << FormatEnumToString(internalformat)
1783                                                                                                         << ". Stage is: " << StageName(i) << tcu::TestLog::EndMessage;
1784                                 return false;
1785                         }
1786                 }
1787                 glDeleteTextures(4, texture);
1788                 glUseProgram(0);
1789                 glDeleteProgram(program);
1790                 return true;
1791         }
1792
1793         virtual long Cleanup()
1794         {
1795                 glDisable(GL_RASTERIZER_DISCARD);
1796                 glDeleteVertexArrays(1, &m_vao);
1797                 return NO_ERROR;
1798         }
1799
1800         template <typename T>
1801         std::string GenVS(GLenum internalformat, const T& value)
1802         {
1803                 std::ostringstream os;
1804                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
1805                    << TypePrefix<T>() << "image2DArray g_image0;" NL "void main() {" NL
1806                                                                  "  ivec3 coord = ivec3(gl_VertexID, 0, 0);" NL "  imageStore(g_image0, coord, "
1807                    << TypePrefix<T>() << "vec4" << value << ");" NL "}";
1808                 return os.str();
1809         }
1810
1811         template <typename T>
1812         std::string GenTCS(GLenum internalformat, const T& value)
1813         {
1814                 std::ostringstream os;
1815                 os << "#version 420 core" NL "layout(vertices = 1) out;" NL "layout(" << FormatEnumToString(internalformat)
1816                    << ") writeonly uniform " << TypePrefix<T>()
1817                    << "image2DArray g_image1;" NL "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL
1818                           "  gl_TessLevelInner[1] = 1;" NL "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL
1819                           "  gl_TessLevelOuter[2] = 1;" NL "  gl_TessLevelOuter[3] = 1;" NL
1820                           "  ivec3 coord = ivec3(gl_PrimitiveID, 0, 0);" NL "  imageStore(g_image1, coord, "
1821                    << TypePrefix<T>() << "vec4" << value << ");" NL "}";
1822                 return os.str();
1823         }
1824
1825         template <typename T>
1826         std::string GenTES(GLenum internalformat, const T& value)
1827         {
1828                 std::ostringstream os;
1829                 os << "#version 420 core" NL "layout(triangles, point_mode) in;" NL "layout("
1830                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
1831                    << "image2DArray g_image2;" NL "void main() {" NL "  ivec3 coord = ivec3(gl_PrimitiveID, 0, 0);" NL
1832                           "  imageStore(g_image2, coord, "
1833                    << TypePrefix<T>() << "vec4" << value << ");" NL "}";
1834                 return os.str();
1835         }
1836
1837         template <typename T>
1838         std::string GenGS(GLenum internalformat, const T& value)
1839         {
1840                 std::ostringstream os;
1841                 os << "#version 420 core" NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "layout("
1842                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
1843                    << "image2DArray g_image3;" NL "void main() {" NL "  ivec3 coord = ivec3(gl_PrimitiveIDIn, 0, 0);" NL
1844                           "  imageStore(g_image3, coord, "
1845                    << TypePrefix<T>() << "vec4" << value << ");" NL "}";
1846                 return os.str();
1847         }
1848 };
1849 //-----------------------------------------------------------------------------
1850 // 1.2.4 BasicAllFormatsLoadGeometryStages
1851 //-----------------------------------------------------------------------------
1852 class BasicAllFormatsLoadGeometryStages : public ShaderImageLoadStoreBase
1853 {
1854         GLuint m_vao;
1855
1856         virtual long Setup()
1857         {
1858                 glGenVertexArrays(1, &m_vao);
1859                 return NO_ERROR;
1860         }
1861
1862         virtual long Run()
1863         {
1864                 if (!SupportedInGeomStages(2))
1865                         return NOT_SUPPORTED;
1866                 glEnable(GL_RASTERIZER_DISCARD);
1867
1868                 if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1869                         return ERROR;
1870                 if (!Read(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1871                         return ERROR;
1872                 if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1873                         return ERROR;
1874
1875                 if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
1876                         return ERROR;
1877                 if (!Read(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
1878                         return ERROR;
1879                 if (!Read(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1880                         return ERROR;
1881
1882                 if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1883                         return ERROR;
1884                 if (!Read(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1885                         return ERROR;
1886                 if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1887                         return ERROR;
1888
1889                 if (!Read(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
1890                         return ERROR;
1891
1892                 if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1893                         return ERROR;
1894                 if (!Read(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1895                         return ERROR;
1896                 if (!Read(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1897                         return ERROR;
1898
1899                 if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
1900                         return ERROR;
1901                 if (!Read(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
1902                         return ERROR;
1903                 if (!Read(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
1904                         return ERROR;
1905
1906                 if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1907                         return ERROR;
1908                 if (!Read(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1909                         return ERROR;
1910                 if (!Read(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1911                         return ERROR;
1912                 if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1913                         return ERROR;
1914
1915                 if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1916                         return ERROR;
1917                 if (!Read(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1918                         return ERROR;
1919                 if (!Read(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1920                         return ERROR;
1921
1922                 if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
1923                         return ERROR;
1924                 if (!Read(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
1925                         return ERROR;
1926                 if (!Read(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
1927                         return ERROR;
1928
1929                 if (!Read(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
1930                         return ERROR;
1931                 if (!Read(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
1932                         return ERROR;
1933                 if (!Read(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1934                         return ERROR;
1935                 if (!Read(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1936                         return ERROR;
1937
1938                 if (!Read(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
1939                         return ERROR;
1940                 if (!Read(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
1941                         return ERROR;
1942                 if (!Read(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
1943                         return ERROR;
1944
1945                 if (!Read(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1946                         return ERROR;
1947                 if (!Read(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1948                         return ERROR;
1949                 if (!Read(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1950                         return ERROR;
1951
1952                 if (!Read(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
1953                         return ERROR;
1954                 if (!Read(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
1955                         return ERROR;
1956                 if (!Read(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
1957                         return ERROR;
1958
1959                 return NO_ERROR;
1960         }
1961
1962         template <typename T>
1963         bool Read(GLenum internalformat, const T& value, const T& expected_value)
1964         {
1965                 const GLuint program = BuildProgram(
1966                         GenVS(internalformat, expected_value).c_str(), GenTCS(internalformat, expected_value).c_str(),
1967                         GenTES(internalformat, expected_value).c_str(), GenGS(internalformat, expected_value).c_str(), NULL);
1968                 const int         kSize = 1;
1969                 std::vector<T> data(kSize * kSize, value);
1970                 GLuint             texture[8];
1971                 glGenTextures(8, texture);
1972
1973                 for (int i = 0; i < 4; ++i)
1974                 {
1975                         glBindTexture(GL_TEXTURE_2D_ARRAY, texture[i]);
1976                         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1977                         glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1978                         glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, kSize, kSize, 1, 0, Format<T>(), Type<T>(), &data[0]);
1979                 }
1980                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
1981                 vec4 zero(0);
1982                 for (int i = 4; i < 8; ++i)
1983                 {
1984                         glBindTexture(GL_TEXTURE_2D, texture[i]);
1985                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1986                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1987                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kSize, kSize, 0, GL_RGBA, GL_FLOAT, &zero);
1988                 }
1989                 glBindTexture(GL_TEXTURE_2D, 0);
1990
1991                 glUseProgram(program);
1992                 glUniform1i(glGetUniformLocation(program, "g_image0"), 0);
1993                 glUniform1i(glGetUniformLocation(program, "g_image1"), 1);
1994                 glUniform1i(glGetUniformLocation(program, "g_image2"), 2);
1995                 glUniform1i(glGetUniformLocation(program, "g_image3"), 3);
1996                 glUniform1i(glGetUniformLocation(program, "g_image0_result"), 4);
1997                 glUniform1i(glGetUniformLocation(program, "g_image1_result"), 5);
1998                 glUniform1i(glGetUniformLocation(program, "g_image2_result"), 6);
1999                 glUniform1i(glGetUniformLocation(program, "g_image3_result"), 7);
2000
2001                 for (GLuint i = 0; i < 4; ++i)
2002                 {
2003                         glBindImageTexture(i, texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
2004                 }
2005                 for (GLuint i = 4; i < 8; ++i)
2006                 {
2007                         glBindImageTexture(i, texture[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
2008                 }
2009                 glBindVertexArray(m_vao);
2010                 glPatchParameteri(GL_PATCH_VERTICES, 1);
2011                 glDrawArrays(GL_PATCHES, 0, 1);
2012                 glPatchParameteri(GL_PATCH_VERTICES, 3);
2013
2014                 const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
2015                 const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
2016                 vec4                                     g_color_eps  = vec4(
2017                         1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
2018                         1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
2019
2020                 for (int i = 0; i < 4; ++i)
2021                 {
2022                         glBindTexture(GL_TEXTURE_2D, texture[i + 4]);
2023                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2024                         vec4 result;
2025                         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &result[0]);
2026                         if (!ColorEqual(result, vec4(0, 1, 0, 1), g_color_eps))
2027                         {
2028                                 glDeleteTextures(8, texture);
2029                                 glUseProgram(0);
2030                                 glDeleteProgram(program);
2031                                 m_context.getTestContext().getLog()
2032                                         << tcu::TestLog::Message << "Bad load value. Format is: " << FormatEnumToString(internalformat)
2033                                         << ". Stage is: " << StageName(i) << tcu::TestLog::EndMessage;
2034                                 return false;
2035                         }
2036                 }
2037                 glDeleteTextures(8, texture);
2038                 glUseProgram(0);
2039                 glDeleteProgram(program);
2040                 return true;
2041         }
2042
2043         virtual long Cleanup()
2044         {
2045                 glDisable(GL_RASTERIZER_DISCARD);
2046                 glDeleteVertexArrays(1, &m_vao);
2047                 return NO_ERROR;
2048         }
2049
2050         template <typename T>
2051         std::string GenVS(GLenum internalformat, const T& expected_value)
2052         {
2053                 std::ostringstream os;
2054                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
2055                    << TypePrefix<T>()
2056                    << "image2DArray g_image0;" NL "layout(rgba32f) writeonly uniform image2D g_image0_result;" NL
2057                           "void main() {" NL "  ivec3 coord = ivec3(gl_VertexID, 0, 0);" NL "  "
2058                    << TypePrefix<T>() << "vec4 v = imageLoad(g_image0, coord);" NL "  if (v != " << TypePrefix<T>() << "vec4"
2059                    << expected_value << ") imageStore(g_image0_result, coord.xy, vec4(1.0, 0.0, 0.0, 1.0));" NL
2060                                                                 "  else imageStore(g_image0_result, coord.xy, vec4(0.0, 1.0, 0.0, 1.0));" NL "}";
2061                 return os.str();
2062         }
2063
2064         template <typename T>
2065         std::string GenTCS(GLenum internalformat, const T& expected_value)
2066         {
2067                 std::ostringstream os;
2068                 os << "#version 420 core" NL "layout(vertices = 1) out;" NL "layout(" << FormatEnumToString(internalformat)
2069                    << ") readonly uniform " << TypePrefix<T>()
2070                    << "image2DArray g_image1;" NL "layout(rgba32f) writeonly uniform image2D g_image1_result;" NL
2071                           "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL "  gl_TessLevelInner[1] = 1;" NL
2072                           "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL "  gl_TessLevelOuter[2] = 1;" NL
2073                           "  gl_TessLevelOuter[3] = 1;" NL "  ivec3 coord = ivec3(gl_PrimitiveID, 0, 0);" NL "  "
2074                    << TypePrefix<T>() << "vec4 v = imageLoad(g_image1, coord);" NL "  if (v != " << TypePrefix<T>() << "vec4"
2075                    << expected_value << ") imageStore(g_image1_result, coord.xy, vec4(1.0, 0.0, 0.0, 1.0));" NL
2076                                                                 "  else imageStore(g_image1_result, coord.xy, vec4(0.0, 1.0, 0.0, 1.0));" NL "}";
2077                 return os.str();
2078         }
2079
2080         template <typename T>
2081         std::string GenTES(GLenum internalformat, const T& expected_value)
2082         {
2083                 std::ostringstream os;
2084                 os << "#version 420 core" NL "layout(triangles, point_mode) in;" NL "layout("
2085                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
2086                    << "image2DArray g_image2;" NL "layout(rgba32f) writeonly uniform image2D g_image2_result;" NL
2087                           "void main() {" NL "  ivec3 coord = ivec3(gl_PrimitiveID, 0, 0);" NL "  "
2088                    << TypePrefix<T>() << "vec4 v = imageLoad(g_image2, coord);" NL "  if (v != " << TypePrefix<T>() << "vec4"
2089                    << expected_value << ") imageStore(g_image2_result, coord.xy, vec4(1.0, 0.0, 0.0, 1.0));" NL
2090                                                                 "  else imageStore(g_image2_result, coord.xy, vec4(0.0, 1.0, 0.0, 1.0));" NL "}";
2091                 return os.str();
2092         }
2093
2094         template <typename T>
2095         std::string GenGS(GLenum internalformat, const T& expected_value)
2096         {
2097                 std::ostringstream os;
2098                 os << "#version 420 core" NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "layout("
2099                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
2100                    << "image2DArray g_image3;" NL "layout(rgba32f) writeonly uniform image2D g_image3_result;" NL
2101                           "void main() {" NL "  ivec3 coord = ivec3(gl_PrimitiveIDIn, 0, 0);" NL "  "
2102                    << TypePrefix<T>() << "vec4 v = imageLoad(g_image3, coord);" NL "  if (v != " << TypePrefix<T>() << "vec4"
2103                    << expected_value << ") imageStore(g_image3_result, coord.xy, vec4(1.0, 0.0, 0.0, 1.0));" NL
2104                                                                 "  else imageStore(g_image3_result, coord.xy, vec4(0.0, 1.0, 0.0, 1.0));" NL "}";
2105                 return os.str();
2106         }
2107 };
2108 //-----------------------------------------------------------------------------
2109 // 1.2.5 BasicAllFormatsLoadStoreComputeStage
2110 //-----------------------------------------------------------------------------
2111 class BasicAllFormatsLoadStoreComputeStage : public ShaderImageLoadStoreBase
2112 {
2113         virtual long Run()
2114         {
2115                 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
2116                 {
2117                         m_context.getTestContext().getLog()
2118                                 << tcu::TestLog::Message << "GL_ARB_compute_shader not supported, skipping test"
2119                                 << tcu::TestLog::EndMessage;
2120                         return NOT_SUPPORTED;
2121                 }
2122
2123                 if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
2124                         return ERROR;
2125                 if (!Read(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
2126                         return ERROR;
2127                 if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
2128                         return ERROR;
2129
2130                 if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
2131                         return ERROR;
2132                 if (!Read(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
2133                         return ERROR;
2134                 if (!Read(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
2135                         return ERROR;
2136
2137                 if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2138                         return ERROR;
2139                 if (!Read(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
2140                         return ERROR;
2141                 if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
2142                         return ERROR;
2143
2144                 if (!Read(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
2145                         return ERROR;
2146
2147                 if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2148                         return ERROR;
2149                 if (!Read(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
2150                         return ERROR;
2151                 if (!Read(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
2152                         return ERROR;
2153
2154                 if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2155                         return ERROR;
2156                 if (!Read(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
2157                         return ERROR;
2158                 if (!Read(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
2159                         return ERROR;
2160
2161                 if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
2162                         return ERROR;
2163                 if (!Read(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
2164                         return ERROR;
2165                 if (!Read(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
2166                         return ERROR;
2167                 if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
2168                         return ERROR;
2169
2170                 if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
2171                         return ERROR;
2172                 if (!Read(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
2173                         return ERROR;
2174                 if (!Read(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
2175                         return ERROR;
2176
2177                 if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
2178                         return ERROR;
2179                 if (!Read(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
2180                         return ERROR;
2181                 if (!Read(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
2182                         return ERROR;
2183
2184                 if (!Read(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
2185                         return ERROR;
2186                 if (!Read(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
2187                         return ERROR;
2188                 if (!Read(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
2189                         return ERROR;
2190                 if (!Read(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
2191                         return ERROR;
2192
2193                 if (!Read(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
2194                         return ERROR;
2195                 if (!Read(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
2196                         return ERROR;
2197                 if (!Read(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
2198                         return ERROR;
2199
2200                 if (!Read(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
2201                         return ERROR;
2202                 if (!Read(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
2203                         return ERROR;
2204                 if (!Read(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
2205                         return ERROR;
2206
2207                 if (!Read(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
2208                         return ERROR;
2209                 if (!Read(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
2210                         return ERROR;
2211                 if (!Read(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
2212                         return ERROR;
2213
2214                 return NO_ERROR;
2215         }
2216
2217         template <typename T>
2218         bool Read(GLenum internalformat, const T& value, const T& expected_value)
2219         {
2220                 GLuint                    program;
2221                 std::string               source = GenCS<T>(internalformat);
2222                 const char* const src   = source.c_str();
2223                 GLuint                    sh     = glCreateShader(GL_COMPUTE_SHADER);
2224                 glShaderSource(sh, 1, &src, NULL);
2225                 glCompileShader(sh);
2226                 program = glCreateProgram();
2227                 glAttachShader(program, sh);
2228                 glLinkProgram(program);
2229                 glDeleteShader(sh);
2230
2231                 const int         kSize = 1;
2232                 std::vector<T> data(kSize * kSize, value);
2233                 GLuint             texture[2];
2234                 glGenTextures(2, texture);
2235
2236                 glBindTexture(GL_TEXTURE_2D, texture[0]);
2237                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2238                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2239                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2240                 glBindTexture(GL_TEXTURE_2D, texture[1]);
2241                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2242                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2243                 vec4 zero(0);
2244                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &zero);
2245
2246                 glBindTexture(GL_TEXTURE_2D, 0);
2247
2248                 glUseProgram(program);
2249                 glUniform1i(glGetUniformLocation(program, "g_image_read"), 0);
2250                 glUniform1i(glGetUniformLocation(program, "g_image_write"), 1);
2251
2252                 glBindImageTexture(0, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
2253                 glBindImageTexture(1, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2254
2255                 glDispatchCompute(1, 1, 1);
2256
2257                 for (int i = 0; i < 2; ++i)
2258                 {
2259                         glBindTexture(GL_TEXTURE_2D, texture[i]);
2260                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2261                         glGetTexImage(GL_TEXTURE_2D, 0, Format<T>(), Type<T>(), &data[0]);
2262
2263                         if (!Equal(data[0], expected_value, internalformat))
2264                         {
2265                                 glDeleteTextures(4, texture);
2266                                 glUseProgram(0);
2267                                 glDeleteProgram(program);
2268                                 m_context.getTestContext().getLog()
2269                                         << tcu::TestLog::Message << "Value is: " << ToString(data[0])
2270                                         << ". Value should be: " << ToString(expected_value)
2271                                         << ". Format is: " << FormatEnumToString(internalformat) << tcu::TestLog::EndMessage;
2272                                 return false;
2273                         }
2274                 }
2275                 glDeleteTextures(2, texture);
2276                 glUseProgram(0);
2277                 glDeleteProgram(program);
2278                 return true;
2279         }
2280
2281         template <typename T>
2282         std::string GenCS(GLenum internalformat)
2283         {
2284                 std::ostringstream os;
2285                 os << "#version 420 core" NL "#extension GL_ARB_compute_shader : require" NL "layout(local_size_x = 1) in;" NL
2286                           "layout("
2287                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
2288                    << "image2D g_image_read;" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2289                    << TypePrefix<T>() << "image2D g_image_write;" NL "void main() {" NL
2290                                                                  "  ivec2 coord = ivec2(int(gl_GlobalInvocationID.x), 0);" NL "  "
2291                    << TypePrefix<T>()
2292                    << "vec4 v = imageLoad(g_image_read, coord);" NL "  imageStore(g_image_write, coord, v);" NL "}";
2293                 return os.str();
2294         }
2295 };
2296 //-----------------------------------------------------------------------------
2297 // 1.3.1 BasicAllTargetsStore
2298 //-----------------------------------------------------------------------------
2299 class BasicAllTargetsStore : public ShaderImageLoadStoreBase
2300 {
2301         GLuint m_vao;
2302         GLuint m_vbo;
2303
2304         virtual long Setup()
2305         {
2306                 m_vao = 0;
2307                 m_vbo = 0;
2308                 return NO_ERROR;
2309         }
2310
2311         virtual long Run()
2312         {
2313                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
2314
2315                 if (!Write(GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
2316                         return ERROR;
2317                 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2318                         return ERROR;
2319                 if (!Write(GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
2320                         return ERROR;
2321
2322                 if (!WriteCubeArray(GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
2323                         return ERROR;
2324                 if (!WriteCubeArray(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2325                         return ERROR;
2326                 if (!WriteCubeArray(GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
2327                         return ERROR;
2328
2329                 if (SupportedSamples(4))
2330                 {
2331                         if (!WriteMS(GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
2332                                 return ERROR;
2333
2334                         GLint isamples;
2335                         glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &isamples);
2336                         if (isamples >= 4)
2337                         {
2338                                 if (!WriteMS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
2339                                         return ERROR;
2340                                 if (!WriteMS(GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
2341                                         return ERROR;
2342                         }
2343                 }
2344                 return NO_ERROR;
2345         }
2346
2347         virtual long Cleanup()
2348         {
2349                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
2350                 glDeleteVertexArrays(1, &m_vao);
2351                 glDeleteBuffers(1, &m_vbo);
2352                 return NO_ERROR;
2353         }
2354
2355         template <typename T>
2356         bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
2357         {
2358                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
2359                                                          "  gl_Position = i_position;" NL "}";
2360                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFS(internalformat, write_value).c_str());
2361                 GLuint           textures[8];
2362                 GLuint           buffer;
2363                 glGenTextures(8, textures);
2364                 glGenBuffers(1, &buffer);
2365
2366                 const int         kSize = 16;
2367                 std::vector<T> data(kSize * kSize * 2);
2368
2369                 glBindTexture(GL_TEXTURE_1D, textures[0]);
2370                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2371                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2372                 glTexImage1D(GL_TEXTURE_1D, 0, internalformat, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2373                 glBindTexture(GL_TEXTURE_1D, 0);
2374
2375                 glBindTexture(GL_TEXTURE_2D, textures[1]);
2376                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2377                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2378                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2379                 glBindTexture(GL_TEXTURE_2D, 0);
2380
2381                 glBindTexture(GL_TEXTURE_3D, textures[2]);
2382                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2383                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2384                 glTexImage3D(GL_TEXTURE_3D, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2385                 glBindTexture(GL_TEXTURE_3D, 0);
2386
2387                 glBindTexture(GL_TEXTURE_RECTANGLE, textures[3]);
2388                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2389                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2390                 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2391                 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
2392
2393                 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
2394                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2395                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2396                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2397                                          &data[0]);
2398                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2399                                          &data[0]);
2400                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2401                                          &data[0]);
2402                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2403                                          &data[0]);
2404                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2405                                          &data[0]);
2406                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
2407                                          &data[0]);
2408                 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
2409
2410                 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
2411                 glBufferData(GL_TEXTURE_BUFFER, kSize * sizeof(T), &data[0], GL_DYNAMIC_DRAW);
2412                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
2413                 glBindTexture(GL_TEXTURE_BUFFER, textures[5]);
2414                 glTexBuffer(GL_TEXTURE_BUFFER, internalformat, buffer);
2415                 glBindTexture(GL_TEXTURE_BUFFER, 0);
2416
2417                 glBindTexture(GL_TEXTURE_1D_ARRAY, textures[6]);
2418                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2419                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2420                 glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, internalformat, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2421                 glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
2422
2423                 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
2424                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2425                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2426                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2427                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
2428
2429                 glBindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
2430                 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
2431                 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2432                 glBindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
2433                 glBindImageTexture(4, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2434                 glBindImageTexture(5, textures[5], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
2435                 glBindImageTexture(6, textures[6], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2436                 glBindImageTexture(7, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2437
2438                 glUseProgram(program);
2439                 glUniform1i(glGetUniformLocation(program, "g_image_1d"), 0);
2440                 glUniform1i(glGetUniformLocation(program, "g_image_2d"), 1);
2441                 glUniform1i(glGetUniformLocation(program, "g_image_3d"), 2);
2442                 glUniform1i(glGetUniformLocation(program, "g_image_2drect"), 3);
2443                 glUniform1i(glGetUniformLocation(program, "g_image_cube"), 4);
2444                 glUniform1i(glGetUniformLocation(program, "g_image_buffer"), 5);
2445                 glUniform1i(glGetUniformLocation(program, "g_image_1darray"), 6);
2446                 glUniform1i(glGetUniformLocation(program, "g_image_2darray"), 7);
2447
2448                 glBindVertexArray(m_vao);
2449                 glViewport(0, 0, kSize, kSize);
2450                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2451
2452                 bool status = true;
2453
2454                 glBindTexture(GL_TEXTURE_1D, textures[0]);
2455                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2456                 glGetTexImage(GL_TEXTURE_1D, 0, Format<T>(), Type<T>(), &data[0]);
2457                 glBindTexture(GL_TEXTURE_1D, 0);
2458                 for (int i = 0; i < kSize; ++i)
2459                 {
2460                         if (!tcu::allEqual(data[i], expected_value))
2461                         {
2462                                 status = false;
2463                                 m_context.getTestContext().getLog()
2464                                         << tcu::TestLog::Message << "GL_TEXTURE_1D target failed. Value is: " << ToString(data[i])
2465                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2466                                 break;
2467                         }
2468                 }
2469                 std::fill(data.begin(), data.end(), T(0));
2470
2471                 glBindTexture(GL_TEXTURE_2D, textures[1]);
2472                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2473                 glGetTexImage(GL_TEXTURE_2D, 0, Format<T>(), Type<T>(), &data[0]);
2474                 glBindTexture(GL_TEXTURE_2D, 0);
2475                 for (int i = 0; i < kSize * kSize; ++i)
2476                 {
2477                         if (!tcu::allEqual(data[i], expected_value))
2478                         {
2479                                 status = false;
2480                                 m_context.getTestContext().getLog()
2481                                         << tcu::TestLog::Message << "GL_TEXTURE_2D target failed. Value is: " << ToString(data[i])
2482                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2483                                 break;
2484                         }
2485                 }
2486
2487                 glBindTexture(GL_TEXTURE_3D, textures[2]);
2488                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2489                 glGetTexImage(GL_TEXTURE_3D, 0, Format<T>(), Type<T>(), &data[0]);
2490                 glBindTexture(GL_TEXTURE_3D, 0);
2491                 for (int i = 0; i < kSize * kSize * 2; ++i)
2492                 {
2493                         if (!tcu::allEqual(data[i], expected_value))
2494                         {
2495                                 status = false;
2496                                 m_context.getTestContext().getLog()
2497                                         << tcu::TestLog::Message << "GL_TEXTURE_3D target failed. Value is: " << ToString(data[i])
2498                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2499                                 break;
2500                         }
2501                 }
2502
2503                 glBindTexture(GL_TEXTURE_RECTANGLE, textures[3]);
2504                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2505                 glGetTexImage(GL_TEXTURE_RECTANGLE, 0, Format<T>(), Type<T>(), &data[0]);
2506                 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
2507                 for (int i = 0; i < kSize * kSize; ++i)
2508                 {
2509                         if (!tcu::allEqual(data[i], expected_value))
2510                         {
2511                                 status = false;
2512                                 m_context.getTestContext().getLog()
2513                                         << tcu::TestLog::Message << "GL_TEXTURE_RECTANGLE target failed. Value is: " << ToString(data[i])
2514                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2515                                 break;
2516                         }
2517                 }
2518
2519                 {
2520                         glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
2521                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2522                         for (int face = 0; face < 6; ++face)
2523                         {
2524                                 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, Format<T>(), Type<T>(), &data[0]);
2525                                 for (int i = 0; i < kSize * kSize; ++i)
2526                                 {
2527                                         if (!tcu::allEqual(data[i], expected_value))
2528                                         {
2529                                                 status = false;
2530                                                 m_context.getTestContext().getLog()
2531                                                         << tcu::TestLog::Message
2532                                                         << "GL_TEXTURE_CUBE_MAP_POSITIVE_X target failed. Value is: " << ToString(data[i])
2533                                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2534                                                 break;
2535                                         }
2536                                 }
2537                         }
2538                         glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
2539                 }
2540
2541                 glBindTexture(GL_TEXTURE_BUFFER, textures[5]);
2542                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2543                 glBindTexture(GL_TEXTURE_BUFFER, 0);
2544                 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
2545                 glGetBufferSubData(GL_TEXTURE_BUFFER, 0, kSize * sizeof(T), &data[0]);
2546                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
2547                 for (int i = 0; i < kSize; ++i)
2548                 {
2549                         if (!tcu::allEqual(data[i], expected_value))
2550                         {
2551                                 status = false;
2552                                 m_context.getTestContext().getLog()
2553                                         << tcu::TestLog::Message << "GL_TEXTURE_BUFFER target failed. Value is: " << ToString(data[i])
2554                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2555                                 break;
2556                         }
2557                 }
2558
2559                 glBindTexture(GL_TEXTURE_1D_ARRAY, textures[6]);
2560                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2561                 glGetTexImage(GL_TEXTURE_1D_ARRAY, 0, Format<T>(), Type<T>(), &data[0]);
2562                 glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
2563                 for (int i = 0; i < kSize * 2; ++i)
2564                 {
2565                         if (!tcu::allEqual(data[i], expected_value))
2566                         {
2567                                 status = false;
2568                                 m_context.getTestContext().getLog()
2569                                         << tcu::TestLog::Message << "GL_TEXTURE_1D_ARRAY target failed. Value is: " << ToString(data[i])
2570                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2571                                 break;
2572                         }
2573                 }
2574
2575                 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
2576                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2577                 glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, Format<T>(), Type<T>(), &data[0]);
2578                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
2579                 for (int i = 0; i < kSize * kSize * 2; ++i)
2580                 {
2581                         if (!tcu::allEqual(data[i], expected_value))
2582                         {
2583                                 status = false;
2584                                 m_context.getTestContext().getLog()
2585                                         << tcu::TestLog::Message << "GL_TEXTURE_2D_ARRAY target failed. Value is: " << ToString(data[i])
2586                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2587                                 break;
2588                         }
2589                 }
2590
2591                 glUseProgram(0);
2592                 glDeleteProgram(program);
2593                 glDeleteTextures(8, textures);
2594                 glDeleteBuffers(1, &buffer);
2595
2596                 return status;
2597         }
2598
2599         template <typename T>
2600         bool WriteMS(GLenum internalformat, const T& write_value, const T& expected_value)
2601         {
2602
2603                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
2604                                                          "  gl_Position = i_position;" NL "}";
2605                 const GLuint program     = BuildProgram(src_vs, NULL, NULL, NULL, GenFSMS(internalformat, write_value).c_str());
2606                 const GLuint val_program = BuildProgram(src_vs, NULL, NULL, NULL, GenFSMSVal(expected_value).c_str());
2607                 GLuint           textures[2];
2608                 glGenTextures(2, textures);
2609
2610                 const int kSize = 16;
2611
2612                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures[0]);
2613                 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, internalformat, kSize, kSize, GL_FALSE);
2614                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
2615
2616                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures[1]);
2617                 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 4, internalformat, kSize, kSize, 2, GL_FALSE);
2618                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
2619
2620                 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
2621                 glBindImageTexture(4, textures[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2622
2623                 glClear(GL_COLOR_BUFFER_BIT);
2624                 glUseProgram(program);
2625                 glUniform1i(glGetUniformLocation(program, "g_image_2dms"), 1);
2626                 glUniform1i(glGetUniformLocation(program, "g_image_2dms_array"), 4);
2627
2628                 glBindVertexArray(m_vao);
2629                 glViewport(0, 0, kSize, kSize);
2630                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2631
2632                 bool status = true;
2633
2634                 glActiveTexture(GL_TEXTURE0);
2635                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures[0]);
2636                 glActiveTexture(GL_TEXTURE1);
2637                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures[1]);
2638
2639                 glUseProgram(val_program);
2640                 glUniform1i(glGetUniformLocation(val_program, "g_sampler_2dms"), 0);
2641                 glUniform1i(glGetUniformLocation(val_program, "g_sampler_2dms_array"), 1);
2642
2643                 glBindVertexArray(m_vao);
2644                 glViewport(0, 0, kSize, kSize);
2645                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2646                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2647
2648                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
2649                 {
2650                         status = false;
2651                         m_context.getTestContext().getLog()
2652                                 << tcu::TestLog::Message
2653                                 << "GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY target failed."
2654                                 << tcu::TestLog::EndMessage;
2655                 }
2656
2657                 glActiveTexture(GL_TEXTURE0);
2658                 glDeleteTextures(2, textures);
2659                 glUseProgram(0);
2660                 glDeleteProgram(program);
2661                 glDeleteProgram(val_program);
2662
2663                 return status;
2664         }
2665
2666         template <typename T>
2667         bool WriteCubeArray(GLenum internalformat, const T& write_value, const T& expected_value)
2668         {
2669                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
2670                                                          "  gl_Position = i_position;" NL "}";
2671                 const GLuint program =
2672                         BuildProgram(src_vs, NULL, NULL, NULL, GenFSCubeArray(internalformat, write_value).c_str());
2673                 GLuint textures[1];
2674                 glGenTextures(1, textures);
2675
2676                 const int kSize = 16;
2677
2678                 std::vector<T> data(kSize * kSize * 12);
2679                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[0]);
2680                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2681                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalformat, kSize, kSize, 12, 0, Format<T>(), Type<T>(),
2682                                          &data[0]);
2683                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
2684
2685                 glBindImageTexture(0, textures[0], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
2686
2687                 glUseProgram(program);
2688                 glBindVertexArray(m_vao);
2689                 glViewport(0, 0, kSize, kSize);
2690                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2691
2692                 bool status = true;
2693
2694                 std::fill(data.begin(), data.end(), T(0));
2695                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[0]);
2696                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2697                 glGetTexImage(GL_TEXTURE_CUBE_MAP_ARRAY, 0, Format<T>(), Type<T>(), &data[0]);
2698                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
2699                 for (int i = 0; i < kSize * kSize * 12; ++i)
2700                 {
2701                         if (!tcu::allEqual(data[i], expected_value))
2702                         {
2703                                 status = false;
2704                                 m_context.getTestContext().getLog()
2705                                         << tcu::TestLog::Message
2706                                         << "GL_TEXTURE_CUBE_MAP_ARRAY target failed. Value is: " << ToString(data[i])
2707                                         << ". Value should be: " << ToString(expected_value) << tcu::TestLog::EndMessage;
2708                                 break;
2709                         }
2710                 }
2711
2712                 glDeleteTextures(1, textures);
2713                 glUseProgram(0);
2714                 glDeleteProgram(program);
2715
2716                 return status;
2717         }
2718
2719         template <typename T>
2720         std::string GenFS(GLenum internalformat, const T& write_value)
2721         {
2722                 std::ostringstream os;
2723                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2724                    << TypePrefix<T>() << "image1D g_image_1d;" NL "layout(" << FormatEnumToString(internalformat)
2725                    << ") writeonly uniform " << TypePrefix<T>() << "image2D g_image_2d;" NL "layout("
2726                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
2727                    << "image3D g_image_3d;" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2728                    << TypePrefix<T>() << "image2DRect g_image_2drect;" NL "layout(" << FormatEnumToString(internalformat)
2729                    << ") writeonly uniform " << TypePrefix<T>() << "imageCube g_image_cube;" NL "layout("
2730                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
2731                    << "imageBuffer g_image_buffer;" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2732                    << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout(" << FormatEnumToString(internalformat)
2733                    << ") writeonly uniform " << TypePrefix<T>()
2734                    << "image2DArray g_image_2darray;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
2735                           "  imageStore(g_image_1d, coord.x, "
2736                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_2d, coord, " << TypePrefix<T>()
2737                    << "vec4" << write_value << ");" NL "  imageStore(g_image_3d, ivec3(coord.xy, 0), " << TypePrefix<T>()
2738                    << "vec4" << write_value << ");" NL "  imageStore(g_image_3d, ivec3(coord.xy, 1), " << TypePrefix<T>()
2739                    << "vec4" << write_value << ");" NL "  imageStore(g_image_2drect, coord, " << TypePrefix<T>() << "vec4"
2740                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 0), " << TypePrefix<T>() << "vec4"
2741                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 1), " << TypePrefix<T>() << "vec4"
2742                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 2), " << TypePrefix<T>() << "vec4"
2743                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 3), " << TypePrefix<T>() << "vec4"
2744                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 4), " << TypePrefix<T>() << "vec4"
2745                    << write_value << ");" NL "  imageStore(g_image_cube, ivec3(coord, 5), " << TypePrefix<T>() << "vec4"
2746                    << write_value << ");" NL "  imageStore(g_image_buffer, coord.x, " << TypePrefix<T>() << "vec4"
2747                    << write_value << ");" NL "  imageStore(g_image_1darray, ivec2(coord.x, 0), " << TypePrefix<T>() << "vec4"
2748                    << write_value << ");" NL "  imageStore(g_image_1darray, ivec2(coord.x, 1), " << TypePrefix<T>() << "vec4"
2749                    << write_value << ");" NL "  imageStore(g_image_2darray, ivec3(coord, 0), " << TypePrefix<T>() << "vec4"
2750                    << write_value << ");" NL "  imageStore(g_image_2darray, ivec3(coord, 1), " << TypePrefix<T>() << "vec4"
2751                    << write_value << ");" NL "  discard;" NL "}";
2752                 return os.str();
2753         }
2754
2755         template <typename T>
2756         std::string GenFSMS(GLenum internalformat, const T& write_value)
2757         {
2758                 std::ostringstream os;
2759                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2760                    << TypePrefix<T>() << "image2DMS g_image_2dms;" NL "layout(" << FormatEnumToString(internalformat)
2761                    << ") writeonly uniform " << TypePrefix<T>()
2762                    << "image2DMSArray g_image_2dms_array;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
2763                           "  imageStore(g_image_2dms, coord, 0, "
2764                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_2dms, coord, 1, "
2765                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_2dms, coord, 2, "
2766                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_2dms, coord, 3, "
2767                    << TypePrefix<T>() << "vec4" << write_value
2768                    << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 0), 0, " << TypePrefix<T>() << "vec4"
2769                    << write_value << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 0), 1, " << TypePrefix<T>()
2770                    << "vec4" << write_value << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 0), 2, "
2771                    << TypePrefix<T>() << "vec4" << write_value
2772                    << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 0), 3, " << TypePrefix<T>() << "vec4"
2773                    << write_value << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 1), 0, " << TypePrefix<T>()
2774                    << "vec4" << write_value << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 1), 1, "
2775                    << TypePrefix<T>() << "vec4" << write_value
2776                    << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 1), 2, " << TypePrefix<T>() << "vec4"
2777                    << write_value << ");" NL "  imageStore(g_image_2dms_array, ivec3(coord, 1), 3, " << TypePrefix<T>()
2778                    << "vec4" << write_value << ");" NL "  discard;" NL "}";
2779                 return os.str();
2780         }
2781
2782         template <typename T>
2783         std::string GenFSMSVal(const T& expected_value)
2784         {
2785                 std::ostringstream os;
2786                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "uniform " << TypePrefix<T>()
2787                    << "sampler2DMS g_sampler_2dms;" NL "uniform " << TypePrefix<T>()
2788                    << "sampler2DMSArray g_sampler_2dms_array;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
2789                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  if (texelFetch(g_sampler_2dms, coord, 0) != "
2790                    << TypePrefix<T>() << "vec4" << expected_value
2791                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (texelFetch(g_sampler_2dms, coord, 1) != "
2792                    << TypePrefix<T>() << "vec4" << expected_value
2793                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (texelFetch(g_sampler_2dms, coord, 2) != "
2794                    << TypePrefix<T>() << "vec4" << expected_value
2795                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (texelFetch(g_sampler_2dms, coord, 3) != "
2796                    << TypePrefix<T>() << "vec4" << expected_value
2797                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL
2798                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 0), 0) != "
2799                    << TypePrefix<T>() << "vec4" << expected_value
2800                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL
2801                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 0), 1) != "
2802                    << TypePrefix<T>() << "vec4" << expected_value
2803                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL
2804                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 0), 2) != "
2805                    << TypePrefix<T>() << "vec4" << expected_value
2806                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL
2807                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 0), 3) != "
2808                    << TypePrefix<T>() << "vec4" << expected_value
2809                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL
2810                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 1), 0) != "
2811                    << TypePrefix<T>() << "vec4" << expected_value
2812                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL
2813                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 1), 1) != "
2814                    << TypePrefix<T>() << "vec4" << expected_value
2815                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL
2816                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 1), 2) != "
2817                    << TypePrefix<T>() << "vec4" << expected_value
2818                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL
2819                           "  if (texelFetch(g_sampler_2dms_array, ivec3(coord, 1), 3) != "
2820                    << TypePrefix<T>() << "vec4" << expected_value << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "}";
2821                 return os.str();
2822         }
2823
2824         template <typename T>
2825         std::string GenFSCubeArray(GLenum internalformat, const T& write_value)
2826         {
2827                 std::ostringstream os;
2828                 os << "#version 420 core" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
2829                    << TypePrefix<T>()
2830                    << "imageCubeArray g_image_cube_array;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
2831                           "  imageStore(g_image_cube_array, ivec3(coord, 0), "
2832                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 1), "
2833                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 2), "
2834                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 3), "
2835                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 4), "
2836                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 5), "
2837                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 6), "
2838                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 7), "
2839                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 8), "
2840                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 9), "
2841                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 10), "
2842                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  imageStore(g_image_cube_array, ivec3(coord, 11), "
2843                    << TypePrefix<T>() << "vec4" << write_value << ");" NL "  discard;" NL "}";
2844                 return os.str();
2845         }
2846 };
2847 //-----------------------------------------------------------------------------
2848 // 1.3.2.1 BasicAllTargetsLoadNonMS
2849 //-----------------------------------------------------------------------------
2850 class BasicAllTargetsLoadNonMS : public ShaderImageLoadStoreBase
2851 {
2852         GLuint m_vao;
2853         GLuint m_vbo;
2854
2855         virtual long Setup()
2856         {
2857                 m_vao = 0;
2858                 m_vbo = 0;
2859                 return NO_ERROR;
2860         }
2861
2862         virtual long Run()
2863         {
2864                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
2865
2866                 if (!Read(GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f)))
2867                         return ERROR;
2868                 if (!Read(GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000)))
2869                         return ERROR;
2870                 if (!Read(GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000)))
2871                         return ERROR;
2872
2873                 if (!ReadCube(GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f)))
2874                         return ERROR;
2875                 if (!ReadCube(GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000)))
2876                         return ERROR;
2877                 if (!ReadCube(GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000)))
2878                         return ERROR;
2879
2880                 return NO_ERROR;
2881         }
2882
2883         virtual long Cleanup()
2884         {
2885                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
2886                 glDeleteVertexArrays(1, &m_vao);
2887                 glDeleteBuffers(1, &m_vbo);
2888                 return NO_ERROR;
2889         }
2890
2891         template <typename T>
2892         bool Read(GLenum internalformat, const T& value, const T& expected_value)
2893         {
2894                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
2895                                                          "  gl_Position = i_position;" NL "}";
2896                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFS(internalformat, expected_value).c_str());
2897                 GLuint           textures[7];
2898                 GLuint           buffer;
2899                 glGenTextures(7, textures);
2900                 glGenBuffers(1, &buffer);
2901
2902                 const int         kSize = 16;
2903                 std::vector<T> data(kSize * kSize * 2, value);
2904
2905                 glBindTexture(GL_TEXTURE_1D, textures[0]);
2906                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2907                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2908                 glTexImage1D(GL_TEXTURE_1D, 0, internalformat, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2909                 glBindTexture(GL_TEXTURE_1D, 0);
2910
2911                 glBindTexture(GL_TEXTURE_2D, textures[1]);
2912                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2913                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2914                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2915                 glBindTexture(GL_TEXTURE_2D, 0);
2916
2917                 glBindTexture(GL_TEXTURE_3D, textures[2]);
2918                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2919                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2920                 glTexImage3D(GL_TEXTURE_3D, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2921                 glBindTexture(GL_TEXTURE_3D, 0);
2922
2923                 glBindTexture(GL_TEXTURE_RECTANGLE, textures[3]);
2924                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2925                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2926                 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
2927                 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
2928
2929                 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
2930                 glBufferData(GL_TEXTURE_BUFFER, kSize * sizeof(T), &data[0], GL_DYNAMIC_DRAW);
2931                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
2932                 glBindTexture(GL_TEXTURE_BUFFER, textures[4]);
2933                 glTexBuffer(GL_TEXTURE_BUFFER, internalformat, buffer);
2934                 glBindTexture(GL_TEXTURE_BUFFER, 0);
2935
2936                 glBindTexture(GL_TEXTURE_1D_ARRAY, textures[5]);
2937                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2938                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2939                 glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, internalformat, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2940                 glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
2941
2942                 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[6]);
2943                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2944                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2945                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
2946                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
2947
2948                 glBindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
2949                 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
2950                 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
2951                 glBindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
2952                 glBindImageTexture(4, textures[4], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
2953                 glBindImageTexture(5, textures[5], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
2954                 glBindImageTexture(6, textures[6], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
2955
2956                 glClear(GL_COLOR_BUFFER_BIT);
2957
2958                 glUseProgram(program);
2959                 glUniform1i(glGetUniformLocation(program, "g_image_1d"), 0);
2960                 glUniform1i(glGetUniformLocation(program, "g_image_2d"), 1);
2961                 glUniform1i(glGetUniformLocation(program, "g_image_3d"), 2);
2962                 glUniform1i(glGetUniformLocation(program, "g_image_2drect"), 3);
2963                 glUniform1i(glGetUniformLocation(program, "g_image_buffer"), 4);
2964                 glUniform1i(glGetUniformLocation(program, "g_image_1darray"), 5);
2965                 glUniform1i(glGetUniformLocation(program, "g_image_2darray"), 6);
2966
2967                 glBindVertexArray(m_vao);
2968                 glViewport(0, 0, kSize, kSize);
2969                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2970
2971                 bool status = true;
2972
2973                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
2974                 {
2975                         status = false;
2976                 }
2977
2978                 std::map<std::string, GLuint> name_index_map;
2979                 GLint uniforms;
2980                 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniforms);
2981                 if (uniforms != 7)
2982                 {
2983                         status = false;
2984                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ACTIVE_UNIFORMS is " << uniforms
2985                                                                                                 << " should be 7." << tcu::TestLog::EndMessage;
2986                 }
2987                 for (GLuint index = 0; index < static_cast<GLuint>(uniforms); ++index)
2988                 {
2989                         GLchar name[32];
2990                         glGetActiveUniformName(program, index, sizeof(name), NULL, name);
2991                         name_index_map.insert(std::make_pair(std::string(name), index));
2992                 }
2993
2994                 if (!CheckUniform(program, "g_image_1d", name_index_map, 1, ImageType<T>(GL_TEXTURE_1D)))
2995                         status = false;
2996                 if (!CheckUniform(program, "g_image_2d", name_index_map, 1, ImageType<T>(GL_TEXTURE_2D)))
2997                         status = false;
2998                 if (!CheckUniform(program, "g_image_3d", name_index_map, 1, ImageType<T>(GL_TEXTURE_3D)))
2999                         status = false;
3000                 if (!CheckUniform(program, "g_image_2drect", name_index_map, 1, ImageType<T>(GL_TEXTURE_RECTANGLE)))
3001                         status = false;
3002                 if (!CheckUniform(program, "g_image_buffer", name_index_map, 1, ImageType<T>(GL_TEXTURE_BUFFER)))
3003                         status = false;
3004                 if (!CheckUniform(program, "g_image_1darray", name_index_map, 1, ImageType<T>(GL_TEXTURE_1D_ARRAY)))
3005                         status = false;
3006                 if (!CheckUniform(program, "g_image_2darray", name_index_map, 1, ImageType<T>(GL_TEXTURE_2D_ARRAY)))
3007                         status = false;
3008
3009                 glUseProgram(0);
3010                 glDeleteProgram(program);
3011                 glDeleteTextures(7, textures);
3012                 glDeleteBuffers(1, &buffer);
3013
3014                 return status;
3015         }
3016
3017         template <typename T>
3018         bool ReadCube(GLenum internalformat, const T& value, const T& expected_value)
3019         {
3020                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
3021                                                          "  gl_Position = i_position;" NL "}";
3022                 const GLuint program =
3023                         BuildProgram(src_vs, NULL, NULL, NULL, GenFSCube(internalformat, expected_value).c_str());
3024                 GLuint textures[2];
3025                 glGenTextures(2, textures);
3026
3027                 const int         kSize = 16;
3028                 std::vector<T> data(kSize * kSize * 12, value);
3029
3030                 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[0]);
3031                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3032                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3033                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3034                                          &data[0]);
3035                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3036                                          &data[0]);
3037                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3038                                          &data[0]);
3039                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3040                                          &data[0]);
3041                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3042                                          &data[0]);
3043                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3044                                          &data[0]);
3045                 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
3046
3047                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[1]);
3048                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3049                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3050                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalformat, kSize, kSize, 12, 0, Format<T>(), Type<T>(),
3051                                          &data[0]);
3052                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
3053
3054                 glBindImageTexture(0, textures[0], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
3055                 glBindImageTexture(1, textures[1], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
3056
3057                 glClear(GL_COLOR_BUFFER_BIT);
3058
3059                 glUseProgram(program);
3060                 glUniform1i(glGetUniformLocation(program, "g_image_cube"), 0);
3061                 glUniform1i(glGetUniformLocation(program, "g_image_cube_array"), 1);
3062
3063                 glBindVertexArray(m_vao);
3064                 glViewport(0, 0, kSize, kSize);
3065                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3066
3067                 bool status = true;
3068
3069                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
3070                 {
3071                         status = false;
3072                 }
3073
3074                 std::map<std::string, GLuint> name_index_map;
3075                 GLint uniforms;
3076                 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniforms);
3077                 if (uniforms != 2)
3078                 {
3079                         status = false;
3080                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ACTIVE_UNIFORMS is " << uniforms
3081                                                                                                 << " should be 2." << tcu::TestLog::EndMessage;
3082                 }
3083                 for (GLuint index = 0; index < static_cast<GLuint>(uniforms); ++index)
3084                 {
3085                         GLchar name[32];
3086                         glGetActiveUniformName(program, index, sizeof(name), NULL, name);
3087                         name_index_map.insert(std::make_pair(std::string(name), index));
3088                 }
3089
3090                 if (!CheckUniform(program, "g_image_cube", name_index_map, 1, ImageType<T>(GL_TEXTURE_CUBE_MAP)))
3091                         status = false;
3092                 if (!CheckUniform(program, "g_image_cube_array", name_index_map, 1, ImageType<T>(GL_TEXTURE_CUBE_MAP_ARRAY)))
3093                         status = false;
3094
3095                 glUseProgram(0);
3096                 glDeleteProgram(program);
3097                 glDeleteTextures(2, textures);
3098
3099                 return status;
3100         }
3101
3102         template <typename T>
3103         std::string GenFS(GLenum internalformat, const T& expected_value)
3104         {
3105                 std::ostringstream os;
3106                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3107                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
3108                    << "image1D g_image_1d;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
3109                    << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat)
3110                    << ") readonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout("
3111                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
3112                    << "image2DRect g_image_2drect;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
3113                    << TypePrefix<T>() << "imageBuffer g_image_buffer;" NL "layout(" << FormatEnumToString(internalformat)
3114                    << ") readonly uniform " << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout("
3115                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
3116                    << "image2DArray g_image_2darray;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3117                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  "
3118                    << TypePrefix<T>()
3119                    << "vec4 v;" NL "  v = imageLoad(g_image_1d, coord.x);" NL "  if (v != " << TypePrefix<T>() << "vec4"
3120                    << expected_value
3121                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.05);" NL "  v = imageLoad(g_image_2d, coord);" NL "  if (v != "
3122                    << TypePrefix<T>() << "vec4" << expected_value
3123                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  v = imageLoad(g_image_3d, ivec3(coord.xy, 0));" NL
3124                           "  if (v != "
3125                    << TypePrefix<T>() << "vec4" << expected_value
3126                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.15);" NL "  v = imageLoad(g_image_3d, ivec3(coord.xy, 1));" NL
3127                           "  if (v != "
3128                    << TypePrefix<T>() << "vec4" << expected_value
3129                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  v = imageLoad(g_image_2drect, coord);" NL "  if (v != "
3130                    << TypePrefix<T>() << "vec4" << expected_value
3131                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.25);" NL "  v = imageLoad(g_image_buffer, coord.x);" NL "  if (v != "
3132                    << TypePrefix<T>() << "vec4" << expected_value
3133                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.6);" NL "  v = imageLoad(g_image_1darray, ivec2(coord.x, 0));" NL
3134                           "  if (v != "
3135                    << TypePrefix<T>() << "vec4" << expected_value
3136                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.65);" NL "  v = imageLoad(g_image_1darray, ivec2(coord.x, 1));" NL
3137                           "  if (v != "
3138                    << TypePrefix<T>() << "vec4" << expected_value
3139                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.7);" NL "  v = imageLoad(g_image_2darray, ivec3(coord, 0));" NL
3140                           "  if (v != "
3141                    << TypePrefix<T>() << "vec4" << expected_value
3142                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.75);" NL "  v = imageLoad(g_image_2darray, ivec3(coord, 1));" NL
3143                           "  if (v != "
3144                    << TypePrefix<T>() << "vec4" << expected_value << ") o_color = vec4(1.0, 0.0, 0.0, 0.8);" NL "}";
3145                 return os.str();
3146         }
3147
3148         template <typename T>
3149         std::string GenFSCube(GLenum internalformat, const T& expected_value)
3150         {
3151                 std::ostringstream os;
3152                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3153                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
3154                    << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
3155                    << TypePrefix<T>()
3156                    << "imageCubeArray g_image_cube_array;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3157                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  "
3158                    << TypePrefix<T>()
3159                    << "vec4 v;" NL "  v = imageLoad(g_image_cube, ivec3(coord, 0));" NL "  if (v != " << TypePrefix<T>()
3160                    << "vec4" << expected_value << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL
3161                                                                                   "  v = imageLoad(g_image_cube, ivec3(coord, 1));" NL "  if (v != "
3162                    << TypePrefix<T>() << "vec4" << expected_value
3163                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.35);" NL "  v = imageLoad(g_image_cube, ivec3(coord, 2));" NL
3164                           "  if (v != "
3165                    << TypePrefix<T>() << "vec4" << expected_value
3166                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.4);" NL "  v = imageLoad(g_image_cube, ivec3(coord, 3));" NL
3167                           "  if (v != "
3168                    << TypePrefix<T>() << "vec4" << expected_value
3169                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.45);" NL "  v = imageLoad(g_image_cube, ivec3(coord, 4));" NL
3170                           "  if (v != "
3171                    << TypePrefix<T>() << "vec4" << expected_value
3172                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.5);" NL "  v = imageLoad(g_image_cube, ivec3(coord, 5));" NL
3173                           "  if (v != "
3174                    << TypePrefix<T>() << "vec4" << expected_value
3175                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.55);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 0));" NL
3176                           "  if (v != "
3177                    << TypePrefix<T>() << "vec4" << expected_value
3178                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.05);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 1));" NL
3179                           "  if (v != "
3180                    << TypePrefix<T>() << "vec4" << expected_value
3181                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 2));" NL
3182                           "  if (v != "
3183                    << TypePrefix<T>() << "vec4" << expected_value
3184                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.15);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 3));" NL
3185                           "  if (v != "
3186                    << TypePrefix<T>() << "vec4" << expected_value
3187                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 4));" NL
3188                           "  if (v != "
3189                    << TypePrefix<T>() << "vec4" << expected_value
3190                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.25);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 5));" NL
3191                           "  if (v != "
3192                    << TypePrefix<T>() << "vec4" << expected_value
3193                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 6));" NL
3194                           "  if (v != "
3195                    << TypePrefix<T>() << "vec4" << expected_value
3196                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.35);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 7));" NL
3197                           "  if (v != "
3198                    << TypePrefix<T>() << "vec4" << expected_value
3199                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.4);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 8));" NL
3200                           "  if (v != "
3201                    << TypePrefix<T>() << "vec4" << expected_value
3202                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.45);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 9));" NL
3203                           "  if (v != "
3204                    << TypePrefix<T>() << "vec4" << expected_value
3205                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.5);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 10));" NL
3206                           "  if (v != "
3207                    << TypePrefix<T>() << "vec4" << expected_value
3208                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.55);" NL "  v = imageLoad(g_image_cube_array, ivec3(coord, 11));" NL
3209                           "  if (v != "
3210                    << TypePrefix<T>() << "vec4" << expected_value << ") o_color = vec4(1.0, 0.0, 0.0, 0.6);" NL "}";
3211                 return os.str();
3212         }
3213 };
3214 //-----------------------------------------------------------------------------
3215 // 1.3.2.2 BasicAllTargetsLoadMS
3216 //-----------------------------------------------------------------------------
3217 class BasicAllTargetsLoadMS : public ShaderImageLoadStoreBase
3218 {
3219         GLuint m_vao;
3220         GLuint m_vbo;
3221
3222         virtual long Setup()
3223         {
3224                 m_vao = 0;
3225                 m_vbo = 0;
3226                 return NO_ERROR;
3227         }
3228
3229         virtual long Run()
3230         {
3231                 if (!SupportedSamples(4))
3232                         return NOT_SUPPORTED;
3233
3234                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
3235
3236                 if (!ReadMS(GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f)))
3237                         return ERROR;
3238
3239                 GLint isamples;
3240                 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &isamples);
3241                 if (isamples >= 4)
3242                 {
3243                         if (!ReadMS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
3244                                 return ERROR;
3245                         if (!ReadMS(GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
3246                                 return ERROR;
3247                 }
3248
3249                 return NO_ERROR;
3250         }
3251
3252         virtual long Cleanup()
3253         {
3254                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
3255                 glDeleteVertexArrays(1, &m_vao);
3256                 glDeleteBuffers(1, &m_vbo);
3257                 return NO_ERROR;
3258         }
3259
3260         template <typename T>
3261         bool ReadMS(GLenum internalformat, const T& value, const T& expected_value)
3262         {
3263                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
3264                                                          "  gl_Position = i_position;" NL "}";
3265                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFSMS(internalformat, expected_value).c_str());
3266                 GLuint           textures[2];
3267                 glGenTextures(2, textures);
3268
3269                 const int kSize = 16;
3270
3271                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures[0]);
3272                 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, internalformat, kSize, kSize, GL_FALSE);
3273                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
3274
3275                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures[1]);
3276                 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 4, internalformat, kSize, kSize, 2, GL_FALSE);
3277                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
3278
3279                 GLuint fbo;
3280                 glGenFramebuffers(1, &fbo);
3281                 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3282                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textures[0], 0);
3283                 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textures[1], 0, 0);
3284                 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, textures[1], 0, 1);
3285                 const GLenum draw_buffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
3286                 glDrawBuffers(3, draw_buffers);
3287                 ClearBuffer(GL_COLOR, 0, value);
3288                 ClearBuffer(GL_COLOR, 1, value);
3289                 ClearBuffer(GL_COLOR, 2, value);
3290                 glDeleteFramebuffers(1, &fbo);
3291
3292                 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
3293                 glBindImageTexture(4, textures[1], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
3294
3295                 glUseProgram(program);
3296                 glUniform1i(glGetUniformLocation(program, "g_image_2dms"), 1);
3297                 glUniform1i(glGetUniformLocation(program, "g_image_2dms_array"), 4);
3298
3299                 glClear(GL_COLOR_BUFFER_BIT);
3300                 glBindVertexArray(m_vao);
3301                 glViewport(0, 0, kSize, kSize);
3302                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3303
3304                 bool status = true;
3305
3306                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
3307                 {
3308                         status = false;
3309                 }
3310
3311                 std::map<std::string, GLuint> name_index_map;
3312                 GLint uniforms;
3313                 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniforms);
3314                 if (uniforms != 2)
3315                 {
3316                         status = false;
3317                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "ACTIVE_UNIFORMS is " << uniforms
3318                                                                                                 << " should be 2." << tcu::TestLog::EndMessage;
3319                 }
3320                 for (GLuint index = 0; index < static_cast<GLuint>(uniforms); ++index)
3321                 {
3322                         GLchar name[32];
3323                         glGetActiveUniformName(program, index, sizeof(name), NULL, name);
3324                         name_index_map.insert(std::make_pair(std::string(name), index));
3325                 }
3326
3327                 if (!CheckUniform(program, "g_image_2dms", name_index_map, 1, ImageType<T>(GL_TEXTURE_2D_MULTISAMPLE)))
3328                         status = false;
3329                 if (!CheckUniform(program, "g_image_2dms_array", name_index_map, 1,
3330                                                   ImageType<T>(GL_TEXTURE_2D_MULTISAMPLE_ARRAY)))
3331                         status = false;
3332
3333                 glDeleteTextures(2, textures);
3334                 glUseProgram(0);
3335                 glDeleteProgram(program);
3336
3337                 return status;
3338         }
3339
3340         template <typename T>
3341         std::string GenFSMS(GLenum internalformat, const T& expected_value)
3342         {
3343                 std::ostringstream os;
3344                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3345                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
3346                    << "image2DMS g_image_2dms;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
3347                    << TypePrefix<T>()
3348                    << "image2DMSArray g_image_2dms_array;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3349                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  if (imageLoad(g_image_2dms, coord, 0) != "
3350                    << TypePrefix<T>() << "vec4" << expected_value
3351                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (imageLoad(g_image_2dms, coord, 1) != "
3352                    << TypePrefix<T>() << "vec4" << expected_value
3353                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (imageLoad(g_image_2dms, coord, 2) != "
3354                    << TypePrefix<T>() << "vec4" << expected_value
3355                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (imageLoad(g_image_2dms, coord, 3) != "
3356                    << TypePrefix<T>() << "vec4" << expected_value
3357                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 0), 0) != "
3358                    << TypePrefix<T>() << "vec4" << expected_value
3359                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 0), 1) != "
3360                    << TypePrefix<T>() << "vec4" << expected_value
3361                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 0), 2) != "
3362                    << TypePrefix<T>() << "vec4" << expected_value
3363                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 0), 3) != "
3364                    << TypePrefix<T>() << "vec4" << expected_value
3365                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 1), 0) != "
3366                    << TypePrefix<T>() << "vec4" << expected_value
3367                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 1), 1) != "
3368                    << TypePrefix<T>() << "vec4" << expected_value
3369                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 1), 2) != "
3370                    << TypePrefix<T>() << "vec4" << expected_value
3371                    << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "  if (imageLoad(g_image_2dms_array, ivec3(coord, 1), 3) != "
3372                    << TypePrefix<T>() << "vec4" << expected_value << ") o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL "}";
3373                 return os.str();
3374         }
3375 };
3376 //-----------------------------------------------------------------------------
3377 // 1.3.3 BasicAllTargetsAtomic
3378 //-----------------------------------------------------------------------------
3379 class BasicAllTargetsAtomic : public ShaderImageLoadStoreBase
3380 {
3381         GLuint m_vao;
3382         GLuint m_vbo;
3383
3384         virtual long Setup()
3385         {
3386                 m_vao = 0;
3387                 m_vbo = 0;
3388                 return NO_ERROR;
3389         }
3390
3391         virtual long Run()
3392         {
3393                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
3394
3395                 if (!Atomic<GLint>(GL_R32I))
3396                         return ERROR;
3397                 if (!Atomic<GLuint>(GL_R32UI))
3398                         return ERROR;
3399
3400                 if (!AtomicCube<GLint>(GL_R32I))
3401                         return ERROR;
3402                 if (!AtomicCube<GLuint>(GL_R32UI))
3403                         return ERROR;
3404
3405                 GLint isamples;
3406                 glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &isamples);
3407                 if (SupportedSamples(4) && isamples >= 4)
3408                 {
3409                         if (!AtomicMS<GLint>(GL_R32I))
3410                                 return ERROR;
3411                         if (!AtomicMS<GLuint>(GL_R32UI))
3412                                 return ERROR;
3413                 }
3414
3415                 return NO_ERROR;
3416         }
3417
3418         virtual long Cleanup()
3419         {
3420                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
3421                 glDeleteVertexArrays(1, &m_vao);
3422                 glDeleteBuffers(1, &m_vbo);
3423                 return NO_ERROR;
3424         }
3425
3426         template <typename T>
3427         bool Atomic(GLenum internalformat)
3428         {
3429                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
3430                                                          "  gl_Position = i_position;" NL "}";
3431                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFS<T>(internalformat).c_str());
3432                 GLuint           textures[7];
3433                 GLuint           buffer;
3434                 glGenTextures(7, textures);
3435                 glGenBuffers(1, &buffer);
3436
3437                 const int         kSize = 16;
3438                 std::vector<T> data(kSize * kSize * 2);
3439
3440                 glBindTexture(GL_TEXTURE_1D, textures[0]);
3441                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3442                 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3443                 glTexImage1D(GL_TEXTURE_1D, 0, internalformat, kSize, 0, Format<T>(), Type<T>(), &data[0]);
3444                 glBindTexture(GL_TEXTURE_1D, 0);
3445
3446                 glBindTexture(GL_TEXTURE_2D, textures[1]);
3447                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3448                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3449                 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
3450                 glBindTexture(GL_TEXTURE_2D, 0);
3451
3452                 glBindTexture(GL_TEXTURE_3D, textures[2]);
3453                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3454                 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3455                 glTexImage3D(GL_TEXTURE_3D, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
3456                 glBindTexture(GL_TEXTURE_3D, 0);
3457
3458                 glBindTexture(GL_TEXTURE_RECTANGLE, textures[3]);
3459                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3460                 glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3461                 glTexImage2D(GL_TEXTURE_RECTANGLE, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(), &data[0]);
3462                 glBindTexture(GL_TEXTURE_RECTANGLE, 0);
3463
3464                 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
3465                 glBufferData(GL_TEXTURE_BUFFER, kSize * sizeof(T), &data[0], GL_DYNAMIC_DRAW);
3466                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
3467                 glBindTexture(GL_TEXTURE_BUFFER, textures[4]);
3468                 glTexBuffer(GL_TEXTURE_BUFFER, internalformat, buffer);
3469                 glBindTexture(GL_TEXTURE_BUFFER, 0);
3470
3471                 glBindTexture(GL_TEXTURE_1D_ARRAY, textures[5]);
3472                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3473                 glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3474                 glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, internalformat, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
3475                 glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
3476
3477                 glBindTexture(GL_TEXTURE_2D_ARRAY, textures[6]);
3478                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3479                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3480                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internalformat, kSize, kSize, 2, 0, Format<T>(), Type<T>(), &data[0]);
3481                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
3482
3483                 glBindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
3484                 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
3485                 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3486                 glBindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
3487                 glBindImageTexture(4, textures[4], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
3488                 glBindImageTexture(5, textures[5], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3489                 glBindImageTexture(6, textures[6], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3490
3491                 glClear(GL_COLOR_BUFFER_BIT);
3492
3493                 glUseProgram(program);
3494                 glUniform1i(glGetUniformLocation(program, "g_image_1d"), 0);
3495                 glUniform1i(glGetUniformLocation(program, "g_image_2d"), 1);
3496                 glUniform1i(glGetUniformLocation(program, "g_image_3d"), 2);
3497                 glUniform1i(glGetUniformLocation(program, "g_image_2drect"), 3);
3498                 glUniform1i(glGetUniformLocation(program, "g_image_buffer"), 4);
3499                 glUniform1i(glGetUniformLocation(program, "g_image_1darray"), 5);
3500                 glUniform1i(glGetUniformLocation(program, "g_image_2darray"), 6);
3501
3502                 glBindVertexArray(m_vao);
3503                 glViewport(0, 0, kSize, 1);
3504                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3505
3506                 bool status = true;
3507
3508                 if (!ValidateReadBuffer(0, 0, kSize, 1, vec4(0, 1, 0, 1)))
3509                 {
3510                         status = false;
3511                 }
3512
3513                 glUseProgram(0);
3514                 glDeleteProgram(program);
3515                 glDeleteTextures(7, textures);
3516                 glDeleteBuffers(1, &buffer);
3517
3518                 return status;
3519         }
3520
3521         template <typename T>
3522         bool AtomicCube(GLenum internalformat)
3523         {
3524                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
3525                                                          "  gl_Position = i_position;" NL "}";
3526                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFSCube<T>(internalformat).c_str());
3527                 GLuint           textures[2];
3528                 glGenTextures(2, textures);
3529
3530                 const int         kSize = 16;
3531                 std::vector<T> data(kSize * kSize * 12);
3532
3533                 glBindTexture(GL_TEXTURE_CUBE_MAP, textures[0]);
3534                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3535                 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3536                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3537                                          &data[0]);
3538                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3539                                          &data[0]);
3540                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3541                                          &data[0]);
3542                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3543                                          &data[0]);
3544                 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3545                                          &data[0]);
3546                 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, internalformat, kSize, kSize, 0, Format<T>(), Type<T>(),
3547                                          &data[0]);
3548                 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
3549
3550                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textures[1]);
3551                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3552                 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3553                 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, internalformat, kSize, kSize, 12, 0, Format<T>(), Type<T>(),
3554                                          &data[0]);
3555                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
3556
3557                 glBindImageTexture(0, textures[0], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3558                 glBindImageTexture(1, textures[1], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3559
3560                 glClear(GL_COLOR_BUFFER_BIT);
3561
3562                 glUseProgram(program);
3563                 glUniform1i(glGetUniformLocation(program, "g_image_cube"), 0);
3564                 glUniform1i(glGetUniformLocation(program, "g_image_cube_array"), 1);
3565
3566                 glBindVertexArray(m_vao);
3567                 glViewport(0, 0, kSize, kSize);
3568                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3569
3570                 bool status = true;
3571
3572                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
3573                 {
3574                         status = false;
3575                 }
3576
3577                 glUseProgram(0);
3578                 glDeleteProgram(program);
3579                 glDeleteTextures(2, textures);
3580
3581                 return status;
3582         }
3583
3584         template <typename T>
3585         bool AtomicMS(GLenum internalformat)
3586         {
3587                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
3588                                                          "  gl_Position = i_position;" NL "}";
3589                 const GLuint program = BuildProgram(src_vs, NULL, NULL, NULL, GenFSMS<T>(internalformat).c_str());
3590                 GLuint           textures[2];
3591                 glGenTextures(2, textures);
3592
3593                 const int kSize = 16;
3594
3595                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textures[0]);
3596                 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, internalformat, kSize, kSize, GL_FALSE);
3597                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
3598
3599                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, textures[1]);
3600                 glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 4, internalformat, kSize, kSize, 2, GL_FALSE);
3601                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
3602
3603                 GLuint fbo;
3604                 glGenFramebuffers(1, &fbo);
3605                 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3606                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textures[0], 0);
3607                 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textures[1], 0, 0);
3608                 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, textures[1], 0, 1);
3609                 const GLenum draw_buffers[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
3610                 glDrawBuffers(3, draw_buffers);
3611                 if (internalformat == GL_R32I)
3612                 {
3613                         const GLint value[4] = { 0, 0, 0, 0 };
3614                         glClearBufferiv(GL_COLOR, 0, value);
3615                         glClearBufferiv(GL_COLOR, 1, value);
3616                         glClearBufferiv(GL_COLOR, 2, value);
3617                 }
3618                 else
3619                 {
3620                         const GLuint value[4] = { 0, 0, 0, 0 };
3621                         glClearBufferuiv(GL_COLOR, 0, value);
3622                         glClearBufferuiv(GL_COLOR, 1, value);
3623                         glClearBufferuiv(GL_COLOR, 2, value);
3624                 }
3625                 glDeleteFramebuffers(1, &fbo);
3626
3627                 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
3628                 glBindImageTexture(4, textures[1], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
3629
3630                 glUseProgram(program);
3631                 glUniform1i(glGetUniformLocation(program, "g_image_2dms"), 1);
3632                 glUniform1i(glGetUniformLocation(program, "g_image_2dms_array"), 4);
3633
3634                 glClear(GL_COLOR_BUFFER_BIT);
3635                 glBindVertexArray(m_vao);
3636                 glViewport(0, 0, kSize, kSize);
3637                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3638
3639                 bool status = true;
3640
3641                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
3642                 {
3643                         status = false;
3644                 }
3645
3646                 glDeleteTextures(2, textures);
3647                 glUseProgram(0);
3648                 glDeleteProgram(program);
3649
3650                 return status;
3651         }
3652
3653         template <typename T>
3654         std::string GenFS(GLenum internalformat)
3655         {
3656                 std::ostringstream os;
3657                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3658                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
3659                    << "image1D g_image_1d;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
3660                    << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat)
3661                    << ") coherent uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout("
3662                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
3663                    << "image2DRect g_image_2drect;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
3664                    << TypePrefix<T>() << "imageBuffer g_image_buffer;" NL "layout(" << FormatEnumToString(internalformat)
3665                    << ") coherent uniform " << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout("
3666                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
3667                    << "image2DArray g_image_2darray;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3668                           "  ivec2 coord = ivec2(gl_FragCoord.xy);"
3669
3670                         NL "  if (imageAtomicAdd(g_image_1d, coord.x, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3671                           "  if (imageAtomicMin(g_image_1d, coord.x, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3672                           "  if (imageAtomicMax(g_image_1d, coord.x, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3673                           "  if (imageAtomicAnd(g_image_1d, coord.x, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3674                           "  if (imageAtomicOr(g_image_1d, coord.x, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3675                           "  if (imageAtomicXor(g_image_1d, coord.x, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3676                           "  if (imageAtomicExchange(g_image_1d, coord.x, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3677                           "  if (imageAtomicCompSwap(g_image_1d, coord.x, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3678                           "  if (imageAtomicExchange(g_image_1d, coord.x, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3679
3680                         NL "  if (imageAtomicAdd(g_image_2d, coord, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3681                           "  if (imageAtomicMin(g_image_2d, coord, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3682                           "  if (imageAtomicMax(g_image_2d, coord, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3683                           "  if (imageAtomicAnd(g_image_2d, coord, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3684                           "  if (imageAtomicOr(g_image_2d, coord, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3685                           "  if (imageAtomicXor(g_image_2d, coord, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3686                           "  if (imageAtomicExchange(g_image_2d, coord, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3687                           "  if (imageAtomicCompSwap(g_image_2d, coord, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3688                           "  if (imageAtomicExchange(g_image_2d, coord, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3689
3690                         NL "  if (imageAtomicAdd(g_image_3d, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3691                           "  if (imageAtomicMin(g_image_3d, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3692                           "  if (imageAtomicMax(g_image_3d, ivec3(coord, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3693                           "  if (imageAtomicAnd(g_image_3d, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3694                           "  if (imageAtomicOr(g_image_3d, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3695                           "  if (imageAtomicXor(g_image_3d, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3696                           "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3697                           "  if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 0), 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, "
3698                           "1.0);" NL
3699                           "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3700
3701                         NL "  if (imageAtomicAdd(g_image_2drect, coord, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3702                           "  if (imageAtomicMin(g_image_2drect, coord, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3703                           "  if (imageAtomicMax(g_image_2drect, coord, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3704                           "  if (imageAtomicAnd(g_image_2drect, coord, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3705                           "  if (imageAtomicOr(g_image_2drect, coord, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3706                           "  if (imageAtomicXor(g_image_2drect, coord, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3707                           "  if (imageAtomicExchange(g_image_2drect, coord, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3708                           "  if (imageAtomicCompSwap(g_image_2drect, coord, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3709                           "  if (imageAtomicExchange(g_image_2drect, coord, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3710
3711                         NL "  if (imageAtomicAdd(g_image_buffer, coord.x, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3712                           "  if (imageAtomicMin(g_image_buffer, coord.x, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3713                           "  if (imageAtomicMax(g_image_buffer, coord.x, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3714                           "  if (imageAtomicAnd(g_image_buffer, coord.x, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3715                           "  if (imageAtomicOr(g_image_buffer, coord.x, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3716                           "  if (imageAtomicXor(g_image_buffer, coord.x, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3717                           "  if (imageAtomicExchange(g_image_buffer, coord.x, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3718                           "  if (imageAtomicCompSwap(g_image_buffer, coord.x, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3719                           "  if (imageAtomicExchange(g_image_buffer, coord.x, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3720
3721                         NL
3722                           "  if (imageAtomicAdd(g_image_1darray, ivec2(coord.x, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3723                           "  if (imageAtomicMin(g_image_1darray, ivec2(coord.x, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3724                           "  if (imageAtomicMax(g_image_1darray, ivec2(coord.x, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3725                           "  if (imageAtomicAnd(g_image_1darray, ivec2(coord.x, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3726                           "  if (imageAtomicOr(g_image_1darray, ivec2(coord.x, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3727                           "  if (imageAtomicXor(g_image_1darray, ivec2(coord.x, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3728                           "  if (imageAtomicExchange(g_image_1darray, ivec2(coord.x, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, "
3729                           "1.0);" NL "  if (imageAtomicCompSwap(g_image_1darray, ivec2(coord.x, 0), 1, 6) != 1) o_color = "
3730                           "vec4(1.0, 0.0, 0.0, 1.0);" NL "  if (imageAtomicExchange(g_image_1darray, ivec2(coord.x, 0), "
3731                           "0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3732
3733                         NL "  if (imageAtomicAdd(g_image_2darray, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3734                           "  if (imageAtomicMin(g_image_2darray, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3735                           "  if (imageAtomicMax(g_image_2darray, ivec3(coord, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3736                           "  if (imageAtomicAnd(g_image_2darray, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3737                           "  if (imageAtomicOr(g_image_2darray, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3738                           "  if (imageAtomicXor(g_image_2darray, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3739                           "  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, "
3740                           "1.0);" NL "  if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 0), 1, 6) != 1) o_color = vec4(1.0, "
3741                           "0.0, 0.0, 1.0);" NL "  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), 0) != 6) "
3742                           "o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
3743                 return os.str();
3744         }
3745
3746         template <typename T>
3747         std::string GenFSCube(GLenum internalformat)
3748         {
3749                 std::ostringstream os;
3750                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3751                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
3752                    << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
3753                    << TypePrefix<T>()
3754                    << "imageCube g_image_cube_array;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3755                           "  ivec2 coord = ivec2(gl_FragCoord.xy);"
3756
3757                         NL "  if (imageAtomicAdd(g_image_cube, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3758                           "  if (imageAtomicMin(g_image_cube, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3759                           "  if (imageAtomicMax(g_image_cube, ivec3(coord, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3760                           "  if (imageAtomicAnd(g_image_cube, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3761                           "  if (imageAtomicOr(g_image_cube, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3762                           "  if (imageAtomicXor(g_image_cube, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3763                           "  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3764                           "  if (imageAtomicCompSwap(g_image_cube, ivec3(coord, 0), 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, "
3765                           "1.0);" NL
3766                           "  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
3767
3768                         NL "  if (imageAtomicAdd(g_image_cube_array, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, "
3769                           "1.0);" NL "  if (imageAtomicMin(g_image_cube_array, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, "
3770                           "0.0, 1.0);" NL "  if (imageAtomicMax(g_image_cube_array, ivec3(coord, 0), 4) != 2) o_color "
3771                           "= vec4(1.0, 0.0, 0.0, 1.0);" NL "  if (imageAtomicAnd(g_image_cube_array, "
3772                           "ivec3(coord, 0), 0) != 4) o_color = "
3773                           "vec4(1.0, 0.0, 0.0, 1.0);" NL
3774                           "  if (imageAtomicOr(g_image_cube_array, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3775                           "  if (imageAtomicXor(g_image_cube_array, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, "
3776                           "1.0);" NL "  if (imageAtomicExchange(g_image_cube_array, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, "
3777                           "0.0, 0.0, 1.0);" NL "  if (imageAtomicCompSwap(g_image_cube_array, ivec3(coord, 0), 1, 6) != "
3778                           "1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3779                           "  if (imageAtomicExchange(g_image_cube_array, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, "
3780                           "1.0);" NL "}";
3781                 return os.str();
3782         }
3783
3784         template <typename T>
3785         std::string GenFSMS(GLenum internalformat)
3786         {
3787                 std::ostringstream os;
3788                 os << "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "layout("
3789                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
3790                    << "image2DMS g_image_2dms;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
3791                    << TypePrefix<T>()
3792                    << "image2DMSArray g_image_2dms_array;" NL "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
3793                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
3794                           "  if (imageAtomicAdd(g_image_2dms, coord, 1, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3795                           "  if (imageAtomicMin(g_image_2dms, coord, 1, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3796                           "  if (imageAtomicMax(g_image_2dms, coord, 1, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3797                           "  if (imageAtomicAnd(g_image_2dms, coord, 1, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3798                           "  if (imageAtomicOr(g_image_2dms, coord, 1, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3799                           "  if (imageAtomicXor(g_image_2dms, coord, 1, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3800                           "  if (imageAtomicExchange(g_image_2dms, coord, 1, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3801                           "  if (imageAtomicCompSwap(g_image_2dms, coord, 1, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3802                           "  if (imageAtomicExchange(g_image_2dms, coord, 1, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL NL
3803                           "  if (imageAtomicAdd(g_image_2dms_array, ivec3(coord, 1), 1, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, "
3804                           "1.0);" NL "  if (imageAtomicMin(g_image_2dms_array, ivec3(coord, 1), 1, 3) != 2) o_color = vec4(1.0, "
3805                           "0.0, 0.0, 1.0);" NL "  if (imageAtomicMax(g_image_2dms_array, ivec3(coord, 1), 1, 4) != 2) "
3806                           "o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3807                           "  if (imageAtomicAnd(g_image_2dms_array, ivec3(coord, 1), 1, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, "
3808                           "1.0);" NL "  if (imageAtomicOr(g_image_2dms_array, ivec3(coord, 1), 1, 7) != 0) o_color = vec4(1.0, "
3809                           "0.0, 0.0, 1.0);" NL "  if (imageAtomicXor(g_image_2dms_array, ivec3(coord, 1), 1, 4) != 7) "
3810                           "o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
3811                           "  if (imageAtomicExchange(g_image_2dms_array, ivec3(coord, 1), 1, 1) != 3) o_color = vec4(1.0, 0.0, "
3812                           "0.0, 1.0);" NL "  if (imageAtomicCompSwap(g_image_2dms_array, ivec3(coord, 1), 1, 1, 6) != 1) o_color = "
3813                           "vec4(1.0, 0.0, 0.0, 1.0);" NL "  if (imageAtomicExchange(g_image_2dms_array, "
3814                           "ivec3(coord, 1), 1, 0) != 6) o_color = vec4(1.0, 0.0, "
3815                           "0.0, 1.0);" NL "}";
3816                 return os.str();
3817         }
3818 };
3819 //-----------------------------------------------------------------------------
3820 // LoadStoreMachine
3821 //-----------------------------------------------------------------------------
3822 class LoadStoreMachine : public ShaderImageLoadStoreBase
3823 {
3824         GLuint m_vao;
3825         int     m_stage;
3826
3827         virtual long Setup()
3828         {
3829                 glGenVertexArrays(1, &m_vao);
3830                 return NO_ERROR;
3831         }
3832
3833         virtual long Cleanup()
3834         {
3835                 glDisable(GL_RASTERIZER_DISCARD);
3836                 glDeleteVertexArrays(1, &m_vao);
3837                 return NO_ERROR;
3838         }
3839
3840         template <typename T>
3841         bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
3842         {
3843                 const GLenum targets[] = { GL_TEXTURE_1D,               GL_TEXTURE_2D,
3844                                                                    GL_TEXTURE_3D,               GL_TEXTURE_RECTANGLE,
3845                                                                    GL_TEXTURE_CUBE_MAP, GL_TEXTURE_1D_ARRAY,
3846                                                                    GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY };
3847                 const int kTargets              = sizeof(targets) / sizeof(targets[0]);
3848                 GLuint  program_store = 0;
3849                 GLuint  program_load  = 0;
3850                 if (m_stage == 0)
3851                 { // VS
3852                         program_store =
3853                                 BuildProgram(GenStoreShader(m_stage, internalformat, write_value).c_str(), NULL, NULL, NULL, NULL);
3854                         program_load =
3855                                 BuildProgram(GenLoadShader(m_stage, internalformat, expected_value).c_str(), NULL, NULL, NULL, NULL);
3856                 }
3857                 else if (m_stage == 1)
3858                 { // TCS
3859                         const char* const glsl_vs  = "#version 420 core" NL "void main() {}";
3860                         const char* const glsl_tes = "#version 420 core" NL "layout(quads, point_mode) in;" NL "void main() {}";
3861                         program_store = BuildProgram(glsl_vs, GenStoreShader(m_stage, internalformat, write_value).c_str(),
3862                                                                                  glsl_tes, NULL, NULL);
3863                         program_load = BuildProgram(glsl_vs, GenLoadShader(m_stage, internalformat, expected_value).c_str(),
3864                                                                                 glsl_tes, NULL, NULL);
3865                 }
3866                 else if (m_stage == 2)
3867                 { // TES
3868                         const char* const glsl_vs = "#version 420 core" NL "void main() {}";
3869                         program_store =
3870                                 BuildProgram(glsl_vs, NULL, GenStoreShader(m_stage, internalformat, write_value).c_str(), NULL, NULL);
3871                         program_load =
3872                                 BuildProgram(glsl_vs, NULL, GenLoadShader(m_stage, internalformat, expected_value).c_str(), NULL, NULL);
3873                 }
3874                 else if (m_stage == 3)
3875                 { // GS
3876                         const char* const glsl_vs = "#version 420 core" NL "void main() {}";
3877                         program_store =
3878                                 BuildProgram(glsl_vs, NULL, NULL, GenStoreShader(m_stage, internalformat, write_value).c_str(), NULL);
3879                         program_load =
3880                                 BuildProgram(glsl_vs, NULL, NULL, GenLoadShader(m_stage, internalformat, expected_value).c_str(), NULL);
3881                 }
3882                 else if (m_stage == 4)
3883                 { // CS
3884                         {
3885                                 std::string               source = GenStoreShader(m_stage, internalformat, write_value);
3886                                 const char* const src   = source.c_str();
3887                                 GLuint                    sh     = glCreateShader(GL_COMPUTE_SHADER);
3888                                 glShaderSource(sh, 1, &src, NULL);
3889                                 glCompileShader(sh);
3890                                 program_store = glCreateProgram();
3891                                 glAttachShader(program_store, sh);
3892                                 glLinkProgram(program_store);
3893                                 glDeleteShader(sh);
3894                         }
3895                         {
3896                                 std::string               source = GenLoadShader(m_stage, internalformat, expected_value);
3897                                 const char* const src   = source.c_str();
3898                                 GLuint                    sh     = glCreateShader(GL_COMPUTE_SHADER);
3899                                 glShaderSource(sh, 1, &src, NULL);
3900                                 glCompileShader(sh);
3901                                 program_load = glCreateProgram();
3902                                 glAttachShader(program_load, sh);
3903                                 glLinkProgram(program_load);
3904                                 glDeleteShader(sh);
3905                         }
3906                 }
3907                 GLuint textures[kTargets], texture_result;
3908                 glGenTextures(kTargets, textures);
3909                 glGenTextures(1, &texture_result);
3910
3911                 glBindTexture(GL_TEXTURE_2D, texture_result);
3912                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3913                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3914                 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
3915
3916                 for (int i = 0; i < kTargets; ++i)
3917                 {
3918                         glBindTexture(targets[i], textures[i]);
3919                         glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3920                         glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3921
3922                         if (targets[i] == GL_TEXTURE_1D)
3923                         {
3924                                 glTexStorage1D(targets[i], 1, internalformat, 1);
3925                         }
3926                         else if (targets[i] == GL_TEXTURE_2D || targets[i] == GL_TEXTURE_RECTANGLE)
3927                         {
3928                                 glTexStorage2D(targets[i], 1, internalformat, 1, 1);
3929                         }
3930                         else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY)
3931                         {
3932                                 glTexStorage3D(targets[i], 1, internalformat, 1, 1, 2);
3933                         }
3934                         else if (targets[i] == GL_TEXTURE_CUBE_MAP)
3935                         {
3936                                 glTexStorage2D(targets[i], 1, internalformat, 1, 1);
3937                         }
3938                         else if (targets[i] == GL_TEXTURE_CUBE_MAP_ARRAY)
3939                         {
3940                                 glTexStorage3D(targets[i], 1, internalformat, 1, 1, 12);
3941                         }
3942                         else if (targets[i] == GL_TEXTURE_1D_ARRAY)
3943                         {
3944                                 glTexStorage2D(targets[i], 1, internalformat, 1, 2);
3945                         }
3946                 }
3947                 glBindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
3948                 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
3949                 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
3950                 glBindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
3951                 glBindImageTexture(4, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
3952                 glBindImageTexture(5, textures[5], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
3953                 glBindImageTexture(6, textures[6], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
3954                 glBindImageTexture(7, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
3955
3956                 glUseProgram(program_store);
3957                 glUniform1i(glGetUniformLocation(program_store, "g_image_1d"), 0);
3958                 glUniform1i(glGetUniformLocation(program_store, "g_image_2d"), 1);
3959                 glUniform1i(glGetUniformLocation(program_store, "g_image_3d"), 2);
3960                 glUniform1i(glGetUniformLocation(program_store, "g_image_2drect"), 3);
3961                 glUniform1i(glGetUniformLocation(program_store, "g_image_cube"), 4);
3962                 glUniform1i(glGetUniformLocation(program_store, "g_image_1darray"), 5);
3963                 glUniform1i(glGetUniformLocation(program_store, "g_image_2darray"), 6);
3964                 glUniform1i(glGetUniformLocation(program_store, "g_image_cube_array"), 7);
3965
3966                 glBindVertexArray(m_vao);
3967                 if (m_stage == 1 || m_stage == 2)
3968                 { // TCS or TES
3969                         glPatchParameteri(GL_PATCH_VERTICES, 1);
3970                         glDrawArrays(GL_PATCHES, 0, 1);
3971                         glPatchParameteri(GL_PATCH_VERTICES, 3);
3972                 }
3973                 else if (m_stage == 4)
3974                 { // CS
3975                         glDispatchCompute(1, 1, 1);
3976                 }
3977                 else
3978                 {
3979                         glDrawArrays(GL_POINTS, 0, 1);
3980                 }
3981
3982                 bool status = true;
3983                 for (int i = 0; i < kTargets; ++i)
3984                 {
3985                         glBindTexture(targets[i], textures[i]);
3986                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
3987
3988                         if (targets[i] == GL_TEXTURE_CUBE_MAP)
3989                         {
3990                                 for (int face = 0; face < 6; ++face)
3991                                 {
3992                                         T data;
3993                                         glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, Format<T>(), Type<T>(), &data[0]);
3994                                         if (!Equal(data, expected_value, internalformat))
3995                                         {
3996                                                 status = false;
3997                                                 m_context.getTestContext().getLog()
3998                                                         << tcu::TestLog::Message << "Value is: " << ToString(data)
3999                                                         << ". Value should be: " << ToString(expected_value)
4000                                                         << ". Format is: " << FormatEnumToString(internalformat)
4001                                                         << ". Target is: " << EnumToString(targets[i]) << ". Stage is: " << StageName(m_stage)
4002                                                         << tcu::TestLog::EndMessage;
4003                                         }
4004                                 }
4005                         }
4006                         else
4007                         {
4008                                 T data[12];
4009                                 memset(&data[0], 0, sizeof(data));
4010                                 glGetTexImage(targets[i], 0, Format<T>(), Type<T>(), &data[0]);
4011
4012                                 int count = 1;
4013                                 if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY)
4014                                         count = 2;
4015                                 else if (targets[i] == GL_TEXTURE_CUBE_MAP_ARRAY)
4016                                         count = 12;
4017                                 else if (targets[i] == GL_TEXTURE_1D_ARRAY)
4018                                         count = 2;
4019
4020                                 for (int j = 0; j < count; ++j)
4021                                 {
4022                                         if (!Equal(data[j], expected_value, internalformat))
4023                                         {
4024                                                 status = false;
4025                                                 m_context.getTestContext().getLog()
4026                                                         << tcu::TestLog::Message << "Value is: " << ToString(data[j])
4027                                                         << ". Value should be: " << ToString(expected_value)
4028                                                         << ". Format is: " << FormatEnumToString(internalformat)
4029                                                         << ". Target is: " << EnumToString(targets[i]) << ". Stage is: " << StageName(m_stage)
4030                                                         << tcu::TestLog::EndMessage;
4031                                         }
4032                                 }
4033                         }
4034                 }
4035                 glBindImageTexture(0, texture_result, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
4036                 glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
4037                 glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
4038                 glBindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
4039                 glBindImageTexture(4, textures[4], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
4040                 glBindImageTexture(5, textures[5], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
4041                 glBindImageTexture(6, textures[6], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
4042                 glBindImageTexture(7, textures[7], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
4043
4044                 glUseProgram(program_load);
4045                 glUniform1i(glGetUniformLocation(program_load, "g_image_result"), 0);
4046                 glUniform1i(glGetUniformLocation(program_load, "g_image_2d"), 1);
4047                 glUniform1i(glGetUniformLocation(program_load, "g_image_3d"), 2);
4048                 glUniform1i(glGetUniformLocation(program_load, "g_image_2drect"), 3);
4049                 glUniform1i(glGetUniformLocation(program_load, "g_image_cube"), 4);
4050                 glUniform1i(glGetUniformLocation(program_load, "g_image_1darray"), 5);
4051                 glUniform1i(glGetUniformLocation(program_load, "g_image_2darray"), 6);
4052                 glUniform1i(glGetUniformLocation(program_load, "g_image_cube_array"), 7);
4053
4054                 if (m_stage == 1 || m_stage == 2)
4055                 { // TCS or TES
4056                         glPatchParameteri(GL_PATCH_VERTICES, 1);
4057                         glDrawArrays(GL_PATCHES, 0, 1);
4058                         glPatchParameteri(GL_PATCH_VERTICES, 3);
4059                 }
4060                 else if (m_stage == 4)
4061                 { // CS
4062                         glDispatchCompute(1, 1, 1);
4063                 }
4064                 else
4065                 {
4066                         glDrawArrays(GL_POINTS, 0, 1);
4067                 }
4068                 {
4069                         vec4 color;
4070                         glBindTexture(GL_TEXTURE_2D, texture_result);
4071                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
4072                         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &color[0]);
4073                         if (!tcu::allEqual(color, vec4(0, 1, 0, 1)))
4074                         {
4075                                 status = false;
4076                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Color is: " << ToString(color)
4077                                                                                                         << ". Format is: " << FormatEnumToString(internalformat)
4078                                                                                                         << ". Stage is: " << StageName(m_stage) << tcu::TestLog::EndMessage;
4079                         }
4080                 }
4081                 glUseProgram(0);
4082                 glDeleteProgram(program_store);
4083                 glDeleteProgram(program_load);
4084                 glDeleteTextures(kTargets, textures);
4085                 glDeleteTextures(1, &texture_result);
4086                 return status;
4087         }
4088
4089         template <typename T>
4090         std::string GenStoreShader(int stage, GLenum internalformat, const T& write_value)
4091         {
4092                 std::ostringstream os;
4093                 os << "#version 420 core";
4094                 if (stage == 4)
4095                 { // CS
4096                         os << NL "#extension GL_ARB_compute_shader : require";
4097                 }
4098                 os << NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
4099                    << "image1D g_image_1d;" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
4100                    << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat)
4101                    << ") writeonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout("
4102                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
4103                    << "image2DRect g_image_2drect;" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
4104                    << TypePrefix<T>() << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat)
4105                    << ") writeonly uniform " << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout("
4106                    << FormatEnumToString(internalformat) << ") writeonly uniform " << TypePrefix<T>()
4107                    << "image2DArray g_image_2darray;" NL "layout(" << FormatEnumToString(internalformat)
4108                    << ") writeonly uniform " << TypePrefix<T>() << "imageCubeArray g_image_cube_array;" NL "uniform "
4109                    << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4" << write_value
4110                    << ";" NL "uniform int g_index[6] = int[](0, 1, 2, 3, 4, 5);";
4111                 if (stage == 0)
4112                 { // VS
4113                         os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_VertexID, g_index[0]);";
4114                 }
4115                 else if (stage == 1)
4116                 { // TCS
4117                         os << NL "layout(vertices = 1) out;" NL "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL
4118                                          "  gl_TessLevelInner[1] = 1;" NL "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL
4119                                          "  gl_TessLevelOuter[2] = 1;" NL "  gl_TessLevelOuter[3] = 1;" NL
4120                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_index[0]);";
4121                 }
4122                 else if (stage == 2)
4123                 { // TES
4124                         os << NL "layout(quads, point_mode) in;" NL "void main() {" NL
4125                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_index[0]);";
4126                 }
4127                 else if (stage == 3)
4128                 { // GS
4129                         os << NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "void main() {" NL
4130                                          "  ivec2 coord = ivec2(gl_PrimitiveIDIn, g_index[0]);";
4131                 }
4132                 else if (stage == 4)
4133                 { // CS
4134                         os << NL "layout(local_size_x = 1) in;" NL "void main() {" NL
4135                                          "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);";
4136                 }
4137                 os << NL "  imageStore(g_image_1d, coord.x, g_value);" NL "  imageStore(g_image_2d, coord, g_value);" NL
4138                                  "  imageStore(g_image_3d, ivec3(coord.xy, g_index[0]), g_value);" NL
4139                                  "  imageStore(g_image_3d, ivec3(coord.xy, g_index[1]), g_value);" NL
4140                                  "  imageStore(g_image_2drect, coord, g_value);" NL "  for (int i = 0; i < 6; ++i) {" NL
4141                                  "    imageStore(g_image_cube, ivec3(coord, g_index[i]), g_value);" NL "  }" NL
4142                                  "  imageStore(g_image_1darray, ivec2(coord.x, g_index[0]), g_value);" NL
4143                                  "  imageStore(g_image_1darray, ivec2(coord.x, g_index[1]), g_value);" NL
4144                                  "  imageStore(g_image_2darray, ivec3(coord, g_index[0]), g_value);" NL
4145                                  "  imageStore(g_image_2darray, ivec3(coord, g_index[1]), g_value);" NL
4146                                  "  for (int i = 0; i < 6; ++i) {" NL
4147                                  "    imageStore(g_image_cube_array, ivec3(coord, g_index[i]), g_value);" NL "  }" NL
4148                                  "  for (int i = 0; i < 6; ++i) {" NL
4149                                  "    imageStore(g_image_cube_array, ivec3(coord, g_index[i] + 6), g_value);" NL "  }" NL "}";
4150                 return os.str();
4151         }
4152
4153         template <typename T>
4154         std::string GenLoadShader(int stage, GLenum internalformat, const T& expected_value)
4155         {
4156                 std::ostringstream os;
4157                 os << "#version 420 core";
4158                 if (stage == 4)
4159                 { // CS
4160                         os << NL "#extension GL_ARB_compute_shader : require";
4161                 }
4162                 os << NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
4163                    << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
4164                    << TypePrefix<T>() << "image3D g_image_3d;" NL "layout(" << FormatEnumToString(internalformat)
4165                    << ") readonly uniform " << TypePrefix<T>() << "image2DRect g_image_2drect;" NL "layout("
4166                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
4167                    << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) << ") readonly uniform "
4168                    << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout(" << FormatEnumToString(internalformat)
4169                    << ") readonly uniform " << TypePrefix<T>() << "image2DArray g_image_2darray;" NL "layout("
4170                    << FormatEnumToString(internalformat) << ") readonly uniform " << TypePrefix<T>()
4171                    << "imageCubeArray g_image_cube_array;" NL "layout(rgba32f) writeonly uniform image2D g_image_result;" NL
4172                           "uniform "
4173                    << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4" << expected_value
4174                    << ";" NL "uniform int g_index[6] = int[](0, 1, 2, 3, 4, 5);";
4175                 if (stage == 0)
4176                 { // VS
4177                         os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_VertexID, g_index[0]);";
4178                 }
4179                 else if (stage == 1)
4180                 { // TCS
4181                         os << NL "layout(vertices = 1) out;" NL "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL
4182                                          "  gl_TessLevelInner[1] = 1;" NL "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL
4183                                          "  gl_TessLevelOuter[2] = 1;" NL "  gl_TessLevelOuter[3] = 1;" NL
4184                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_index[0]);";
4185                 }
4186                 else if (stage == 2)
4187                 { // TES
4188                         os << NL "layout(quads, point_mode) in;" NL "void main() {" NL
4189                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_index[0]);";
4190                 }
4191                 else if (stage == 3)
4192                 { // GS
4193                         os << NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "void main() {" NL
4194                                          "  ivec2 coord = ivec2(gl_PrimitiveIDIn, g_index[0]);";
4195                 }
4196                 else if (stage == 4)
4197                 { // CS
4198                         os << NL "layout(local_size_x = 1) in;" NL "void main() {" NL
4199                                          "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);";
4200                 }
4201                 os << NL "  vec4 r = vec4(0, 1, 0, 1);" NL "  " << TypePrefix<T>()
4202                    << "vec4 v;" NL "  v = imageLoad(g_image_2d, coord);" NL
4203                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL
4204                           "  v = imageLoad(g_image_3d, ivec3(coord, g_index[0]));" NL
4205                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL "  v = imageLoad(g_image_2drect, coord);" NL
4206                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL
4207                           "  v = imageLoad(g_image_cube, ivec3(coord, g_index[0]));" NL
4208                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL "  v = imageLoad(g_image_1darray, coord);" NL
4209                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL
4210                           "  v = imageLoad(g_image_2darray, ivec3(coord, g_index[0]));" NL
4211                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL
4212                           "  v = imageLoad(g_image_cube_array, ivec3(coord, g_index[0]));" NL
4213                           "  if (v != g_value) r = vec4(1.0, 0.0, 0.0, 1.0);" NL "  imageStore(g_image_result, coord, r);" NL "}";
4214                 return os.str();
4215         }
4216
4217 protected:
4218         long RunStage(int stage)
4219         {
4220                 if (!SupportedInStage(stage, 8))
4221                         return NOT_SUPPORTED;
4222
4223                 glEnable(GL_RASTERIZER_DISCARD);
4224                 m_stage = stage;
4225
4226                 if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
4227                         return ERROR;
4228                 if (!Write(GL_RG32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
4229                         return ERROR;
4230                 if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
4231                         return ERROR;
4232
4233                 if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
4234                         return ERROR;
4235                 if (!Write(GL_RG16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 0.0f, 1.0f)))
4236                         return ERROR;
4237                 if (!Write(GL_R16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
4238                         return ERROR;
4239
4240                 if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
4241                         return ERROR;
4242                 if (!Write(GL_RG32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
4243                         return ERROR;
4244                 if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
4245                         return ERROR;
4246
4247                 if (!Write(GL_R11F_G11F_B10F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 1.0f)))
4248                         return ERROR;
4249
4250                 if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
4251                         return ERROR;
4252                 if (!Write(GL_RG16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
4253                         return ERROR;
4254                 if (!Write(GL_R16I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
4255                         return ERROR;
4256
4257                 if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
4258                         return ERROR;
4259                 if (!Write(GL_RG8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 0, 1)))
4260                         return ERROR;
4261                 if (!Write(GL_R8I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
4262                         return ERROR;
4263
4264                 if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
4265                         return ERROR;
4266                 if (!Write(GL_RGB10_A2UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
4267                         return ERROR;
4268                 if (!Write(GL_RG32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
4269                         return ERROR;
4270                 if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
4271                         return ERROR;
4272
4273                 if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
4274                         return ERROR;
4275                 if (!Write(GL_RG16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
4276                         return ERROR;
4277                 if (!Write(GL_R16UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
4278                         return ERROR;
4279
4280                 if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
4281                         return ERROR;
4282                 if (!Write(GL_RG8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 0, 1)))
4283                         return ERROR;
4284                 if (!Write(GL_R8UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
4285                         return ERROR;
4286
4287                 if (!Write(GL_RGBA16, vec4(1.0f), vec4(1.0f)))
4288                         return ERROR;
4289                 if (!Write(GL_RGB10_A2, vec4(1.0f), vec4(1.0f)))
4290                         return ERROR;
4291                 if (!Write(GL_RG16, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
4292                         return ERROR;
4293                 if (!Write(GL_R16, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
4294                         return ERROR;
4295
4296                 if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
4297                         return ERROR;
4298                 if (!Write(GL_RG8, vec4(1.0f), vec4(1.0f, 1.0f, 0.0f, 1.0f)))
4299                         return ERROR;
4300                 if (!Write(GL_R8, vec4(1.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
4301                         return ERROR;
4302
4303                 //
4304                 {
4305                         if (!Write(GL_RGBA16_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
4306                                 return ERROR;
4307                         if (!Write(GL_RG16_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
4308                                 return ERROR;
4309                         if (!Write(GL_R16_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
4310                                 return ERROR;
4311
4312                         if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
4313                                 return ERROR;
4314                         if (!Write(GL_RG8_SNORM, vec4(-1.0f), vec4(-1.0f, -1.0f, 0.0f, 1.0f)))
4315                                 return ERROR;
4316                         if (!Write(GL_R8_SNORM, vec4(-1.0f, 1.0f, -1.0f, 1.0f), vec4(-1.0f, 0.0f, 0.0f, 1.0f)))
4317                                 return ERROR;
4318                 }
4319                 return NO_ERROR;
4320         }
4321 };
4322 //-----------------------------------------------------------------------------
4323 // AtomicMachine
4324 //-----------------------------------------------------------------------------
4325 class AtomicMachine : public ShaderImageLoadStoreBase
4326 {
4327         GLuint m_vao;
4328
4329         virtual long Setup()
4330         {
4331                 glEnable(GL_RASTERIZER_DISCARD);
4332                 glGenVertexArrays(1, &m_vao);
4333                 return NO_ERROR;
4334         }
4335
4336         virtual long Cleanup()
4337         {
4338                 glDisable(GL_RASTERIZER_DISCARD);
4339                 glDeleteVertexArrays(1, &m_vao);
4340                 return NO_ERROR;
4341         }
4342
4343         template <typename T>
4344         bool Atomic(int stage, GLenum internalformat)
4345         {
4346                 GLuint program = 0;
4347                 if (stage == 0)
4348                 { // VS
4349                         program = BuildProgram(GenShader<T>(stage, internalformat).c_str(), NULL, NULL, NULL, NULL);
4350                 }
4351                 else if (stage == 1)
4352                 { // TCS
4353                         const char* const glsl_vs  = "#version 420 core" NL "void main() {}";
4354                         const char* const glsl_tes = "#version 420 core" NL "layout(quads, point_mode) in;" NL "void main() {}";
4355                         program = BuildProgram(glsl_vs, GenShader<T>(stage, internalformat).c_str(), glsl_tes, NULL, NULL);
4356                 }
4357                 else if (stage == 2)
4358                 { // TES
4359                         const char* const glsl_vs = "#version 420 core" NL "void main() {}";
4360                         program = BuildProgram(glsl_vs, NULL, GenShader<T>(stage, internalformat).c_str(), NULL, NULL);
4361                 }
4362                 else if (stage == 3)
4363                 { // GS
4364                         const char* const glsl_vs = "#version 420 core" NL "void main() {}";
4365                         program = BuildProgram(glsl_vs, NULL, NULL, GenShader<T>(stage, internalformat).c_str(), NULL);
4366                 }
4367                 else if (stage == 4)
4368                 { // CS
4369                         std::string               source = GenShader<T>(stage, internalformat);
4370                         const char* const src   = source.c_str();
4371                         GLuint                    sh     = glCreateShader(GL_COMPUTE_SHADER);
4372                         glShaderSource(sh, 1, &src, NULL);
4373                         glCompileShader(sh);
4374                         program = glCreateProgram();
4375                         glAttachShader(program, sh);
4376                         glLinkProgram(program);
4377                         glDeleteShader(sh);
4378                 }
4379                 GLuint texture_result;
4380                 glGenTextures(1, &texture_result);
4381                 glBindTexture(GL_TEXTURE_2D, texture_result);
4382                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4383                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4384                 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
4385
4386                 const GLenum targets[] = { GL_TEXTURE_2D,        GL_TEXTURE_3D,    GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,
4387                                                                    GL_TEXTURE_BUFFER, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY };
4388                 const int kTargets = sizeof(targets) / sizeof(targets[0]);
4389
4390                 GLuint textures[kTargets];
4391                 GLuint buffer;
4392                 glGenTextures(kTargets, textures);
4393                 glGenBuffers(1, &buffer);
4394
4395                 for (int i = 0; i < kTargets; ++i)
4396                 {
4397                         glBindTexture(targets[i], textures[i]);
4398                         if (targets[i] != GL_TEXTURE_BUFFER)
4399                         {
4400                                 glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4401                                 glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4402                         }
4403                         if (targets[i] == GL_TEXTURE_2D || targets[i] == GL_TEXTURE_RECTANGLE)
4404                         {
4405                                 glTexStorage2D(targets[i], 1, internalformat, 1, 1);
4406                         }
4407                         else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY)
4408                         {
4409                                 glTexStorage3D(targets[i], 1, internalformat, 1, 1, 2);
4410                         }
4411                         else if (targets[i] == GL_TEXTURE_CUBE_MAP)
4412                         {
4413                                 glTexStorage2D(targets[i], 1, internalformat, 1, 1);
4414                         }
4415                         else if (targets[i] == GL_TEXTURE_BUFFER)
4416                         {
4417                                 glBindBuffer(GL_TEXTURE_BUFFER, buffer);
4418                                 glBufferData(GL_TEXTURE_BUFFER, 4, NULL, GL_DYNAMIC_DRAW);
4419                                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
4420                                 glTexBuffer(targets[i], internalformat, buffer);
4421                         }
4422                         else if (targets[i] == GL_TEXTURE_1D_ARRAY)
4423                         {
4424                                 glTexStorage2D(targets[i], 1, internalformat, 1, 2);
4425                         }
4426                 }
4427                 glBindImageTexture(0, texture_result, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
4428                 glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
4429                 glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
4430                 glBindImageTexture(3, textures[2], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
4431                 glBindImageTexture(4, textures[3], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
4432                 glBindImageTexture(5, textures[4], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat);
4433                 glBindImageTexture(6, textures[5], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
4434                 glBindImageTexture(7, textures[6], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);
4435
4436                 glUseProgram(program);
4437                 glUniform1i(glGetUniformLocation(program, "g_image_result"), 0);
4438                 glUniform1i(glGetUniformLocation(program, "g_image_2d"), 1);
4439                 glUniform1i(glGetUniformLocation(program, "g_image_3d"), 2);
4440                 glUniform1i(glGetUniformLocation(program, "g_image_2drect"), 3);
4441                 glUniform1i(glGetUniformLocation(program, "g_image_cube"), 4);
4442                 glUniform1i(glGetUniformLocation(program, "g_image_buffer"), 5);
4443                 glUniform1i(glGetUniformLocation(program, "g_image_1darray"), 6);
4444                 glUniform1i(glGetUniformLocation(program, "g_image_2darray"), 7);
4445
4446                 glBindVertexArray(m_vao);
4447                 if (stage == 1 || stage == 2)
4448                 { // TCS or TES
4449                         glPatchParameteri(GL_PATCH_VERTICES, 1);
4450                         glDrawArrays(GL_PATCHES, 0, 1);
4451                         glPatchParameteri(GL_PATCH_VERTICES, 3);
4452                 }
4453                 else if (stage == 4)
4454                 { // CS
4455                         glDispatchCompute(1, 1, 1);
4456                 }
4457                 else
4458                 {
4459                         glDrawArrays(GL_POINTS, 0, 1);
4460                 }
4461
4462                 bool status = true;
4463                 {
4464                         vec4 color;
4465                         glBindTexture(GL_TEXTURE_2D, texture_result);
4466                         glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
4467                         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &color[0]);
4468                         if (!tcu::allEqual(color, vec4(0, 1, 0, 1)))
4469                         {
4470                                 status = false;
4471                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Color is: " << ToString(color)
4472                                                                                                         << ". Format is: " << FormatEnumToString(internalformat)
4473                                                                                                         << ". Stage is: " << StageName(stage) << tcu::TestLog::EndMessage;
4474                         }
4475                 }
4476                 glUseProgram(0);
4477                 glDeleteProgram(program);
4478                 glDeleteTextures(7, textures);
4479                 glDeleteTextures(1, &texture_result);
4480                 glDeleteBuffers(1, &buffer);
4481                 return status;
4482         }
4483
4484         template <typename T>
4485         std::string GenShader(int stage, GLenum internalformat)
4486         {
4487                 std::ostringstream os;
4488                 os << "#version 420 core";
4489                 if (stage == 4)
4490                 { // CS
4491                         os << NL "#extension GL_ARB_compute_shader : require";
4492                 }
4493                 os << NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
4494                    << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
4495                    << TypePrefix<T>() << "image3D g_image_3d;" NL "layout(" << FormatEnumToString(internalformat)
4496                    << ") coherent uniform " << TypePrefix<T>() << "image2DRect g_image_2drect;" NL "layout("
4497                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
4498                    << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat) << ") coherent uniform "
4499                    << TypePrefix<T>() << "imageBuffer g_image_buffer;" NL "layout(" << FormatEnumToString(internalformat)
4500                    << ") coherent uniform " << TypePrefix<T>() << "image1DArray g_image_1darray;" NL "layout("
4501                    << FormatEnumToString(internalformat) << ") coherent uniform " << TypePrefix<T>()
4502                    << "image2DArray g_image_2darray;" NL "layout(rgba32f) writeonly uniform image2D g_image_result;" NL
4503                           "uniform int g_value[6] = int[](0, 1, 2, 3, 4, 5);";
4504                 if (stage == 0)
4505                 { // VS
4506                         os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_VertexID, g_value[0]);";
4507                 }
4508                 else if (stage == 1)
4509                 { // TCS
4510                         os << NL "layout(vertices = 1) out;" NL "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL
4511                                          "  gl_TessLevelInner[1] = 1;" NL "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL
4512                                          "  gl_TessLevelOuter[2] = 1;" NL "  gl_TessLevelOuter[3] = 1;" NL
4513                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_value[0]);";
4514                 }
4515                 else if (stage == 2)
4516                 { // TES
4517                         os << NL "layout(quads, point_mode) in;" NL "void main() {" NL
4518                                          "  ivec2 coord = ivec2(gl_PrimitiveID, g_value[0]);";
4519                 }
4520                 else if (stage == 3)
4521                 { // GS
4522                         os << NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "void main() {" NL
4523                                          "  ivec2 coord = ivec2(gl_PrimitiveIDIn, g_value[0]);";
4524                 }
4525                 else if (stage == 4)
4526                 { // CS
4527                         os << NL "layout(local_size_x = 1) in;" NL "void main() {" NL
4528                                          "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_value[0]);";
4529                 }
4530                 os << NL
4531                         "  vec4 o_color = vec4(0, 1, 0, 1);" NL "  imageAtomicExchange(g_image_2d, coord, 0);" NL
4532                         "  if (imageAtomicAdd(g_image_2d, coord, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4533                         "  if (imageAtomicMin(g_image_2d, coord, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4534                         "  if (imageAtomicMax(g_image_2d, coord, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4535                         "  if (imageAtomicAnd(g_image_2d, coord, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4536                         "  if (imageAtomicOr(g_image_2d, coord, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4537                         "  if (imageAtomicXor(g_image_2d, coord, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4538                         "  if (imageAtomicExchange(g_image_2d, coord, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4539                         "  if (imageAtomicCompSwap(g_image_2d, coord, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4540                         "  if (imageAtomicExchange(g_image_2d, coord, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4541
4542                         NL "  imageAtomicExchange(g_image_3d, ivec3(coord, 0), 0);" NL
4543                         "  if (imageAtomicAdd(g_image_3d, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4544                         "  if (imageAtomicMin(g_image_3d, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4545                         "  if (imageAtomicMax(g_image_3d, ivec3(coord, g_value[0]), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4546                         "  if (imageAtomicAnd(g_image_3d, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4547                         "  if (imageAtomicOr(g_image_3d, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4548                         "  if (imageAtomicXor(g_image_3d, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4549                         "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4550                         "  if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 0), 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4551                         "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4552
4553                         NL "  imageAtomicExchange(g_image_2drect, coord, 0);" NL
4554                         "  if (imageAtomicAdd(g_image_2drect, coord, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4555                         "  if (imageAtomicMin(g_image_2drect, coord, 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4556                         "  if (imageAtomicMax(g_image_2drect, coord, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4557                         "  if (imageAtomicAnd(g_image_2drect, coord, 0) != g_value[4]) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4558                         "  if (imageAtomicOr(g_image_2drect, coord, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4559                         "  if (imageAtomicXor(g_image_2drect, coord, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4560                         "  if (imageAtomicExchange(g_image_2drect, coord, 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4561                         "  if (imageAtomicCompSwap(g_image_2drect, coord, g_value[1], 6) != 1) o_color = vec4(1.0, 0.0, 0.0, "
4562                         "1.0);" NL "  if (imageAtomicExchange(g_image_2drect, coord, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4563
4564                         NL "  imageAtomicExchange(g_image_cube, ivec3(coord, 0), 0);" NL "  if (imageAtomicAdd(g_image_cube, "
4565                         "ivec3(coord, 0), g_value[2]) != 0) "
4566                         "o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4567                         "  if (imageAtomicMin(g_image_cube, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4568                         "  if (imageAtomicMax(g_image_cube, ivec3(coord, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4569                         "  if (imageAtomicAnd(g_image_cube, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4570                         "  if (imageAtomicOr(g_image_cube, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4571                         "  if (imageAtomicXor(g_image_cube, ivec3(coord, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4572                         "  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4573                         "  if (imageAtomicCompSwap(g_image_cube, ivec3(coord, g_value[0]), 1, 6) != 1) o_color = vec4(1.0, 0.0, "
4574                         "0.0, 1.0);" NL
4575                         "  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4576
4577                         NL "  imageAtomicExchange(g_image_buffer, coord.x, g_value[0]);" NL
4578                         "  if (imageAtomicAdd(g_image_buffer, coord.x, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4579                         "  if (imageAtomicMin(g_image_buffer, coord.x, g_value[3]) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4580                         "  if (imageAtomicMax(g_image_buffer, coord.x, 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4581                         "  if (imageAtomicAnd(g_image_buffer, coord.x, 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4582                         "  if (imageAtomicOr(g_image_buffer, coord.x, 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4583                         "  if (imageAtomicXor(g_image_buffer, coord.x, 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4584                         "  if (imageAtomicExchange(g_image_buffer, coord.x, g_value[1]) != 3) o_color = vec4(1.0, 0.0, 0.0, "
4585                         "1.0);" NL
4586                         "  if (imageAtomicCompSwap(g_image_buffer, coord.x, 1, 6) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4587                         "  if (imageAtomicExchange(g_image_buffer, coord.x, 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4588
4589                         NL "  imageAtomicExchange(g_image_1darray, ivec2(coord.x, 0), 0);" NL
4590                         "  if (imageAtomicAdd(g_image_1darray, ivec2(coord.x, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4591                         "  if (imageAtomicMin(g_image_1darray, ivec2(coord.x, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4592                         "  if (imageAtomicMax(g_image_1darray, ivec2(coord.x, g_value[0]), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, "
4593                         "1.0);" NL
4594                         "  if (imageAtomicAnd(g_image_1darray, ivec2(coord.x, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4595                         "  if (imageAtomicOr(g_image_1darray, ivec2(coord.x, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4596                         "  if (imageAtomicXor(g_image_1darray, ivec2(coord.x, 0), 4) != 7) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4597                         "  if (imageAtomicExchange(g_image_1darray, ivec2(coord.x, 0), 1) != 3) o_color = vec4(1.0, 0.0, 0.0, "
4598                         "1.0);" NL "  if (imageAtomicCompSwap(g_image_1darray, ivec2(coord.x, 0), 1, 6) != 1) o_color = vec4(1.0, "
4599                         "0.0, 0.0, 1.0);" NL
4600                         "  if (imageAtomicExchange(g_image_1darray, ivec2(coord.x, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4601
4602                         NL "  imageAtomicExchange(g_image_2darray, ivec3(coord, 0), 0);" NL
4603                         "  if (imageAtomicAdd(g_image_2darray, ivec3(coord, 0), 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4604                         "  if (imageAtomicMin(g_image_2darray, ivec3(coord, 0), 3) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4605                         "  if (imageAtomicMax(g_image_2darray, ivec3(coord, 0), 4) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4606                         "  if (imageAtomicAnd(g_image_2darray, ivec3(coord, 0), 0) != 4) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4607                         "  if (imageAtomicOr(g_image_2darray, ivec3(coord, 0), 7) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4608                         "  if (imageAtomicXor(g_image_2darray, ivec3(coord, 0), g_value[4]) != 7) o_color = vec4(1.0, 0.0, 0.0, "
4609                         "1.0);" NL "  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), 1) != 3) o_color = vec4(1.0, 0.0, "
4610                         "0.0, 1.0);" NL "  if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 0), 1, 6) != 1) "
4611                         "o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
4612                         "  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), 0) != 6) o_color = vec4(1.0, 0.0, 0.0, 1.0);"
4613
4614                         NL "  imageStore(g_image_result, coord, o_color);" NL "}";
4615                 return os.str();
4616         }
4617
4618 protected:
4619         long RunStage(int stage)
4620         {
4621                 if (!SupportedInStage(stage, 8))
4622                         return NOT_SUPPORTED;
4623                 if (!Atomic<GLint>(stage, GL_R32I))
4624                         return ERROR;
4625                 if (!Atomic<GLuint>(stage, GL_R32UI))
4626                         return ERROR;
4627                 return NO_ERROR;
4628         }
4629 };
4630 //-----------------------------------------------------------------------------
4631 // 1.3.4 BasicAllTargetsLoadStoreVS
4632 //-----------------------------------------------------------------------------
4633 class BasicAllTargetsLoadStoreVS : public LoadStoreMachine
4634 {
4635         virtual long Run()
4636         {
4637                 return RunStage(0);
4638         }
4639 };
4640 //-----------------------------------------------------------------------------
4641 // 1.3.5 BasicAllTargetsLoadStoreTCS
4642 //-----------------------------------------------------------------------------
4643 class BasicAllTargetsLoadStoreTCS : public LoadStoreMachine
4644 {
4645         virtual long Run()
4646         {
4647                 return RunStage(1);
4648         }
4649 };
4650 //-----------------------------------------------------------------------------
4651 // 1.3.6 BasicAllTargetsLoadStoreTES
4652 //-----------------------------------------------------------------------------
4653 class BasicAllTargetsLoadStoreTES : public LoadStoreMachine
4654 {
4655         virtual long Run()
4656         {
4657                 return RunStage(2);
4658         }
4659 };
4660 //-----------------------------------------------------------------------------
4661 // 1.3.7 BasicAllTargetsLoadStoreGS
4662 //-----------------------------------------------------------------------------
4663 class BasicAllTargetsLoadStoreGS : public LoadStoreMachine
4664 {
4665         virtual long Run()
4666         {
4667                 return RunStage(3);
4668         }
4669 };
4670 //-----------------------------------------------------------------------------
4671 // 1.3.8 BasicAllTargetsLoadStoreCS
4672 //-----------------------------------------------------------------------------
4673 class BasicAllTargetsLoadStoreCS : public LoadStoreMachine
4674 {
4675         virtual long Run()
4676         {
4677                 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
4678                 {
4679                         m_context.getTestContext().getLog()
4680                                 << tcu::TestLog::Message << "GL_ARB_compute_shader not supported, skipping test"
4681                                 << tcu::TestLog::EndMessage;
4682                         return NO_ERROR;
4683                 }
4684
4685                 return RunStage(4);
4686         }
4687 };
4688 //-----------------------------------------------------------------------------
4689 // 1.3.9 BasicAllTargetsAtomicVS
4690 //-----------------------------------------------------------------------------
4691 class BasicAllTargetsAtomicVS : public AtomicMachine
4692 {
4693         virtual long Run()
4694         {
4695                 return RunStage(0);
4696         }
4697 };
4698 //-----------------------------------------------------------------------------
4699 // 1.3.10 BasicAllTargetsAtomicTCS
4700 //-----------------------------------------------------------------------------
4701 class BasicAllTargetsAtomicTCS : public AtomicMachine
4702 {
4703         virtual long Run()
4704         {
4705                 return RunStage(1);
4706         }
4707 };
4708 //-----------------------------------------------------------------------------
4709 // 1.3.11 BasicAllTargetsAtomicTES
4710 //-----------------------------------------------------------------------------
4711 class BasicAllTargetsAtomicTES : public AtomicMachine
4712 {
4713         virtual long Run()
4714         {
4715                 return RunStage(2);
4716         }
4717 };
4718 //-----------------------------------------------------------------------------
4719 // 1.3.12 BasicAllTargetsAtomicGS
4720 //-----------------------------------------------------------------------------
4721 class BasicAllTargetsAtomicGS : public AtomicMachine
4722 {
4723         virtual long Run()
4724         {
4725                 return RunStage(3);
4726         }
4727 };
4728 //-----------------------------------------------------------------------------
4729 // 1.3.13 BasicAllTargetsAtomicCS
4730 //-----------------------------------------------------------------------------
4731 class BasicAllTargetsAtomicCS : public AtomicMachine
4732 {
4733         virtual long Run()
4734         {
4735                 if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_compute_shader"))
4736                 {
4737                         m_context.getTestContext().getLog()
4738                                 << tcu::TestLog::Message << "GL_ARB_compute_shader not supported, skipping test"
4739                                 << tcu::TestLog::EndMessage;
4740                         return NO_ERROR;
4741                 }
4742
4743                 return RunStage(4);
4744         }
4745 };
4746 //-----------------------------------------------------------------------------
4747 // 1.4.1 BasicGLSLMisc
4748 //-----------------------------------------------------------------------------
4749 class BasicGLSLMisc : public ShaderImageLoadStoreBase
4750 {
4751         GLuint m_texture;
4752         GLuint m_program;
4753         GLuint m_vao, m_vbo;
4754
4755         virtual long Setup()
4756         {
4757                 m_texture = 0;
4758                 m_program = 0;
4759                 m_vao = m_vbo = 0;
4760                 return NO_ERROR;
4761         }
4762
4763         virtual long Run()
4764         {
4765                 const int                 kSize = 32;
4766                 std::vector<vec4> data(kSize * kSize * 4, vec4(0.0f));
4767
4768                 glGenTextures(1, &m_texture);
4769                 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
4770                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4771                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, kSize, kSize, 4, 0, GL_RGBA, GL_FLOAT, &data[0]);
4772                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
4773
4774                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
4775                                                          "  gl_Position = i_position;" NL "}";
4776                 const char* src_fs =
4777                         "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
4778                         "layout(rgba32f) coherent volatile restrict uniform image2D g_image_layer0;" NL
4779                         "layout(rgba32f) volatile uniform image2D g_image_layer1;" NL
4780                         "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
4781                         "  imageStore(g_image_layer0, coord, vec4(1.0));" NL "  memoryBarrier();" NL
4782                         "  imageStore(g_image_layer0, coord, vec4(2.0));" NL "  memoryBarrier();" NL
4783                         "  imageStore(g_image_layer0, coord, vec4(0.0, 1.0, 0.0, 1.0));" NL "  memoryBarrier();" NL
4784                         "  o_color = imageLoad(g_image_layer0, coord) + imageLoad(g_image_layer1, coord);" NL "}";
4785                 m_program = BuildProgram(src_vs, NULL, NULL, NULL, src_fs);
4786
4787                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
4788
4789                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
4790                 glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_ONLY, GL_RGBA32F);
4791
4792                 glClear(GL_COLOR_BUFFER_BIT);
4793                 glViewport(0, 0, kSize, kSize);
4794
4795                 glUseProgram(m_program);
4796                 glUniform1i(glGetUniformLocation(m_program, "g_image_layer0"), 0);
4797                 glUniform1i(glGetUniformLocation(m_program, "g_image_layer1"), 1);
4798
4799                 glBindVertexArray(m_vao);
4800                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4801
4802                 if (!ValidateReadBuffer(0, 0, kSize, kSize, vec4(0, 1, 0, 1)))
4803                 {
4804                         return ERROR;
4805                 }
4806                 return NO_ERROR;
4807         }
4808
4809         virtual long Cleanup()
4810         {
4811                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
4812                 glDeleteTextures(1, &m_texture);
4813                 glDeleteVertexArrays(1, &m_vao);
4814                 glDeleteBuffers(1, &m_vbo);
4815                 glUseProgram(0);
4816                 glDeleteProgram(m_program);
4817                 return NO_ERROR;
4818         }
4819 };
4820 //-----------------------------------------------------------------------------
4821 // 1.4.2 BasicGLSLEarlyFragTests
4822 //-----------------------------------------------------------------------------
4823 class BasicGLSLEarlyFragTests : public ShaderImageLoadStoreBase
4824 {
4825         GLuint m_texture[2];
4826         GLuint m_program[2];
4827         GLuint m_vao, m_vbo;
4828
4829         virtual long Setup()
4830         {
4831                 m_texture[0] = m_texture[1] = 0;
4832                 m_program[0] = m_program[1] = 0;
4833                 m_vao = m_vbo = 0;
4834                 return NO_ERROR;
4835         }
4836
4837         virtual long Run()
4838         {
4839                 int ds = m_context.getRenderContext().getRenderTarget().getDepthBits();
4840
4841                 const int                 kSize = 32;
4842                 std::vector<vec4> data(kSize * kSize);
4843
4844                 glGenTextures(2, m_texture);
4845                 glBindTexture(GL_TEXTURE_2D, m_texture[0]);
4846                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4847                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kSize, kSize, 0, GL_RGBA, GL_FLOAT, &data[0]);
4848                 glBindTexture(GL_TEXTURE_2D, 0);
4849
4850                 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
4851                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4852                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, kSize, kSize, 0, GL_RGBA, GL_FLOAT, &data[0]);
4853                 glBindTexture(GL_TEXTURE_2D, 0);
4854
4855                 const char* glsl_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
4856                                                           "  gl_Position = i_position;" NL "}";
4857                 const char* glsl_early_frag_tests_fs =
4858                         "#version 420 core" NL "layout(early_fragment_tests) in;" NL "layout(location = 0) out vec4 o_color;" NL
4859                         "layout(rgba32f) coherent uniform image2D g_image;" NL "void main() {" NL
4860                         "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image, coord, vec4(1.0));" NL
4861                         "  o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
4862                 const char* glsl_fs = "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
4863                                                           "layout(rgba32f) coherent uniform image2D g_image;" NL "void main() {" NL
4864                                                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image, coord, vec4(1.0));" NL
4865                                                           "  o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
4866                 m_program[0] = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_early_frag_tests_fs);
4867                 m_program[1] = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
4868
4869                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
4870
4871                 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
4872                 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
4873
4874                 glViewport(0, 0, kSize, kSize);
4875                 glBindVertexArray(m_vao);
4876
4877                 glEnable(GL_DEPTH_TEST);
4878                 glClearColor(0.0, 1.0f, 0.0, 1.0f);
4879                 glClearDepthf(0.0f);
4880
4881                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4882                 glUseProgram(m_program[0]);
4883                 glUniform1i(glGetUniformLocation(m_program[0], "g_image"), 0);
4884
4885                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4886
4887                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
4888                 glUseProgram(m_program[1]);
4889                 glUniform1i(glGetUniformLocation(m_program[1], "g_image"), 1);
4890                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
4891
4892                 glBindTexture(GL_TEXTURE_2D, m_texture[0]);
4893                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
4894                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0]);
4895                 for (int i = 0; i < kSize * kSize; ++i)
4896                 {
4897                         if (IsEqual(data[i], vec4(1.0f)) && ds != 0)
4898                                 return ERROR;
4899                 }
4900
4901                 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
4902                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
4903                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &data[0]);
4904                 for (int i = 0; i < kSize * kSize; ++i)
4905                 {
4906                         if (!IsEqual(data[i], vec4(1.0f)) && ds != 0)
4907                                 return ERROR;
4908                 }
4909
4910                 return NO_ERROR;
4911         }
4912
4913         virtual long Cleanup()
4914         {
4915                 glDisable(GL_DEPTH_TEST);
4916                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
4917                 glClearDepthf(1.0f);
4918                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
4919                 glDeleteTextures(2, m_texture);
4920                 glDeleteVertexArrays(1, &m_vao);
4921                 glDeleteBuffers(1, &m_vbo);
4922                 glUseProgram(0);
4923                 glDeleteProgram(m_program[0]);
4924                 glDeleteProgram(m_program[1]);
4925                 return NO_ERROR;
4926         }
4927 };
4928 //-----------------------------------------------------------------------------
4929 // 1.4.3 BasicGLSLConst
4930 //-----------------------------------------------------------------------------
4931 class BasicGLSLConst : public ShaderImageLoadStoreBase
4932 {
4933         GLuint m_program;
4934         GLuint m_vao, m_vbo;
4935
4936         virtual long Setup()
4937         {
4938                 m_program = 0;
4939                 m_vao = m_vbo = 0;
4940                 return NO_ERROR;
4941         }
4942
4943         virtual long Run()
4944         {
4945                 bool isAtLeast44Context =
4946                         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 4));
4947
4948                 const char* src_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
4949                                                          "  gl_Position = i_position;" NL "}";
4950                 std::ostringstream src_fs;
4951                 src_fs << "#version " << (isAtLeast44Context ? "440" : "420") << " core";
4952                 src_fs << NL "layout(location = 0) out vec4 o_color;" NL "uniform int MaxImageUnits;" NL
4953                                          "uniform int MaxCombinedShaderOutputResources;" NL "uniform int MaxImageSamples;" NL
4954                                          "uniform int MaxVertexImageUniforms;" NL "uniform int MaxTessControlImageUniforms;" NL
4955                                          "uniform int MaxTessEvaluationImageUniforms;" NL "uniform int MaxGeometryImageUniforms;" NL
4956                                          "uniform int MaxFragmentImageUniforms;" NL "uniform int MaxCombinedImageUniforms;" NL
4957                                          "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
4958                                          "  if (gl_MaxImageUnits != MaxImageUnits) o_color = vec4(1.0, 0.0, 0.0, 0.1);";
4959                 if (isAtLeast44Context)
4960                         src_fs << NL "  if (gl_MaxCombinedShaderOutputResources != MaxCombinedShaderOutputResources) o_color = "
4961                                                  "vec4(0.2, 0.0, 0.0, 0.2);";
4962                 else
4963                         src_fs << NL "  if (gl_MaxCombinedImageUnitsAndFragmentOutputs != MaxCombinedShaderOutputResources) "
4964                                                  "o_color = vec4(0.2, 0.0, 0.0, 0.2);";
4965                 src_fs << NL
4966                         "  if (gl_MaxImageSamples != MaxImageSamples) o_color = vec4(1.0, 0.0, 0.0, 0.3);" NL
4967                         "  if (gl_MaxVertexImageUniforms != MaxVertexImageUniforms) o_color = vec4(1.0, 0.0, 0.0, 0.4);" NL
4968                         "  if (gl_MaxTessControlImageUniforms != MaxTessControlImageUniforms) o_color = vec4(1.0, 0.0, 0.0, "
4969                         "0.5);" NL "  if (gl_MaxTessEvaluationImageUniforms != MaxTessEvaluationImageUniforms) o_color = vec4(1.0, "
4970                         "0.0, 0.0, 0.6);" NL
4971                         "  if (gl_MaxGeometryImageUniforms != MaxGeometryImageUniforms) o_color = vec4(1.0, 0.0, 0.0, 0.7);" NL
4972                         "  if (gl_MaxFragmentImageUniforms != MaxFragmentImageUniforms) o_color = vec4(1.0, 0.0, 0.0, 0.8);" NL
4973                         "  if (gl_MaxCombinedImageUniforms != MaxCombinedImageUniforms) o_color = vec4(1.0, 0.0, 0.0, 0.9);" NL "}";
4974
4975                 m_program = BuildProgram(src_vs, NULL, NULL, NULL, src_fs.str().c_str());
4976                 glUseProgram(m_program);
4977
4978                 GLint i;
4979                 glGetIntegerv(GL_MAX_IMAGE_UNITS, &i);
4980                 glUniform1i(glGetUniformLocation(m_program, "MaxImageUnits"), i);
4981
4982                 glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &i);
4983                 glUniform1i(glGetUniformLocation(m_program, "MaxCombinedShaderOutputResources"), i);
4984
4985                 glGetIntegerv(GL_MAX_IMAGE_SAMPLES, &i);
4986                 glUniform1i(glGetUniformLocation(m_program, "MaxImageSamples"), i);
4987
4988                 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &i);
4989                 glUniform1i(glGetUniformLocation(m_program, "MaxVertexImageUniforms"), i);
4990
4991                 glGetIntegerv(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, &i);
4992                 glUniform1i(glGetUniformLocation(m_program, "MaxTessControlImageUniforms"), i);
4993
4994                 glGetIntegerv(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, &i);
4995                 glUniform1i(glGetUniformLocation(m_program, "MaxTessEvaluationImageUniforms"), i);
4996
4997                 glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &i);
4998                 glUniform1i(glGetUniformLocation(m_program, "MaxGeometryImageUniforms"), i);
4999
5000                 glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &i);
5001                 glUniform1i(glGetUniformLocation(m_program, "MaxFragmentImageUniforms"), i);
5002
5003                 glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &i);
5004                 glUniform1i(glGetUniformLocation(m_program, "MaxCombinedImageUniforms"), i);
5005
5006                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5007
5008                 glClear(GL_COLOR_BUFFER_BIT);
5009                 glBindVertexArray(m_vao);
5010                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5011
5012                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5013                 {
5014                         return ERROR;
5015                 }
5016                 return NO_ERROR;
5017         }
5018
5019         virtual long Cleanup()
5020         {
5021                 glDeleteVertexArrays(1, &m_vao);
5022                 glDeleteBuffers(1, &m_vbo);
5023                 glUseProgram(0);
5024                 glDeleteProgram(m_program);
5025                 return NO_ERROR;
5026         }
5027 };
5028 //-----------------------------------------------------------------------------
5029 // 2.1.1 AdvancedSyncImageAccess
5030 //-----------------------------------------------------------------------------
5031 class AdvancedSyncImageAccess : public ShaderImageLoadStoreBase
5032 {
5033         GLuint m_buffer;
5034         GLuint m_buffer_tex;
5035         GLuint m_store_program;
5036         GLuint m_draw_program;
5037         GLuint m_attribless_vao;
5038
5039         virtual long Setup()
5040         {
5041                 m_buffer                 = 0;
5042                 m_buffer_tex     = 0;
5043                 m_store_program  = 0;
5044                 m_draw_program   = 0;
5045                 m_attribless_vao = 0;
5046                 return NO_ERROR;
5047         }
5048
5049         virtual long Run()
5050         {
5051                 if (!SupportedInVS(1))
5052                         return NOT_SUPPORTED;
5053                 const char* const glsl_store_vs =
5054                         "#version 420 core" NL "writeonly uniform imageBuffer g_output_data;" NL "void main() {" NL
5055                         "  vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL
5056                         "  imageStore(g_output_data, gl_VertexID, vec4(data[gl_VertexID], 0.0, 1.0));" NL "}";
5057                 const char* const glsl_draw_vs =
5058                         "#version 420 core" NL "out vec4 vs_color;" NL "layout(rg32f) readonly uniform imageBuffer g_image;" NL
5059                         "uniform samplerBuffer g_sampler;" NL "void main() {" NL "  vec4 pi = imageLoad(g_image, gl_VertexID);" NL
5060                         "  vec4 ps = texelFetch(g_sampler, gl_VertexID);" NL
5061                         "  if (pi != ps) vs_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "  else vs_color = vec4(0.0, 1.0, 0.0, 1.0);" NL
5062                         "  gl_Position = pi;" NL "}";
5063                 const char* const glsl_draw_fs =
5064                         "#version 420 core" NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
5065                         "  o_color = vs_color;" NL "}";
5066                 m_store_program = BuildProgram(glsl_store_vs, NULL, NULL, NULL, NULL);
5067                 m_draw_program  = BuildProgram(glsl_draw_vs, NULL, NULL, NULL, glsl_draw_fs);
5068
5069                 glGenVertexArrays(1, &m_attribless_vao);
5070                 glBindVertexArray(m_attribless_vao);
5071
5072                 glGenBuffers(1, &m_buffer);
5073                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5074                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec2) * 4, NULL, GL_DYNAMIC_DRAW);
5075                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5076
5077                 glGenTextures(1, &m_buffer_tex);
5078                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
5079                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, m_buffer);
5080
5081                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F);
5082
5083                 glEnable(GL_RASTERIZER_DISCARD);
5084                 glUseProgram(m_store_program);
5085                 glDrawArrays(GL_POINTS, 0, 4);
5086
5087                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT);
5088
5089                 glDisable(GL_RASTERIZER_DISCARD);
5090                 glClear(GL_COLOR_BUFFER_BIT);
5091                 glUseProgram(m_draw_program);
5092                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5093
5094                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5095                 {
5096                         return ERROR;
5097                 }
5098                 return NO_ERROR;
5099         }
5100
5101         virtual long Cleanup()
5102         {
5103                 glUseProgram(0);
5104                 glDeleteBuffers(1, &m_buffer);
5105                 glDeleteTextures(1, &m_buffer_tex);
5106                 glDeleteProgram(m_store_program);
5107                 glDeleteProgram(m_draw_program);
5108                 glDeleteVertexArrays(1, &m_attribless_vao);
5109                 return NO_ERROR;
5110         }
5111 };
5112 //-----------------------------------------------------------------------------
5113 // 2.1.2 AdvancedSyncVertexArray
5114 //-----------------------------------------------------------------------------
5115 class AdvancedSyncVertexArray : public ShaderImageLoadStoreBase
5116 {
5117         GLuint m_position_buffer;
5118         GLuint m_color_buffer;
5119         GLuint m_element_buffer;
5120         GLuint m_position_buffer_tex;
5121         GLuint m_color_buffer_tex;
5122         GLuint m_element_buffer_tex;
5123         GLuint m_store_program;
5124         GLuint m_draw_program;
5125         GLuint m_attribless_vao;
5126         GLuint m_draw_vao;
5127
5128         virtual long Setup()
5129         {
5130                 m_position_buffer        = 0;
5131                 m_color_buffer            = 0;
5132                 m_element_buffer          = 0;
5133                 m_position_buffer_tex = 0;
5134                 m_color_buffer_tex      = 0;
5135                 m_element_buffer_tex  = 0;
5136                 m_store_program           = 0;
5137                 m_draw_program            = 0;
5138                 m_attribless_vao          = 0;
5139                 m_draw_vao                        = 0;
5140                 return NO_ERROR;
5141         }
5142
5143         virtual long Run()
5144         {
5145                 if (!SupportedInVS(3))
5146                         return NOT_SUPPORTED;
5147                 const char* const glsl_store_vs =
5148                         "#version 420 core" NL "layout(rg32f) writeonly uniform imageBuffer g_position_buffer;" NL
5149                         "layout(rgba32f) writeonly uniform imageBuffer g_color_buffer;" NL
5150                         "layout(r32ui) writeonly uniform uimageBuffer g_element_buffer;" NL "uniform vec4 g_color;" NL
5151                         "void main() {" NL "  vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL
5152                         "  imageStore(g_position_buffer, gl_VertexID, vec4(data[gl_VertexID], 0.0, 1.0));" NL
5153                         "  imageStore(g_color_buffer, gl_VertexID, g_color);" NL
5154                         "  imageStore(g_element_buffer, gl_VertexID, uvec4(gl_VertexID));" NL "}";
5155                 const char* const glsl_draw_vs =
5156                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
5157                         "layout(location = 1) in vec4 i_color;" NL "out vec4 vs_color;" NL "void main() {" NL
5158                         "  gl_Position = i_position;" NL "  vs_color = i_color;" NL "}";
5159                 const char* const glsl_draw_fs =
5160                         "#version 420 core" NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL "void main() {" NL
5161                         "  o_color = vs_color;" NL "}";
5162                 m_store_program = BuildProgram(glsl_store_vs, NULL, NULL, NULL, NULL);
5163                 glUseProgram(m_store_program);
5164                 glUniform1i(glGetUniformLocation(m_store_program, "g_position_buffer"), 0);
5165                 glUniform1i(glGetUniformLocation(m_store_program, "g_color_buffer"), 1);
5166                 glUniform1i(glGetUniformLocation(m_store_program, "g_element_buffer"), 2);
5167                 glUseProgram(0);
5168
5169                 m_draw_program = BuildProgram(glsl_draw_vs, NULL, NULL, NULL, glsl_draw_fs);
5170
5171                 glGenBuffers(1, &m_position_buffer);
5172                 glBindBuffer(GL_TEXTURE_BUFFER, m_position_buffer);
5173                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec2) * 4, NULL, GL_DYNAMIC_DRAW);
5174                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5175
5176                 glGenBuffers(1, &m_color_buffer);
5177                 glBindBuffer(GL_TEXTURE_BUFFER, m_color_buffer);
5178                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec4) * 4, NULL, GL_DYNAMIC_DRAW);
5179                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5180
5181                 glGenBuffers(1, &m_element_buffer);
5182                 glBindBuffer(GL_TEXTURE_BUFFER, m_element_buffer);
5183                 glBufferData(GL_TEXTURE_BUFFER, sizeof(GLuint) * 4, NULL, GL_DYNAMIC_DRAW);
5184                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5185
5186                 glGenTextures(1, &m_position_buffer_tex);
5187                 glBindTexture(GL_TEXTURE_BUFFER, m_position_buffer_tex);
5188                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32F, m_position_buffer);
5189                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5190
5191                 glGenTextures(1, &m_color_buffer_tex);
5192                 glBindTexture(GL_TEXTURE_BUFFER, m_color_buffer_tex);
5193                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_color_buffer);
5194                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5195
5196                 glGenTextures(1, &m_element_buffer_tex);
5197                 glBindTexture(GL_TEXTURE_BUFFER, m_element_buffer_tex);
5198                 glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, m_element_buffer);
5199                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5200
5201                 glGenVertexArrays(1, &m_attribless_vao);
5202
5203                 glGenVertexArrays(1, &m_draw_vao);
5204                 glBindVertexArray(m_draw_vao);
5205                 glBindBuffer(GL_ARRAY_BUFFER, m_position_buffer);
5206                 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
5207                 glBindBuffer(GL_ARRAY_BUFFER, m_color_buffer);
5208                 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
5209                 glBindBuffer(GL_ARRAY_BUFFER, 0);
5210                 glEnableVertexAttribArray(0);
5211                 glEnableVertexAttribArray(1);
5212                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_element_buffer);
5213                 glBindVertexArray(0);
5214
5215                 glEnable(GL_RASTERIZER_DISCARD);
5216                 glBindImageTexture(0, m_position_buffer_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F);
5217                 glBindImageTexture(1, m_color_buffer_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
5218                 glBindImageTexture(2, m_element_buffer_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
5219                 glUseProgram(m_store_program);
5220                 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f);
5221                 glBindVertexArray(m_attribless_vao);
5222                 glDrawArrays(GL_POINTS, 0, 4);
5223
5224                 glDisable(GL_RASTERIZER_DISCARD);
5225                 glClear(GL_COLOR_BUFFER_BIT);
5226                 glUseProgram(m_draw_program);
5227                 glBindVertexArray(m_draw_vao);
5228                 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
5229                 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
5230
5231                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5232                 {
5233                         return ERROR;
5234                 }
5235
5236                 glEnable(GL_RASTERIZER_DISCARD);
5237                 glUseProgram(m_store_program);
5238                 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 0.0f, 1.0f, 1.0f);
5239                 glBindVertexArray(m_attribless_vao);
5240                 glDrawArrays(GL_POINTS, 0, 4);
5241
5242                 glDisable(GL_RASTERIZER_DISCARD);
5243                 glClear(GL_COLOR_BUFFER_BIT);
5244                 glUseProgram(m_draw_program);
5245                 glBindVertexArray(m_draw_vao);
5246                 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
5247                 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
5248
5249                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 0, 1, 1)))
5250                 {
5251                         return ERROR;
5252                 }
5253                 return NO_ERROR;
5254         }
5255
5256         virtual long Cleanup()
5257         {
5258                 glDisable(GL_RASTERIZER_DISCARD);
5259                 glUseProgram(0);
5260                 glDeleteBuffers(1, &m_position_buffer);
5261                 glDeleteBuffers(1, &m_color_buffer);
5262                 glDeleteBuffers(1, &m_element_buffer);
5263                 glDeleteTextures(1, &m_position_buffer_tex);
5264                 glDeleteTextures(1, &m_color_buffer_tex);
5265                 glDeleteTextures(1, &m_element_buffer_tex);
5266                 glDeleteProgram(m_store_program);
5267                 glDeleteProgram(m_draw_program);
5268                 glDeleteVertexArrays(1, &m_attribless_vao);
5269                 glDeleteVertexArrays(1, &m_draw_vao);
5270                 return NO_ERROR;
5271         }
5272 };
5273
5274 //-----------------------------------------------------------------------------
5275 // 2.1.4 AdvancedSyncDrawIndirect
5276 //-----------------------------------------------------------------------------
5277 class AdvancedSyncDrawIndirect : public ShaderImageLoadStoreBase
5278 {
5279         GLuint m_draw_command_buffer;
5280         GLuint m_draw_command_buffer_tex;
5281         GLuint m_store_program;
5282         GLuint m_draw_program;
5283         GLuint m_attribless_vao;
5284         GLuint m_draw_vao;
5285         GLuint m_draw_vbo;
5286
5287         virtual long Setup()
5288         {
5289                 m_draw_command_buffer    = 0;
5290                 m_draw_command_buffer_tex = 0;
5291                 m_store_program                   = 0;
5292                 m_draw_program                    = 0;
5293                 m_attribless_vao                  = 0;
5294                 m_draw_vao                                = 0;
5295                 m_draw_vbo                                = 0;
5296                 return NO_ERROR;
5297         }
5298
5299         virtual long Run()
5300         {
5301                 if (!SupportedInVS(1))
5302                         return NOT_SUPPORTED;
5303                 const char* const glsl_store_vs =
5304                         "#version 420 core" NL "writeonly uniform uimageBuffer g_draw_command_buffer;" NL "void main() {" NL
5305                         "  imageStore(g_draw_command_buffer, 0, uvec4(4, 1, 0, 0));" NL "}";
5306                 const char* const glsl_draw_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
5307                                                                                  "void main() {" NL "  gl_Position = i_position;" NL "}";
5308                 const char* const glsl_draw_fs = "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
5309                                                                                  "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
5310                 m_store_program = BuildProgram(glsl_store_vs, NULL, NULL, NULL, NULL);
5311                 m_draw_program  = BuildProgram(glsl_draw_vs, NULL, NULL, NULL, glsl_draw_fs);
5312
5313                 glGenBuffers(1, &m_draw_command_buffer);
5314                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_command_buffer);
5315                 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(uvec4), NULL, GL_DYNAMIC_DRAW);
5316                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
5317
5318                 glGenTextures(1, &m_draw_command_buffer_tex);
5319                 glBindTexture(GL_TEXTURE_BUFFER, m_draw_command_buffer_tex);
5320                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, m_draw_command_buffer);
5321                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5322
5323                 glGenVertexArrays(1, &m_attribless_vao);
5324                 CreateFullViewportQuad(&m_draw_vao, &m_draw_vbo, NULL);
5325
5326                 glBindImageTexture(0, m_draw_command_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI);
5327
5328                 glEnable(GL_RASTERIZER_DISCARD);
5329                 glUseProgram(m_store_program);
5330                 glBindVertexArray(m_attribless_vao);
5331                 glDrawArrays(GL_POINTS, 0, 1);
5332
5333                 glDisable(GL_RASTERIZER_DISCARD);
5334                 glClear(GL_COLOR_BUFFER_BIT);
5335                 glUseProgram(m_draw_program);
5336                 glBindVertexArray(m_draw_vao);
5337                 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_command_buffer);
5338                 glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
5339                 glDrawArraysIndirect(GL_TRIANGLE_STRIP, 0);
5340
5341                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5342                 {
5343                         return ERROR;
5344                 }
5345                 return NO_ERROR;
5346         }
5347
5348         virtual long Cleanup()
5349         {
5350                 glUseProgram(0);
5351                 glDeleteBuffers(1, &m_draw_command_buffer);
5352                 glDeleteTextures(1, &m_draw_command_buffer_tex);
5353                 glDeleteProgram(m_store_program);
5354                 glDeleteProgram(m_draw_program);
5355                 glDeleteVertexArrays(1, &m_attribless_vao);
5356                 glDeleteVertexArrays(1, &m_draw_vao);
5357                 glDeleteBuffers(1, &m_draw_vbo);
5358                 return NO_ERROR;
5359         }
5360 };
5361 //-----------------------------------------------------------------------------
5362 // 2.1.5 AdvancedSyncTextureUpdate
5363 //-----------------------------------------------------------------------------
5364 class AdvancedSyncTextureUpdate : public ShaderImageLoadStoreBase
5365 {
5366         GLuint m_texture;
5367         GLuint m_store_program;
5368         GLuint m_draw_program;
5369         GLuint m_vao;
5370         GLuint m_vbo;
5371         GLuint m_pbo;
5372
5373         virtual long Setup()
5374         {
5375                 m_texture               = 0;
5376                 m_store_program = 0;
5377                 m_draw_program  = 0;
5378                 m_vao                   = 0;
5379                 m_vbo                   = 0;
5380                 m_pbo                   = 0;
5381                 return NO_ERROR;
5382         }
5383
5384         virtual long Run()
5385         {
5386                 const char* const glsl_vs =
5387                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "out vec2 vs_texcoord;" NL
5388                         "void main() {" NL "  gl_Position = i_position;" NL "  vs_texcoord = 0.5 + 0.5 * i_position.xy;" NL "}";
5389                 const char* const glsl_store_fs =
5390                         "#version 420 core" NL "writeonly uniform image2D g_image;" NL "void main() {" NL
5391                         "  imageStore(g_image, ivec2(gl_FragCoord.xy), gl_FragCoord);" NL "  discard;" NL "}";
5392                 const char* const glsl_draw_fs =
5393                         "#version 420 core" NL "in vec2 vs_texcoord;" NL "layout(location = 0) out vec4 o_color;" NL
5394                         "uniform sampler2D g_sampler;" NL "void main() {" NL "  o_color = texture(g_sampler, vs_texcoord);" NL "}";
5395                 m_store_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_store_fs);
5396                 m_draw_program  = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_draw_fs);
5397
5398                 std::vector<vec4> data(16 * 16, vec4(1.0f));
5399                 glGenBuffers(1, &m_pbo);
5400                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
5401                 glBufferData(GL_PIXEL_UNPACK_BUFFER, 16 * 16 * sizeof(vec4), &data[0], GL_DYNAMIC_READ);
5402                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
5403
5404                 glGenTextures(1, &m_texture);
5405                 glBindTexture(GL_TEXTURE_2D, m_texture);
5406                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5407                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL);
5408                 glBindTexture(GL_TEXTURE_2D, 0);
5409
5410                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5411
5412                 glViewport(0, 0, 16, 16);
5413                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
5414                 glUseProgram(m_store_program);
5415                 glBindVertexArray(m_vao);
5416                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5417
5418                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
5419                 glBindTexture(GL_TEXTURE_2D, m_texture);
5420                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
5421                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGBA, GL_FLOAT, 0);
5422                 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
5423
5424                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
5425                 glClear(GL_COLOR_BUFFER_BIT);
5426                 glUseProgram(m_draw_program);
5427                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5428
5429                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(1, 1, 1, 1)))
5430                 {
5431                         return ERROR;
5432                 }
5433                 return NO_ERROR;
5434         }
5435
5436         virtual long Cleanup()
5437         {
5438                 glUseProgram(0);
5439                 glDeleteBuffers(1, &m_vbo);
5440                 glDeleteBuffers(1, &m_pbo);
5441                 glDeleteTextures(1, &m_texture);
5442                 glDeleteProgram(m_store_program);
5443                 glDeleteProgram(m_draw_program);
5444                 glDeleteVertexArrays(1, &m_vao);
5445                 return NO_ERROR;
5446         }
5447 };
5448 //-----------------------------------------------------------------------------
5449 // 2.1.6 AdvancedSyncImageAccess2
5450 //-----------------------------------------------------------------------------
5451 class AdvancedSyncImageAccess2 : public ShaderImageLoadStoreBase
5452 {
5453         GLuint m_texture;
5454         GLuint m_store_program;
5455         GLuint m_draw_program;
5456         GLuint m_vao;
5457         GLuint m_vbo;
5458
5459         virtual long Setup()
5460         {
5461                 m_texture               = 0;
5462                 m_store_program = 0;
5463                 m_draw_program  = 0;
5464                 m_vao                   = 0;
5465                 m_vbo                   = 0;
5466                 return NO_ERROR;
5467         }
5468
5469         virtual long Run()
5470         {
5471                 const char* const glsl_vs =
5472                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "out vec2 vs_texcoord;" NL
5473                         "void main() {" NL "  gl_Position = i_position;" NL "  vs_texcoord = 0.5 + 0.5 * i_position.xy;" NL "}";
5474                 const char* const glsl_store_fs =
5475                         "#version 420 core" NL "writeonly uniform image2D g_image;" NL "uniform vec4 g_color;" NL "void main() {" NL
5476                         "  imageStore(g_image, ivec2(gl_FragCoord.xy), g_color);" NL "  discard;" NL "}";
5477                 const char* const glsl_draw_fs =
5478                         "#version 420 core" NL "in vec2 vs_texcoord;" NL "layout(location = 0) out vec4 o_color;" NL
5479                         "uniform sampler2D g_sampler;" NL "void main() {" NL "  o_color = texture(g_sampler, vs_texcoord);" NL "}";
5480                 m_store_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_store_fs);
5481                 m_draw_program  = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_draw_fs);
5482
5483                 glGenTextures(1, &m_texture);
5484                 glBindTexture(GL_TEXTURE_2D, m_texture);
5485                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5486                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_FLOAT, NULL);
5487                 glBindTexture(GL_TEXTURE_2D, 0);
5488
5489                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5490
5491                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
5492                 glUseProgram(m_store_program);
5493                 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 1.0f, 0.0f, 0.0f, 1.0f);
5494                 glBindVertexArray(m_vao);
5495                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5496
5497                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
5498
5499                 glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f);
5500                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5501
5502                 glClear(GL_COLOR_BUFFER_BIT);
5503                 glBindTexture(GL_TEXTURE_2D, m_texture);
5504                 glUseProgram(m_draw_program);
5505                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5506
5507                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5508                 {
5509                         return ERROR;
5510                 }
5511                 return NO_ERROR;
5512         }
5513
5514         virtual long Cleanup()
5515         {
5516                 glUseProgram(0);
5517                 glDeleteBuffers(1, &m_vbo);
5518                 glDeleteTextures(1, &m_texture);
5519                 glDeleteProgram(m_store_program);
5520                 glDeleteProgram(m_draw_program);
5521                 glDeleteVertexArrays(1, &m_vao);
5522                 return NO_ERROR;
5523         }
5524 };
5525 //-----------------------------------------------------------------------------
5526 // 2.1.7 AdvancedSyncBufferUpdate
5527 //-----------------------------------------------------------------------------
5528 class AdvancedSyncBufferUpdate : public ShaderImageLoadStoreBase
5529 {
5530         GLuint m_buffer;
5531         GLuint m_buffer_tex;
5532         GLuint m_store_program;
5533         GLuint m_attribless_vao;
5534
5535         virtual long Setup()
5536         {
5537                 m_buffer                 = 0;
5538                 m_buffer_tex     = 0;
5539                 m_store_program  = 0;
5540                 m_attribless_vao = 0;
5541                 return NO_ERROR;
5542         }
5543
5544         virtual long Run()
5545         {
5546                 if (!SupportedInVS(1))
5547                         return NOT_SUPPORTED;
5548                 const char* const glsl_store_vs =
5549                         "#version 420 core" NL "writeonly uniform imageBuffer g_output_data;" NL "void main() {" NL
5550                         "  imageStore(g_output_data, gl_VertexID, vec4(gl_VertexID));" NL "}";
5551                 m_store_program = BuildProgram(glsl_store_vs, NULL, NULL, NULL, NULL);
5552
5553                 glGenVertexArrays(1, &m_attribless_vao);
5554                 glBindVertexArray(m_attribless_vao);
5555
5556                 glGenBuffers(1, &m_buffer);
5557                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5558                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec4) * 1000, NULL, GL_DYNAMIC_DRAW);
5559                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5560
5561                 glGenTextures(1, &m_buffer_tex);
5562                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
5563                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_buffer);
5564
5565                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5566
5567                 glEnable(GL_RASTERIZER_DISCARD);
5568                 glUseProgram(m_store_program);
5569                 glDrawArrays(GL_POINTS, 0, 1000);
5570
5571                 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5572
5573                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5574                 vec4* ptr =
5575                         reinterpret_cast<vec4*>(glMapBufferRange(GL_TEXTURE_BUFFER, 0, 1000 * sizeof(vec4), GL_MAP_READ_BIT));
5576                 for (int i = 0; i < 1000; ++i)
5577                 {
5578                         if (!IsEqual(ptr[i], vec4(static_cast<float>(i))))
5579                         {
5580                                 m_context.getTestContext().getLog()
5581                                         << tcu::TestLog::Message << "Bad buffer value found at index " << i << tcu::TestLog::EndMessage;
5582                                 return ERROR;
5583                         }
5584                 }
5585                 return NO_ERROR;
5586         }
5587
5588         virtual long Cleanup()
5589         {
5590                 glDisable(GL_RASTERIZER_DISCARD);
5591                 glUseProgram(0);
5592                 glDeleteBuffers(1, &m_buffer);
5593                 glDeleteTextures(1, &m_buffer_tex);
5594                 glDeleteProgram(m_store_program);
5595                 glDeleteVertexArrays(1, &m_attribless_vao);
5596                 return NO_ERROR;
5597         }
5598 };
5599 //-----------------------------------------------------------------------------
5600 // 2.2.1 AdvancedAllStagesOneImage
5601 //-----------------------------------------------------------------------------
5602 class AdvancedAllStagesOneImage : public ShaderImageLoadStoreBase
5603 {
5604         GLuint m_program;
5605         GLuint m_vao;
5606         GLuint m_vbo;
5607         GLuint m_ebo;
5608         GLuint m_buffer;
5609         GLuint m_buffer_tex;
5610         GLuint m_texture;
5611
5612         virtual long Setup()
5613         {
5614                 m_program       = 0;
5615                 m_vao            = 0;
5616                 m_vbo            = 0;
5617                 m_ebo            = 0;
5618                 m_buffer         = 0;
5619                 m_buffer_tex = 0;
5620                 m_texture       = 0;
5621                 return NO_ERROR;
5622         }
5623
5624         virtual long Run()
5625         {
5626                 if (!SupportedInGeomStages(2))
5627                         return NOT_SUPPORTED;
5628                 const char* const glsl_vs =
5629                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
5630                         "layout(r32i) coherent uniform iimageBuffer g_buffer;" NL
5631                         "layout(r32ui) coherent uniform uimage2D g_image;" NL "void main() {" NL
5632                         "  gl_Position = i_position + vec4(1.0, 1.0, 0.0, 0.0);" NL "  imageAtomicAdd(g_buffer, 0, 1);" NL
5633                         "  imageAtomicAdd(g_image, ivec2(0, 0), 2u);" NL "}";
5634                 const char* const glsl_tcs =
5635                         "#version 420 core" NL "layout(vertices = 1) out;" NL
5636                         "layout(r32i) coherent uniform iimageBuffer g_buffer;" NL
5637                         "layout(r32ui) coherent uniform uimage2D g_image;" NL "void main() {" NL
5638                         "  gl_out[gl_InvocationID].gl_Position = gl_in[0].gl_Position;" NL "  gl_TessLevelInner[0] = 1.0;" NL
5639                         "  gl_TessLevelInner[1] = 1.0;" NL "  gl_TessLevelOuter[0] = 1.0;" NL "  gl_TessLevelOuter[1] = 1.0;" NL
5640                         "  gl_TessLevelOuter[2] = 1.0;" NL "  gl_TessLevelOuter[3] = 1.0;" NL "  imageAtomicAdd(g_buffer, 0, 1);" NL
5641                         "  imageAtomicAdd(g_image, ivec2(0, 0), 2u);" NL "}";
5642                 const char* const glsl_tes =
5643                         "#version 420 core" NL "layout(triangles, point_mode) in;" NL
5644                         "layout(r32i) coherent uniform iimageBuffer g_buffer;" NL
5645                         "layout(r32ui) coherent uniform uimage2D g_image;" NL "void main() {" NL
5646                         "  imageAtomicAdd(g_buffer, 0, 1);" NL "  imageAtomicAdd(g_image, ivec2(0, 0), 2u);" NL
5647                         "  gl_Position = gl_in[0].gl_Position;" NL "}";
5648                 const char* const glsl_gs =
5649                         "#version 420 core" NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL
5650                         "layout(r32i) coherent uniform iimageBuffer g_buffer;" NL
5651                         "layout(r32ui) coherent uniform uimage2D g_image;" NL "void main() {" NL
5652                         "  imageAtomicAdd(g_buffer, 0, 1);" NL "  imageAtomicAdd(g_image, ivec2(0, 0), 2u);" NL
5653                         "  gl_Position = gl_in[0].gl_Position;" NL "  EmitVertex();" NL "}";
5654                 const char* const glsl_fs =
5655                         "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
5656                         "layout(r32i) coherent uniform iimageBuffer g_buffer;" NL
5657                         "layout(r32ui) coherent uniform uimage2D g_image;" NL "void main() {" NL
5658                         "  imageAtomicAdd(g_buffer, 0, 1);" NL "  imageAtomicAdd(g_image, ivec2(0, 0), 2u);" NL
5659                         "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "}";
5660                 m_program = BuildProgram(glsl_vs, glsl_tcs, glsl_tes, glsl_gs, glsl_fs);
5661                 glUseProgram(m_program);
5662                 glUniform1i(glGetUniformLocation(m_program, "g_buffer"), 0);
5663                 glUniform1i(glGetUniformLocation(m_program, "g_image"), 1);
5664
5665                 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
5666
5667                 GLint i32 = 0;
5668                 glGenBuffers(1, &m_buffer);
5669                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5670                 glBufferData(GL_TEXTURE_BUFFER, 4, &i32, GL_STATIC_DRAW);
5671                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5672
5673                 glGenTextures(1, &m_buffer_tex);
5674                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
5675                 glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, m_buffer);
5676                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5677
5678                 GLuint ui32 = 0;
5679                 glGenTextures(1, &m_texture);
5680                 glBindTexture(GL_TEXTURE_2D, m_texture);
5681                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5682                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5683                 glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, 1, 1, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &ui32);
5684                 glBindTexture(GL_TEXTURE_2D, 0);
5685
5686                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
5687                 glBindImageTexture(1, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
5688
5689                 glBindVertexArray(m_vao);
5690                 glPatchParameteri(GL_PATCH_VERTICES, 1);
5691
5692                 glDrawElementsInstancedBaseVertex(GL_PATCHES, 1, GL_UNSIGNED_SHORT, 0, 1, 0);
5693                 glDrawElementsInstanced(GL_PATCHES, 1, GL_UNSIGNED_SHORT, 0, 1);
5694
5695                 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5696                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5697                 glGetBufferSubData(GL_TEXTURE_BUFFER, 0, 4, &i32);
5698                 if (i32 < 20 || i32 > 50)
5699                 {
5700                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer value is " << i32
5701                                                                                                 << " should be in the range [20;50]" << tcu::TestLog::EndMessage;
5702                         return ERROR;
5703                 }
5704
5705                 glBindTexture(GL_TEXTURE_2D, m_texture);
5706                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &ui32);
5707                 if (ui32 < 40 || ui32 != static_cast<GLuint>(2 * i32))
5708                 {
5709                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texture value is " << ui32 << " should be "
5710                                                                                                 << (2 * i32) << tcu::TestLog::EndMessage;
5711                         return ERROR;
5712                 }
5713
5714                 return NO_ERROR;
5715         }
5716
5717         virtual long Cleanup()
5718         {
5719                 glPatchParameteri(GL_PATCH_VERTICES, 3);
5720                 glUseProgram(0);
5721                 glDeleteBuffers(1, &m_buffer);
5722                 glDeleteBuffers(1, &m_vbo);
5723                 glDeleteBuffers(1, &m_ebo);
5724                 glDeleteTextures(1, &m_buffer_tex);
5725                 glDeleteTextures(1, &m_texture);
5726                 glDeleteProgram(m_program);
5727                 glDeleteVertexArrays(1, &m_vao);
5728                 return NO_ERROR;
5729         }
5730 };
5731 //-----------------------------------------------------------------------------
5732 // 2.3.1 AdvancedMemoryDependentInvocation
5733 //-----------------------------------------------------------------------------
5734 class AdvancedMemoryDependentInvocation : public ShaderImageLoadStoreBase
5735 {
5736         GLuint m_buffer;
5737         GLuint m_buffer_tex;
5738         GLuint m_texture;
5739         GLuint m_program;
5740         GLuint m_vao;
5741         GLuint m_vbo;
5742
5743         virtual long Setup()
5744         {
5745                 m_buffer         = 0;
5746                 m_buffer_tex = 0;
5747                 m_texture       = 0;
5748                 m_program       = 0;
5749                 m_vao            = 0;
5750                 m_vbo            = 0;
5751                 return NO_ERROR;
5752         }
5753
5754         virtual long Run()
5755         {
5756                 if (!SupportedInVS(2))
5757                         return NOT_SUPPORTED;
5758                 const char* const glsl_vs =
5759                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
5760                         "layout(location = 1) in vec4 i_color;" NL "out vec4 vs_color;" NL
5761                         "layout(rgba32f) coherent uniform imageBuffer g_buffer;" NL
5762                         "layout(rgba32f) coherent uniform image2D g_image;" NL "void main() {" NL "  gl_Position = i_position;" NL
5763                         "  vs_color = i_color;" NL "  imageStore(g_buffer, 0, vec4(1.0));" NL
5764                         "  imageStore(g_image, ivec2(0, 0), vec4(2.0));" NL "  memoryBarrier();" NL "}";
5765                 const char* const glsl_fs =
5766                         "#version 420 core" NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL
5767                         "layout(rgba32f) coherent uniform imageBuffer g_buffer;" NL
5768                         "layout(rgba32f) coherent uniform image2D g_image;" NL "void main() {" NL "  o_color = vs_color;" NL
5769                         "  if (imageLoad(g_buffer, 0) != vec4(1.0)) o_color = vec4(1.0, 0.0, 0.0, 0.1);" NL
5770                         "  if (imageLoad(g_image, ivec2(0, 0)) != vec4(2.0)) o_color = vec4(1.0, 0.0, 0.0, 0.2);" NL "}";
5771                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
5772                 glUseProgram(m_program);
5773                 glUniform1i(glGetUniformLocation(m_program, "g_buffer"), 0);
5774                 glUniform1i(glGetUniformLocation(m_program, "g_image"), 1);
5775
5776                 vec4 zero(0);
5777                 glGenBuffers(1, &m_buffer);
5778                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5779                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec4), &zero, GL_STATIC_DRAW);
5780                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5781
5782                 glGenTextures(1, &m_buffer_tex);
5783                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
5784                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_buffer);
5785                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5786
5787                 glGenTextures(1, &m_texture);
5788                 glBindTexture(GL_TEXTURE_2D, m_texture);
5789                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5790                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, &zero);
5791                 glBindTexture(GL_TEXTURE_2D, 0);
5792
5793                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5794                 glBindImageTexture(1, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5795
5796                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5797
5798                 glClear(GL_COLOR_BUFFER_BIT);
5799                 glBindVertexArray(m_vao);
5800                 glDrawArraysInstancedBaseInstance(GL_TRIANGLE_STRIP, 0, 4, 1, 0);
5801
5802                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5803                 {
5804                         return ERROR;
5805                 }
5806                 return NO_ERROR;
5807         }
5808
5809         virtual long Cleanup()
5810         {
5811                 glUseProgram(0);
5812                 glDeleteBuffers(1, &m_vbo);
5813                 glDeleteBuffers(1, &m_buffer);
5814                 glDeleteTextures(1, &m_texture);
5815                 glDeleteTextures(1, &m_buffer_tex);
5816                 glDeleteProgram(m_program);
5817                 glDeleteVertexArrays(1, &m_vao);
5818                 return NO_ERROR;
5819         }
5820 };
5821 //-----------------------------------------------------------------------------
5822 // 2.3.2 AdvancedMemoryOrder
5823 //-----------------------------------------------------------------------------
5824 class AdvancedMemoryOrder : public ShaderImageLoadStoreBase
5825 {
5826         GLuint m_buffer;
5827         GLuint m_buffer_tex;
5828         GLuint m_texture;
5829         GLuint m_program;
5830         GLuint m_vao;
5831         GLuint m_vbo;
5832
5833         virtual long Setup()
5834         {
5835                 m_buffer         = 0;
5836                 m_buffer_tex = 0;
5837                 m_texture       = 0;
5838                 m_program       = 0;
5839                 m_vao            = 0;
5840                 m_vbo            = 0;
5841                 return NO_ERROR;
5842         }
5843
5844         virtual long Run()
5845         {
5846                 if (!SupportedInVS(1))
5847                         return NOT_SUPPORTED;
5848                 const char* const glsl_vs =
5849                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "out vec4 vs_color;" NL
5850                         "layout(rgba32f) coherent uniform imageBuffer g_buffer;" NL "void main() {" NL
5851                         "  gl_Position = i_position;" NL "  vs_color = vec4(0, 1, 0, 1);" NL
5852                         "  imageStore(g_buffer, gl_VertexID, vec4(1.0));" NL "  imageStore(g_buffer, gl_VertexID, vec4(2.0));" NL
5853                         "  imageStore(g_buffer, gl_VertexID, vec4(3.0));" NL
5854                         "  if (imageLoad(g_buffer, gl_VertexID) != vec4(3.0)) vs_color = vec4(1, 0, 0, 1);" NL "}";
5855                 const char* const glsl_fs =
5856                         "#version 420 core" NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL
5857                         "layout(rgba32f) uniform image2D g_image;" NL "void main() {" NL "  o_color = vs_color;" NL
5858                         "  ivec2 coord = ivec2(gl_FragCoord);" NL "  for (int i = 0; i < 3; ++i) {" NL
5859                         "    imageStore(g_image, coord, vec4(i));" NL "    vec4 v = imageLoad(g_image, coord);" NL
5860                         "    if (v != vec4(i)) {" NL "      o_color = vec4(v.xyz, 0.0);" NL "      break;" NL "    }" NL "  }" NL
5861                         "}";
5862                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
5863                 glUseProgram(m_program);
5864                 glUniform1i(glGetUniformLocation(m_program, "g_buffer"), 0);
5865                 glUniform1i(glGetUniformLocation(m_program, "g_image"), 1);
5866
5867                 glGenBuffers(1, &m_buffer);
5868                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
5869                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec4) * 4, NULL, GL_STATIC_DRAW);
5870                 glBindBuffer(GL_TEXTURE_BUFFER, 0);
5871
5872                 glGenTextures(1, &m_buffer_tex);
5873                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
5874                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_buffer);
5875                 glBindTexture(GL_TEXTURE_BUFFER, 0);
5876
5877                 std::vector<vec4> data(getWindowWidth() * getWindowHeight());
5878                 glGenTextures(1, &m_texture);
5879                 glBindTexture(GL_TEXTURE_2D, m_texture);
5880                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5881                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_FLOAT, &data[0]);
5882                 glBindTexture(GL_TEXTURE_2D, 0);
5883
5884                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5885                 glBindImageTexture(1, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5886
5887                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5888
5889                 glClear(GL_COLOR_BUFFER_BIT);
5890                 glBindVertexArray(m_vao);
5891                 glDrawArraysInstancedBaseInstance(GL_TRIANGLE_STRIP, 0, 4, 1, 0);
5892
5893                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
5894                 {
5895                         return ERROR;
5896                 }
5897                 return NO_ERROR;
5898         }
5899
5900         virtual long Cleanup()
5901         {
5902                 glUseProgram(0);
5903                 glDeleteBuffers(1, &m_vbo);
5904                 glDeleteBuffers(1, &m_buffer);
5905                 glDeleteTextures(1, &m_texture);
5906                 glDeleteTextures(1, &m_buffer_tex);
5907                 glDeleteProgram(m_program);
5908                 glDeleteVertexArrays(1, &m_vao);
5909                 return NO_ERROR;
5910         }
5911 };
5912 //-----------------------------------------------------------------------------
5913 // 2.4.1 AdvancedSSOSimple
5914 //-----------------------------------------------------------------------------
5915 class AdvancedSSOSimple : public ShaderImageLoadStoreBase
5916 {
5917         GLuint m_texture;
5918         GLuint m_pipeline[2];
5919         GLuint m_vsp, m_fsp0, m_fsp1;
5920         GLuint m_vao, m_vbo;
5921
5922         virtual long Setup()
5923         {
5924                 glGenTextures(1, &m_texture);
5925                 glGenProgramPipelines(2, m_pipeline);
5926                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
5927
5928                 const char* const glsl_vs =
5929                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "out gl_PerVertex {" NL
5930                         "  vec4 gl_Position;" NL "};" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
5931                 const char* const glsl_fs0 =
5932                         "#version 420 core" NL "layout(rgba32f) uniform image2D g_image[4];" NL "void main() {" NL
5933                         "  for (int i = 0; i < g_image.length(); ++i) {" NL
5934                         "    imageStore(g_image[i], ivec2(gl_FragCoord), vec4(1.0));" NL "  }" NL "  discard;" NL "}";
5935                 const char* const glsl_fs1 =
5936                         "#version 420 core" NL "writeonly uniform image2D g_image[4];" NL "void main() {" NL
5937                         "  for (int i = 0; i < g_image.length(); ++i) {" NL
5938                         "    imageStore(g_image[i], ivec2(gl_FragCoord), vec4(2.0));" NL "  }" NL "  discard;" NL "}";
5939                 m_vsp  = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs);
5940                 m_fsp0 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs0);
5941                 m_fsp1 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs1);
5942
5943                 return NO_ERROR;
5944         }
5945
5946         virtual long Run()
5947         {
5948                 glProgramUniform1i(m_fsp0, glGetUniformLocation(m_fsp0, "g_image[0]"), 0);
5949                 glProgramUniform1i(m_fsp0, glGetUniformLocation(m_fsp0, "g_image[1]"), 2);
5950                 glProgramUniform1i(m_fsp0, glGetUniformLocation(m_fsp0, "g_image[2]"), 4);
5951                 glProgramUniform1i(m_fsp0, glGetUniformLocation(m_fsp0, "g_image[3]"), 6);
5952
5953                 glProgramUniform1i(m_fsp1, glGetUniformLocation(m_fsp1, "g_image[0]"), 1);
5954                 glProgramUniform1i(m_fsp1, glGetUniformLocation(m_fsp1, "g_image[1]"), 3);
5955                 glProgramUniform1i(m_fsp1, glGetUniformLocation(m_fsp1, "g_image[2]"), 5);
5956                 glProgramUniform1i(m_fsp1, glGetUniformLocation(m_fsp1, "g_image[3]"), 7);
5957
5958                 glUseProgramStages(m_pipeline[0], GL_VERTEX_SHADER_BIT, m_vsp);
5959                 glUseProgramStages(m_pipeline[0], GL_FRAGMENT_SHADER_BIT, m_fsp0);
5960
5961                 glUseProgramStages(m_pipeline[1], GL_VERTEX_SHADER_BIT, m_vsp);
5962                 glUseProgramStages(m_pipeline[1], GL_FRAGMENT_SHADER_BIT, m_fsp1);
5963
5964                 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
5965                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5966                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 8, 0, GL_RGBA, GL_FLOAT,
5967                                          NULL);
5968
5969                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
5970                 glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_RGBA32F);
5971                 glBindImageTexture(2, m_texture, 0, GL_FALSE, 2, GL_READ_WRITE, GL_RGBA32F);
5972                 glBindImageTexture(3, m_texture, 0, GL_FALSE, 3, GL_READ_WRITE, GL_RGBA32F);
5973                 glBindImageTexture(4, m_texture, 0, GL_FALSE, 4, GL_READ_WRITE, GL_RGBA32F);
5974                 glBindImageTexture(5, m_texture, 0, GL_FALSE, 5, GL_READ_WRITE, GL_RGBA32F);
5975                 glBindImageTexture(6, m_texture, 0, GL_FALSE, 6, GL_READ_WRITE, GL_RGBA32F);
5976                 glBindImageTexture(7, m_texture, 0, GL_FALSE, 7, GL_READ_WRITE, GL_RGBA32F);
5977
5978                 glBindVertexArray(m_vao);
5979
5980                 glBindProgramPipeline(m_pipeline[0]);
5981                 glDrawArraysInstancedBaseInstance(GL_TRIANGLE_STRIP, 0, 4, 1, 0);
5982
5983                 glBindProgramPipeline(m_pipeline[1]);
5984                 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5985
5986                 std::vector<vec4> data(getWindowWidth() * getWindowHeight() * 8);
5987                 glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_FLOAT, &data[0]);
5988
5989                 for (int layer = 0; layer < 8; ++layer)
5990                 {
5991                         for (int h = 0; h < getWindowHeight(); ++h)
5992                         {
5993                                 for (int w = 0; w < getWindowWidth(); ++w)
5994                                 {
5995                                         const vec4 c = data[layer * getWindowWidth() * getWindowHeight() + h * getWindowWidth() + w];
5996                                         if (layer % 2)
5997                                         {
5998                                                 if (!IsEqual(c, vec4(2.0f)))
5999                                                 {
6000                                                         return ERROR;
6001                                                 }
6002                                         }
6003                                         else
6004                                         {
6005                                                 if (!IsEqual(c, vec4(1.0f)))
6006                                                 {
6007                                                         return ERROR;
6008                                                 }
6009                                         }
6010                                 }
6011                         }
6012                 }
6013                 return NO_ERROR;
6014         }
6015
6016         virtual long Cleanup()
6017         {
6018                 glDeleteBuffers(1, &m_vbo);
6019                 glDeleteTextures(1, &m_texture);
6020                 glDeleteProgram(m_vsp);
6021                 glDeleteProgram(m_fsp0);
6022                 glDeleteProgram(m_fsp1);
6023                 glDeleteVertexArrays(1, &m_vao);
6024                 glDeleteProgramPipelines(2, m_pipeline);
6025                 return NO_ERROR;
6026         }
6027 };
6028 //-----------------------------------------------------------------------------
6029 // 2.4.2 AdvancedSSOAtomicCounters
6030 //-----------------------------------------------------------------------------
6031 class AdvancedSSOAtomicCounters : public ShaderImageLoadStoreBase
6032 {
6033         GLuint m_buffer, m_buffer_tex;
6034         GLuint m_counter_buffer;
6035         GLuint m_transform_buffer;
6036         GLuint m_pipeline;
6037         GLuint m_vao, m_vbo;
6038         GLuint m_vsp, m_fsp;
6039
6040         virtual long Setup()
6041         {
6042                 m_vao = 0;
6043                 m_vbo = 0;
6044                 m_vsp = 0;
6045                 m_fsp = 0;
6046                 glGenBuffers(1, &m_buffer);
6047                 glGenTextures(1, &m_buffer_tex);
6048                 glGenBuffers(1, &m_counter_buffer);
6049                 glGenBuffers(1, &m_transform_buffer);
6050                 glGenProgramPipelines(1, &m_pipeline);
6051                 return NO_ERROR;
6052         }
6053
6054         virtual long Run()
6055         {
6056                 if (!SupportedInVS(1))
6057                         return NOT_SUPPORTED;
6058
6059                 CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
6060                 const char* const glsl_vs =
6061                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
6062                         "layout(location = 1) in vec4 i_color;" NL "layout(location = 3) out vec4 o_color;" NL
6063                         "out gl_PerVertex {" NL "  vec4 gl_Position;" NL "};" NL "layout(std140) uniform Transform {" NL
6064                         "  mat4 mvp;" NL "} g_transform;" NL "writeonly uniform imageBuffer g_buffer;" NL
6065                         "layout(binding = 0, offset = 0) uniform atomic_uint g_counter;" NL "void main() {" NL
6066                         "  gl_Position = g_transform.mvp * i_position;" NL "  o_color = i_color;" NL
6067                         "  const uint index = atomicCounterIncrement(g_counter);" NL
6068                         "  imageStore(g_buffer, int(index), gl_Position);" NL "}";
6069                 const char* const glsl_fs =
6070                         "#version 420 core" NL "layout(location = 3) in vec4 i_color;" NL
6071                         "layout(location = 0) out vec4 o_color;" NL "void main() {" NL "  o_color = i_color;" NL "}";
6072                 m_vsp = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs);
6073                 m_fsp = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs);
6074
6075                 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp);
6076                 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_fsp);
6077
6078                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
6079                 glBufferData(GL_TEXTURE_BUFFER, sizeof(vec4) * 4, NULL, GL_STATIC_DRAW);
6080
6081                 glBindTexture(GL_TEXTURE_BUFFER, m_buffer_tex);
6082                 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_buffer);
6083
6084                 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_counter_buffer);
6085                 vec4 zero(0);
6086                 glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), &zero, GL_STATIC_DRAW);
6087
6088                 glBindBuffer(GL_UNIFORM_BUFFER, m_transform_buffer);
6089                 mat4 identity(1);
6090                 glBufferData(GL_UNIFORM_BUFFER, sizeof(mat4), &identity, GL_STATIC_DRAW);
6091
6092                 glClear(GL_COLOR_BUFFER_BIT);
6093                 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, m_counter_buffer);
6094                 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transform_buffer);
6095                 glBindImageTexture(0, m_buffer_tex, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6096                 glBindVertexArray(m_vao);
6097                 glBindProgramPipeline(m_pipeline);
6098                 glDrawArraysInstancedBaseInstance(GL_TRIANGLE_STRIP, 0, 4, 1, 0);
6099
6100                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
6101                 {
6102                         return ERROR;
6103                 }
6104
6105                 std::vector<vec4> data(4);
6106                 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
6107                 glGetBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(vec4) * 4, &data[0]);
6108
6109                 for (int i = 0; i < 4; ++i)
6110                 {
6111                         if (!IsEqual(data[i], vec4(-1.0f, -1.0f, 0.0f, 1.0f)) && !IsEqual(data[i], vec4(1.0f, -1.0f, 0.0f, 1.0f)) &&
6112                                 !IsEqual(data[i], vec4(-1.0f, 1.0f, 0.0f, 1.0f)) && !IsEqual(data[i], vec4(1.0f, 1.0f, 0.0f, 1.0f)))
6113                         {
6114                                 return ERROR;
6115                         }
6116                 }
6117
6118                 return NO_ERROR;
6119         }
6120
6121         virtual long Cleanup()
6122         {
6123                 glDeleteBuffers(1, &m_buffer);
6124                 glDeleteBuffers(1, &m_vbo);
6125                 glDeleteBuffers(1, &m_counter_buffer);
6126                 glDeleteBuffers(1, &m_transform_buffer);
6127                 glDeleteTextures(1, &m_buffer_tex);
6128                 glDeleteProgram(m_vsp);
6129                 glDeleteProgram(m_fsp);
6130                 glDeleteVertexArrays(1, &m_vao);
6131                 glDeleteProgramPipelines(1, &m_pipeline);
6132                 return NO_ERROR;
6133         }
6134 };
6135 //-----------------------------------------------------------------------------
6136 // 2.4.3 AdvancedSSOSubroutine
6137 //-----------------------------------------------------------------------------
6138 class AdvancedSSOSubroutine : public ShaderImageLoadStoreBase
6139 {
6140         GLuint m_texture;
6141         GLuint m_attribless_vao;
6142         GLuint m_program;
6143         GLint  m_draw_buffer;
6144
6145         virtual long Setup()
6146         {
6147                 glGenTextures(1, &m_texture);
6148                 glGenVertexArrays(1, &m_attribless_vao);
6149
6150                 const char* const glsl_vs = "#version 420 core" NL "const int kSize = 3;" NL
6151                                                                         "const vec2 g_triangle[kSize] = vec2[3](vec2(-1, -1), vec2(3, -1), vec2(-1, 3));" NL
6152                                                                         "void main() {" NL "  gl_Position = vec4(g_triangle[gl_VertexID], 0, 1);" NL "}";
6153                 const char* const glsl_fs =
6154                         "#version 420 core" NL "writeonly uniform image2DArray g_image0;" NL
6155                         "writeonly uniform image2DArray g_image1;" NL "subroutine void Brush(ivec2 coord);" NL
6156                         "subroutine uniform Brush g_brush;" NL "subroutine(Brush) void Brush0(ivec2 coord) {" NL
6157                         "  imageStore(g_image0, ivec3(coord, 0), vec4(1.0, 0.0, 0.0, 1.0));" NL
6158                         "  imageStore(g_image0, ivec3(coord, 1), vec4(0.0, 1.0, 0.0, 1.0));" NL
6159                         "  imageStore(g_image0, ivec3(coord, 2), vec4(0.0, 0.0, 1.0, 1.0));" NL "}" NL
6160                         "subroutine(Brush) void Brush1(ivec2 coord) {" NL
6161                         "  imageStore(g_image1, ivec3(coord, 0), vec4(0.0, 1.0, 0.0, 1.0));" NL
6162                         "  imageStore(g_image1, ivec3(coord, 1), vec4(0.0, 0.0, 1.0, 1.0));" NL
6163                         "  imageStore(g_image1, ivec3(coord, 2), vec4(1.0, 0.0, 0.0, 1.0));" NL "}" NL "void main() {" NL
6164                         "  g_brush(ivec2(gl_FragCoord));" NL "}";
6165                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
6166
6167                 return NO_ERROR;
6168         }
6169
6170         virtual long Run()
6171         {
6172                 glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image0"), 1);
6173                 glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image1"), 1);
6174
6175                 glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
6176                 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6177                 glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 3, 0, GL_RGBA, GL_FLOAT,
6178                                          NULL);
6179
6180                 glGetIntegerv(GL_DRAW_BUFFER, &m_draw_buffer);
6181
6182                 glDrawBuffer(GL_NONE);
6183                 glBindImageTexture(1, m_texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA32F);
6184                 glUseProgram(m_program);
6185                 glBindVertexArray(m_attribless_vao);
6186
6187                 const GLuint indices[2] = { glGetSubroutineIndex(m_program, GL_FRAGMENT_SHADER, "Brush0"),
6188                                                                         glGetSubroutineIndex(m_program, GL_FRAGMENT_SHADER, "Brush1") };
6189
6190                 glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &indices[0]);
6191                 glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);
6192
6193                 std::vector<vec4> data(getWindowWidth() * getWindowHeight() * 3);
6194                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
6195                 glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_FLOAT, &data[0]);
6196
6197                 for (int layer = 0; layer < 3; ++layer)
6198                 {
6199                         for (int h = 0; h < getWindowHeight(); ++h)
6200                         {
6201                                 for (int w = 0; w < getWindowWidth(); ++w)
6202                                 {
6203                                         const vec4 c = data[layer * getWindowWidth() * getWindowHeight() + h * getWindowWidth() + w];
6204                                         if (layer == 0 && !IsEqual(c, vec4(1.0f, 0.0f, 0.0f, 1.0f)))
6205                                         {
6206                                                 m_context.getTestContext().getLog()
6207                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6208                                                         << ") should be (1 0 0 1)" << tcu::TestLog::EndMessage;
6209                                                 return ERROR;
6210                                         }
6211                                         else if (layer == 1 && !IsEqual(c, vec4(0.0f, 1.0f, 0.0f, 1.0f)))
6212                                         {
6213                                                 m_context.getTestContext().getLog()
6214                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6215                                                         << ") should be (0 1 0 1)" << tcu::TestLog::EndMessage;
6216                                                 return ERROR;
6217                                         }
6218                                         else if (layer == 2 && !IsEqual(c, vec4(0.0f, 0.0f, 1.0f, 1.0f)))
6219                                         {
6220                                                 m_context.getTestContext().getLog()
6221                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6222                                                         << ") should be (0 0 1 1)" << tcu::TestLog::EndMessage;
6223                                                 return ERROR;
6224                                         }
6225                                 }
6226                         }
6227                 }
6228
6229                 glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &indices[1]);
6230                 glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 3, 1, 0);
6231
6232                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
6233                 glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_FLOAT, &data[0]);
6234
6235                 for (int layer = 0; layer < 3; ++layer)
6236                 {
6237                         for (int h = 0; h < getWindowHeight(); ++h)
6238                         {
6239                                 for (int w = 0; w < getWindowWidth(); ++w)
6240                                 {
6241                                         const vec4 c = data[layer * getWindowWidth() * getWindowHeight() + h * getWindowWidth() + w];
6242                                         if (layer == 0 && !IsEqual(c, vec4(0.0f, 1.0f, 0.0f, 1.0f)))
6243                                         {
6244                                                 m_context.getTestContext().getLog()
6245                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6246                                                         << ") should be (0 1 0 1)" << tcu::TestLog::EndMessage;
6247                                                 return ERROR;
6248                                         }
6249                                         else if (layer == 1 && !IsEqual(c, vec4(0.0f, 0.0f, 1.0f, 1.0f)))
6250                                         {
6251                                                 m_context.getTestContext().getLog()
6252                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6253                                                         << ") should be (0 0 1 1)" << tcu::TestLog::EndMessage;
6254                                                 return ERROR;
6255                                         }
6256                                         else if (layer == 2 && !IsEqual(c, vec4(1.0f, 0.0f, 0.0f, 1.0f)))
6257                                         {
6258                                                 m_context.getTestContext().getLog()
6259                                                         << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6260                                                         << ") should be (1 0 0 1)" << tcu::TestLog::EndMessage;
6261                                                 return ERROR;
6262                                         }
6263                                 }
6264                         }
6265                 }
6266                 return NO_ERROR;
6267         }
6268
6269         virtual long Cleanup()
6270         {
6271                 glDrawBuffer(m_draw_buffer);
6272                 glDeleteTextures(1, &m_texture);
6273                 glUseProgram(0);
6274                 glDeleteProgram(m_program);
6275                 glDeleteVertexArrays(1, &m_attribless_vao);
6276                 return NO_ERROR;
6277         }
6278 };
6279 //-----------------------------------------------------------------------------
6280 // 2.4.4 AdvancedSSOPerSample
6281 //-----------------------------------------------------------------------------
6282 class AdvancedSSOPerSample : public ShaderImageLoadStoreBase
6283 {
6284         GLuint m_texture;
6285         GLuint m_pipeline;
6286         GLuint m_vao, m_vbo, m_ebo;
6287         GLuint m_vsp, m_store_fsp, m_load_fsp;
6288
6289         virtual long Setup()
6290         {
6291                 m_vao           = 0;
6292                 m_vbo           = 0;
6293                 m_ebo           = 0;
6294                 m_vsp           = 0;
6295                 m_store_fsp = 0;
6296                 m_load_fsp  = 0;
6297                 glGenTextures(1, &m_texture);
6298                 glGenProgramPipelines(1, &m_pipeline);
6299
6300                 return NO_ERROR;
6301         }
6302
6303         virtual long Run()
6304         {
6305                 if (!SupportedSamples(4))
6306                         return NOT_SUPPORTED;
6307
6308                 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
6309
6310                 const char* const glsl_vs =
6311                         "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "out gl_PerVertex {" NL
6312                         "  vec4 gl_Position;" NL "};" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
6313                 const char* const glsl_store_fs =
6314                         "#version 420 core" NL "layout(rgba32f) writeonly uniform image2DMS g_image;" NL "void main() {" NL
6315                         "  imageStore(g_image, ivec2(gl_FragCoord), gl_SampleID, vec4(gl_SampleID+1));" NL "}";
6316                 const char* const glsl_load_fs =
6317                         "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
6318                         "layout(rgba32f) readonly uniform image2DMS g_image;" NL "void main() {" NL
6319                         "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "  if (imageLoad(g_image, ivec2(gl_FragCoord), gl_SampleID) != "
6320                         "vec4(gl_SampleID+1)) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
6321                 m_vsp           = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs);
6322                 m_store_fsp = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_store_fs);
6323                 m_load_fsp  = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_load_fs);
6324
6325                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_texture);
6326                 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA32F, getWindowWidth(), getWindowHeight(),
6327                                                                 GL_FALSE);
6328                 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
6329
6330                 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp);
6331                 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_store_fsp);
6332
6333                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6334
6335                 glClear(GL_COLOR_BUFFER_BIT);
6336                 glBindVertexArray(m_vao);
6337                 glBindProgramPipeline(m_pipeline);
6338                 glDrawElementsInstancedBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6339
6340                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
6341
6342                 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_load_fsp);
6343                 glDrawElementsInstancedBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6344
6345                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
6346                 {
6347                         return ERROR;
6348                 }
6349                 return NO_ERROR;
6350         }
6351
6352         virtual long Cleanup()
6353         {
6354                 glDeleteBuffers(1, &m_vbo);
6355                 glDeleteBuffers(1, &m_ebo);
6356                 glDeleteTextures(1, &m_texture);
6357                 glDeleteProgram(m_vsp);
6358                 glDeleteProgram(m_store_fsp);
6359                 glDeleteProgram(m_load_fsp);
6360                 glDeleteVertexArrays(1, &m_vao);
6361                 glDeleteProgramPipelines(1, &m_pipeline);
6362                 return NO_ERROR;
6363         }
6364 };
6365
6366 //-----------------------------------------------------------------------------
6367 // 2.5 AdvancedCopyImage
6368 //-----------------------------------------------------------------------------
6369 class AdvancedCopyImage : public ShaderImageLoadStoreBase
6370 {
6371         GLuint m_texture[2];
6372         GLuint m_program;
6373         GLuint m_vao, m_vbo, m_ebo;
6374
6375         virtual long Setup()
6376         {
6377                 glGenTextures(2, m_texture);
6378                 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
6379
6380                 const char* const glsl_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
6381                                                                         "void main() {" NL "  gl_Position = i_position;" NL "}";
6382                 const char* const glsl_fs =
6383                         "#version 420 core" NL "layout(rgba32f) readonly uniform image2D g_input_image;" NL
6384                         "layout(rgba32f) writeonly uniform image2D g_output_image;" NL "void main() {" NL
6385                         "  ivec2 coord = ivec2(gl_FragCoord);" NL
6386                         "  imageStore(g_output_image, coord, imageLoad(g_input_image, coord));" NL "  discard;" NL "}";
6387                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
6388
6389                 return NO_ERROR;
6390         }
6391
6392         virtual long Run()
6393         {
6394                 glUseProgram(m_program);
6395                 glUniform1i(glGetUniformLocation(m_program, "g_input_image"), 0);
6396                 glUniform1i(glGetUniformLocation(m_program, "g_output_image"), 1);
6397
6398                 std::vector<vec4> data(getWindowWidth() * getWindowHeight(), vec4(7.0f));
6399                 glBindTexture(GL_TEXTURE_2D, m_texture[0]);
6400                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6401                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_FLOAT, &data[0]);
6402
6403                 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
6404                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6405                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_FLOAT, NULL);
6406
6407                 glBindTexture(GL_TEXTURE_2D, 0);
6408
6409                 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
6410                 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
6411
6412                 glClear(GL_COLOR_BUFFER_BIT);
6413                 glBindVertexArray(m_vao);
6414                 glDrawElementsInstancedBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6415
6416                 std::vector<vec4> rdata(getWindowWidth() * getWindowHeight());
6417                 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
6418                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, &rdata[0]);
6419
6420                 for (int h = 0; h < getWindowHeight(); ++h)
6421                 {
6422                         for (int w = 0; w < getWindowWidth(); ++w)
6423                         {
6424                                 if (!IsEqual(rdata[h * getWindowWidth() + w], vec4(7.0f)))
6425                                 {
6426                                         return ERROR;
6427                                 }
6428                         }
6429                 }
6430                 return NO_ERROR;
6431         }
6432
6433         virtual long Cleanup()
6434         {
6435                 glUseProgram(0);
6436                 glDeleteBuffers(1, &m_vbo);
6437                 glDeleteBuffers(1, &m_ebo);
6438                 glDeleteTextures(2, m_texture);
6439                 glDeleteProgram(m_program);
6440                 glDeleteVertexArrays(1, &m_vao);
6441                 return NO_ERROR;
6442         }
6443 };
6444 //-----------------------------------------------------------------------------
6445 // 2.6 AdvancedAllMips
6446 //-----------------------------------------------------------------------------
6447 class AdvancedAllMips : public ShaderImageLoadStoreBase
6448 {
6449         GLuint m_texture;
6450         GLuint m_store_program, m_load_program;
6451         GLuint m_vao, m_vbo, m_ebo;
6452
6453         virtual long Setup()
6454         {
6455                 glGenTextures(1, &m_texture);
6456                 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
6457
6458                 const char* const glsl_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
6459                                                                         "void main() {" NL "  gl_Position = i_position;" NL "}";
6460                 const char* const glsl_store_fs =
6461                         "#version 420 core" NL "layout(rgba32f) uniform image2D g_image[6];" NL "void main() {" NL
6462                         "  for (int i = 0; i < 6; ++i) {" NL "    imageStore(g_image[i], ivec2(gl_FragCoord), vec4(i));" NL "  }" NL
6463                         "  discard;" NL "}";
6464                 const char* const glsl_load_fs =
6465                         "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
6466                         "layout(rgba32f) uniform image2D g_image[6];" NL "void main() {" NL
6467                         "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "  for (int i = 0; i < 6; ++i) {" NL
6468                         "    const ivec2 coord = ivec2(gl_FragCoord);" NL "    const vec4 c = imageLoad(g_image[i], coord);" NL
6469                         "    if (c != vec4(i) && c != vec4(0.0)) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "  }" NL "}";
6470                 m_store_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_store_fs);
6471                 m_load_program  = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_load_fs);
6472
6473                 return NO_ERROR;
6474         }
6475
6476         virtual long Run()
6477         {
6478                 glUseProgram(m_store_program);
6479                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[0]"), 0);
6480                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[1]"), 1);
6481                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[2]"), 2);
6482                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[3]"), 3);
6483                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[4]"), 4);
6484                 glUniform1i(glGetUniformLocation(m_store_program, "g_image[5]"), 5);
6485                 glUseProgram(0);
6486
6487                 glUseProgram(m_load_program);
6488                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[0]"), 0);
6489                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[1]"), 1);
6490                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[2]"), 2);
6491                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[3]"), 3);
6492                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[4]"), 4);
6493                 glUniform1i(glGetUniformLocation(m_load_program, "g_image[5]"), 5);
6494                 glUseProgram(0);
6495
6496                 glBindTexture(GL_TEXTURE_2D, m_texture);
6497                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 32, 32, 0, GL_RGBA, GL_FLOAT, NULL);
6498                 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL);
6499                 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA32F, 8, 8, 0, GL_RGBA, GL_FLOAT, NULL);
6500                 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA32F, 4, 4, 0, GL_RGBA, GL_FLOAT, NULL);
6501                 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA32F, 2, 2, 0, GL_RGBA, GL_FLOAT, NULL);
6502                 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA32F, 1, 1, 0, GL_RGBA, GL_FLOAT, NULL);
6503                 glBindTexture(GL_TEXTURE_2D, 0);
6504
6505                 glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6506                 glBindImageTexture(1, m_texture, 1, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6507                 glBindImageTexture(2, m_texture, 2, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6508                 glBindImageTexture(3, m_texture, 3, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6509                 glBindImageTexture(4, m_texture, 4, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6510                 glBindImageTexture(5, m_texture, 5, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
6511
6512                 glViewport(0, 0, 32, 32);
6513                 glBindVertexArray(m_vao);
6514
6515                 glClear(GL_COLOR_BUFFER_BIT);
6516                 glUseProgram(m_store_program);
6517                 glDrawElementsInstancedBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6518
6519                 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
6520
6521                 glUseProgram(m_load_program);
6522                 glDrawElementsInstancedBaseVertex(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6523
6524                 if (!ValidateReadBuffer(0, 0, 32, 32, vec4(0, 1, 0, 1)))
6525                 {
6526                         return ERROR;
6527                 }
6528                 return NO_ERROR;
6529         }
6530
6531         virtual long Cleanup()
6532         {
6533                 glViewport(0, 0, getWindowWidth(), getWindowHeight());
6534                 glUseProgram(0);
6535                 glDeleteBuffers(1, &m_vbo);
6536                 glDeleteBuffers(1, &m_ebo);
6537                 glDeleteTextures(1, &m_texture);
6538                 glDeleteProgram(m_store_program);
6539                 glDeleteProgram(m_load_program);
6540                 glDeleteVertexArrays(1, &m_vao);
6541                 return NO_ERROR;
6542         }
6543 };
6544 //-----------------------------------------------------------------------------
6545 // 2.7 AdvancedCast
6546 //-----------------------------------------------------------------------------
6547 class AdvancedCast : public ShaderImageLoadStoreBase
6548 {
6549         GLuint m_texture[2];
6550         GLuint m_program;
6551         GLuint m_vao, m_vbo, m_ebo;
6552
6553         virtual long Setup()
6554         {
6555                 glGenTextures(2, m_texture);
6556                 CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
6557
6558                 const char* const glsl_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
6559                                                                         "void main() {" NL "  gl_Position = i_position;" NL "}";
6560                 const char* const glsl_fs =
6561                         "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
6562                         "layout(r32i) coherent uniform iimage2D g_image0;" NL "layout(r32ui) coherent uniform uimage2D g_image1;" NL
6563                         "void main() {" NL "  o_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "  ivec2 coord = ivec2(gl_FragCoord);" NL
6564                         "  if (imageAtomicAdd(g_image0, coord, 2) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
6565                         "  if (imageAtomicAdd(g_image0, coord, -1) != 2) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
6566                         "  if (imageAtomicAdd(g_image1, coord, 1) != 0) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
6567                         "  if (imageAtomicAdd(g_image1, coord, 2) != 1) o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
6568                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
6569
6570                 return NO_ERROR;
6571         }
6572
6573         virtual long Run()
6574         {
6575                 glUseProgram(m_program);
6576                 glUniform1i(glGetUniformLocation(m_program, "g_image0"), 0);
6577                 glUniform1i(glGetUniformLocation(m_program, "g_image1"), 1);
6578
6579                 {
6580                         std::vector<GLubyte> data(getWindowWidth() * getWindowHeight() * 4);
6581                         glBindTexture(GL_TEXTURE_2D, m_texture[0]);
6582                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6583                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
6584                                                  &data[0]);
6585
6586                         glBindTexture(GL_TEXTURE_2D, m_texture[1]);
6587                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6588                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
6589                                                  &data[0]);
6590
6591                         glBindTexture(GL_TEXTURE_2D, 0);
6592                 }
6593
6594                 glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
6595                 glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
6596
6597                 glClear(GL_COLOR_BUFFER_BIT);
6598                 glBindVertexArray(m_vao);
6599                 glDrawElementsInstancedBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0);
6600
6601                 std::vector<GLubyte> data(getWindowWidth() * getWindowHeight() * 4);
6602                 glBindTexture(GL_TEXTURE_2D, m_texture[0]);
6603                 glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
6604                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
6605
6606                 for (int h = 0; h < getWindowHeight(); ++h)
6607                 {
6608                         for (int w = 0; w < getWindowWidth(); ++w)
6609                         {
6610                                 const GLubyte c[4] = {
6611                                         data[h * (getWindowWidth() * 4) + w * 4 + 0], data[h * (getWindowWidth() * 4) + w * 4 + 1],
6612                                         data[h * (getWindowWidth() * 4) + w * 4 + 2], data[h * (getWindowWidth() * 4) + w * 4 + 3],
6613                                 };
6614                                 if (c[0] != 1 || c[1] != 0 || c[2] != 0 || c[3] != 0)
6615                                 {
6616                                         m_context.getTestContext().getLog()
6617                                                 << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6618                                                 << ") should be (1 0 0 0)" << tcu::TestLog::EndMessage;
6619                                         return ERROR;
6620                                 }
6621                         }
6622                 }
6623
6624                 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
6625                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
6626
6627                 for (int h = 0; h < getWindowHeight(); ++h)
6628                 {
6629                         for (int w = 0; w < getWindowWidth(); ++w)
6630                         {
6631                                 const GLubyte c[4] = {
6632                                         data[h * (getWindowWidth() * 4) + w * 4 + 0], data[h * (getWindowWidth() * 4) + w * 4 + 1],
6633                                         data[h * (getWindowWidth() * 4) + w * 4 + 2], data[h * (getWindowWidth() * 4) + w * 4 + 3],
6634                                 };
6635                                 if (c[0] != 3 || c[1] != 0 || c[2] != 0 || c[3] != 0)
6636                                 {
6637                                         m_context.getTestContext().getLog()
6638                                                 << tcu::TestLog::Message << "Color is (" << c[0] << " " << c[1] << c[2] << " " << c[3]
6639                                                 << ") should be (3 0 0 0)" << tcu::TestLog::EndMessage;
6640                                         return ERROR;
6641                                 }
6642                         }
6643                 }
6644
6645                 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
6646                 {
6647                         return ERROR;
6648                 }
6649                 return NO_ERROR;
6650         }
6651
6652         virtual long Cleanup()
6653         {
6654                 glUseProgram(0);
6655                 glDeleteBuffers(1, &m_vbo);
6656                 glDeleteBuffers(1, &m_ebo);
6657                 glDeleteTextures(2, m_texture);
6658                 glDeleteProgram(m_program);
6659                 glDeleteVertexArrays(1, &m_vao);
6660                 return NO_ERROR;
6661         }
6662 };
6663
6664 /** Test "imageLoad() and imageStore() for single-byte data alignment" description follows.
6665  *
6666  *  Steps:
6667  *  - create two textures: "source" and "destination". Fill "source"
6668  *  texture with unique values. Fill "destination" texture with zeros,
6669  *  - prepare a program object that will read texel from "source" image at given
6670  *  coordinates and write its value to "destination" image at same
6671  *  coordinates,
6672  *  - bind "source" and "destination" textures as "source" and "destination"
6673  *  image uniforms,
6674  *  - render "full screen" quad (left bottom corner at -1,-1 and right top
6675  *  corner at 1,1),
6676  *  - verify that texel values in "destination" texture match those in
6677  *  "source" texture (use glGetTexImage).
6678  *
6679  *  Test with 2D R8UI textures with following dimensions:
6680  *  - 16x16,
6681  *  - 16x17,
6682  *  - 17x16,
6683  *  - 17x17,
6684  *  - 16x18,
6685  *  - 18x16,
6686  *  - 18x18,
6687  *  - 19x16,
6688  *  - 16x19,
6689  *  - 19x19.
6690  *
6691  *  Note that default data alignment should cause problems with packing/
6692  *  /unpacking. Therefore GL_PACK_ALIGNMENT and GL_UNPACK_ALIGNMENT parameters
6693  *  of pixel storage mode have to be changed to one byte alignment.
6694  *
6695  *  Program should consist of vertex and fragment shader. Vertex shader should
6696  *  pass vertex position through. Fragment shader should do imageLoad() and
6697  *  imageStore() operations at coordinates gl_FragCoord.
6698  **/
6699 class ImageLoadStoreDataAlignmentTest : public ShaderImageLoadStoreBase
6700 {
6701 private:
6702         /* Structures */
6703         struct TextureDimensions
6704         {
6705                 GLuint m_width;
6706                 GLuint m_height;
6707
6708                 TextureDimensions(GLuint width, GLuint height) : m_width(width), m_height(height)
6709                 {
6710                 }
6711         };
6712
6713         /* Typedefs */
6714         typedef std::deque<TextureDimensions> TextureDimensionsList;
6715
6716         /* Fields */
6717         GLuint                            m_destination_texture_id;
6718         GLuint                            m_program_id;
6719         TextureDimensionsList m_texture_dimensions;
6720         GLuint                            m_source_texture_id;
6721         GLuint                            m_vertex_array_object_id;
6722         GLuint                            m_vertex_buffer_id;
6723
6724 public:
6725         /* Constructor */
6726         ImageLoadStoreDataAlignmentTest()
6727                 : m_destination_texture_id(0)
6728                 , m_program_id(0)
6729                 , m_source_texture_id(0)
6730                 , m_vertex_array_object_id(0)
6731                 , m_vertex_buffer_id(0)
6732         {
6733                 /* Nothing to be done here */
6734         }
6735
6736         /* Methods inherited from SubcaseBase */
6737         virtual long Setup()
6738         {
6739                 /* Shaders code */
6740                 const char* const vertex_shader_code = "#version 400 core\n"
6741                                                                                            "#extension GL_ARB_shader_image_load_store : require\n"
6742                                                                                            "\n"
6743                                                                                            "precision highp float;\n"
6744                                                                                            "\n"
6745                                                                                            "in vec4 vs_in_position;\n"
6746                                                                                            "\n"
6747                                                                                            "void main()\n"
6748                                                                                            "{\n"
6749                                                                                            "    gl_Position = vs_in_position;\n"
6750                                                                                            "}\n";
6751
6752                 const char* const fragment_shader_code =
6753                         "#version 400 core\n"
6754                         "#extension GL_ARB_shader_image_load_store : require\n"
6755                         "\n"
6756                         "precision highp float;\n"
6757                         "\n"
6758                         "layout(r8ui) writeonly uniform uimage2D u_destination_image;\n"
6759                         "layout(r8ui) readonly  uniform uimage2D u_source_image;\n"
6760                         "\n"
6761                         "void main()\n"
6762                         "{\n"
6763                         "    uvec4 loaded_color = imageLoad (u_source_image,      ivec2(gl_FragCoord));\n"
6764                         "                         imageStore(u_destination_image, ivec2(gl_FragCoord), loaded_color);\n"
6765                         "\n"
6766                         "    discard;\n"
6767                         "}\n";
6768
6769                 /* Vertex postions for "full screen" quad, made with triangle strip */
6770                 static const GLfloat m_vertex_buffer_data[] = {
6771                         -1.0f, -1.0f, 0.0f, 1.0f, /* left bottom */
6772                         -1.0f, 1.0f,  0.0f, 1.0f, /* left top */
6773                         1.0f,  -1.0f, 0.0f, 1.0f, /* right bottom */
6774                         1.0f,  1.0f,  0.0f, 1.0f, /* right top */
6775                 };
6776
6777                 /* Result of BuildProgram operation */
6778                 bool is_program_correct = true; /* BuildProgram set false when it fails, but it does not set true on success */
6779
6780                 /* Add all tested texture dimensions */
6781                 m_texture_dimensions.push_back(TextureDimensions(16, 16));
6782                 m_texture_dimensions.push_back(TextureDimensions(16, 17));
6783                 m_texture_dimensions.push_back(TextureDimensions(17, 16));
6784                 m_texture_dimensions.push_back(TextureDimensions(17, 17));
6785                 m_texture_dimensions.push_back(TextureDimensions(16, 18));
6786                 m_texture_dimensions.push_back(TextureDimensions(18, 16));
6787                 m_texture_dimensions.push_back(TextureDimensions(18, 18));
6788                 m_texture_dimensions.push_back(TextureDimensions(16, 19));
6789                 m_texture_dimensions.push_back(TextureDimensions(19, 16));
6790                 m_texture_dimensions.push_back(TextureDimensions(19, 19));
6791
6792                 /* Clean previous error */
6793                 glGetError();
6794
6795                 /* Set single-byte data alignment */
6796                 glPixelStorei(GL_PACK_ALIGNMENT, 1);
6797                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
6798                 GLU_EXPECT_NO_ERROR(glGetError(), "PixelStorei");
6799
6800                 /* Prepare buffer with vertex positions of "full screen" quad" */
6801                 glGenBuffers(1, &m_vertex_buffer_id);
6802                 GLU_EXPECT_NO_ERROR(glGetError(), "GenBuffers");
6803
6804                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
6805                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
6806
6807                 glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertex_buffer_data), m_vertex_buffer_data, GL_STATIC_DRAW);
6808                 GLU_EXPECT_NO_ERROR(glGetError(), "BufferData");
6809
6810                 /* Generate vertex array object */
6811                 glGenVertexArrays(1, &m_vertex_array_object_id);
6812                 GLU_EXPECT_NO_ERROR(glGetError(), "GenVertexArrays");
6813
6814                 /* Prepare program object */
6815                 m_program_id = BuildProgram(vertex_shader_code, 0 /* src_tcs */, 0 /* src_tes */, 0 /*src_gs */,
6816                                                                         fragment_shader_code, &is_program_correct);
6817                 if (false == is_program_correct)
6818                 {
6819                         return ERROR;
6820                 }
6821
6822                 /* Done */
6823                 return NO_ERROR;
6824         }
6825
6826         virtual long Cleanup()
6827         {
6828                 /* Reset OpenGL state */
6829                 glBindBuffer(GL_ARRAY_BUFFER, 0);
6830                 glBindTexture(GL_TEXTURE_2D, 0);
6831                 glBindVertexArray(0);
6832                 glUseProgram(0);
6833
6834                 /* Delete program */
6835                 if (0 != m_program_id)
6836                 {
6837                         glDeleteProgram(m_program_id);
6838                         m_program_id = 0;
6839                 }
6840
6841                 /* Delete textures */
6842                 if (0 != m_destination_texture_id)
6843                 {
6844                         glDeleteTextures(1, &m_destination_texture_id);
6845                         m_destination_texture_id = 0;
6846                 }
6847
6848                 if (0 != m_source_texture_id)
6849                 {
6850                         glDeleteTextures(1, &m_source_texture_id);
6851                         m_source_texture_id = 0;
6852                 }
6853
6854                 /* Delete vertex array object */
6855                 if (0 != m_vertex_array_object_id)
6856                 {
6857                         glDeleteVertexArrays(1, &m_vertex_array_object_id);
6858                         m_vertex_array_object_id = 0;
6859                 }
6860
6861                 /* Delete buffer */
6862                 if (0 != m_vertex_buffer_id)
6863                 {
6864                         glDeleteBuffers(1, &m_vertex_buffer_id);
6865                         m_vertex_buffer_id = 0;
6866                 }
6867
6868                 /* Done */
6869                 return NO_ERROR;
6870         }
6871
6872         virtual long Run()
6873         {
6874                 bool result = true;
6875
6876                 /* For each dimension */
6877                 for (TextureDimensionsList::const_iterator it = m_texture_dimensions.begin(); m_texture_dimensions.end() != it;
6878                          ++it)
6879                 {
6880                         /* Prepare "source" and "destination" textures */
6881                         GLU_EXPECT_NO_ERROR(Create2DR8UIDestinationTexture(it->m_width, it->m_height, m_destination_texture_id),
6882                                                                 "Create2DR8UIDestinationTexture");
6883                         GLU_EXPECT_NO_ERROR(Create2DR8UISourceTexture(it->m_width, it->m_height, m_source_texture_id),
6884                                                                 "Create2DR8UISourceTexture");
6885
6886                         /* Copy texture data with imageLoad() and imageStore() operations */
6887                         Copy2DR8UITexture(m_destination_texture_id, m_source_texture_id);
6888
6889                         /* Compare "source" and "destination" textures */
6890                         if (false ==
6891                                 Compare2DR8UITextures(m_destination_texture_id, m_source_texture_id, it->m_width, it->m_height))
6892                         {
6893                                 m_context.getTestContext().getLog()
6894                                         << tcu::TestLog::Message
6895                                         << "Copy with imageLoad and imageStore failed for textures: " << it->m_width << "x" << it->m_height
6896                                         << ". Source and destination textures are different" << tcu::TestLog::EndMessage;
6897
6898                                 result = false;
6899                         }
6900
6901                         /* Destroy "source" and "destination" textures */
6902                         glDeleteTextures(1, &m_destination_texture_id);
6903                         glDeleteTextures(1, &m_source_texture_id);
6904
6905                         m_destination_texture_id = 0;
6906                         m_source_texture_id              = 0;
6907                 }
6908
6909                 if (false == result)
6910                 {
6911                         return ERROR;
6912                 }
6913
6914                 /* Done */
6915                 return NO_ERROR;
6916         }
6917
6918 private:
6919         /* Private methods */
6920
6921         /** Binds a texture to user-specified image unit and updates relevant sampler uniform
6922          *
6923          * @param program_id   Program object id
6924          * @param texture_id   Texture id
6925          * @param image_unit   Index of image unit
6926          * @param uniform_name Name of image uniform
6927          **/
6928         void BindTextureToImage(GLuint program_id, GLuint texture_id, GLuint image_unit, const char* uniform_name)
6929         {
6930                 /* Uniform location and invalid value */
6931                 static const GLint invalid_uniform_location = -1;
6932                 GLint                      image_uniform_location   = 0;
6933
6934                 /* Get uniform location */
6935                 image_uniform_location = glGetUniformLocation(program_id, uniform_name);
6936                 GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
6937                 if (invalid_uniform_location == image_uniform_location)
6938                 {
6939                         throw tcu::InternalError("A required uniform is considered inactive", uniform_name, __FILE__, __LINE__);
6940                 }
6941
6942                 /* Bind texture to image unit */
6943                 glBindImageTexture(image_unit, texture_id, 0 /* level */, GL_FALSE, 0 /* layer */, GL_READ_WRITE, GL_R8UI);
6944                 GLU_EXPECT_NO_ERROR(glGetError(), "BindImageTexture");
6945
6946                 /* Set uniform to image unit */
6947                 glUniform1i(image_uniform_location, image_unit);
6948                 GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
6949         }
6950
6951         /** Compare two 2D R8UI textures
6952          *
6953          * @param left_texture_id  Id of "left" texture object
6954          * @param right_texture_id Id of "right" texture object
6955          * @param width            Width of the textures
6956          * @param height           Height of the textures
6957          *
6958          * @return true when texture data is identical, false otherwise
6959          **/
6960         bool Compare2DR8UITextures(GLuint left_texture_id, GLuint right_texture_id, GLuint width, GLuint height)
6961         {
6962                 /* Size of textures */
6963                 const GLuint texture_data_size = width * height;
6964
6965                 /* Storage for texture data */
6966                 std::vector<GLubyte> left_texture_data;
6967                 std::vector<GLubyte> right_texture_data;
6968
6969                 /* Alocate memory for texture data */
6970                 left_texture_data.resize(texture_data_size);
6971                 right_texture_data.resize(texture_data_size);
6972
6973                 /* Get "left" texture data */
6974                 glBindTexture(GL_TEXTURE_2D, left_texture_id);
6975                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
6976
6977                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, &left_texture_data[0]);
6978                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
6979
6980                 /* Get "right" texture data */
6981                 glBindTexture(GL_TEXTURE_2D, right_texture_id);
6982                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
6983
6984                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, &right_texture_data[0]);
6985                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
6986
6987                 /* Compare texels */
6988                 return (0 == memcmp(&left_texture_data[0], &right_texture_data[0], texture_data_size));
6989         }
6990
6991         /** Copy contents of "source" texture to "destination" texture with imageLoad() and imageStore() operations
6992          *
6993          * @param destination_texture_id Id of "destination" texture object
6994          * @param source_texture_id      Id of "source" texture object
6995          **/
6996         void Copy2DR8UITexture(GLuint destination_texture_id, GLuint source_texture_id)
6997         {
6998                 /* Uniform names */
6999                 static const char* const destination_image_uniform_name = "u_destination_image";
7000                 static const char* const source_image_uniform_name              = "u_source_image";
7001
7002                 /* Attribute name */
7003                 static const char* const position_attribute_name = "vs_in_position";
7004
7005                 /* Attribute location and invalid value */
7006                 static const GLint invalid_attribute_location  = -1;
7007                 GLint                      position_attribute_location = 0;
7008
7009                 /* Set current program */
7010                 glUseProgram(m_program_id);
7011                 GLU_EXPECT_NO_ERROR(glGetError(), "UseProgram");
7012
7013                 /* Bind vertex array object */
7014                 glBindVertexArray(m_vertex_array_object_id);
7015                 GLU_EXPECT_NO_ERROR(glGetError(), "BindVertexArray");
7016
7017                 /* Bind buffer with quad vertex positions */
7018                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
7019                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
7020
7021                 /* Set up position attribute */
7022                 position_attribute_location = glGetAttribLocation(m_program_id, position_attribute_name);
7023                 GLU_EXPECT_NO_ERROR(glGetError(), "GetAttribLocation");
7024                 if (invalid_attribute_location == position_attribute_location)
7025                 {
7026                         throw tcu::InternalError("Attribute location is not available", position_attribute_name, __FILE__,
7027                                                                          __LINE__);
7028                 }
7029
7030                 glVertexAttribPointer(position_attribute_location, 4 /*size */, GL_FLOAT, GL_FALSE /* normalized */,
7031                                                           0 /* stride */, 0);
7032                 GLU_EXPECT_NO_ERROR(glGetError(), "VertexAttribPointer");
7033
7034                 glEnableVertexAttribArray(position_attribute_location);
7035                 GLU_EXPECT_NO_ERROR(glGetError(), "EnableVertexAttribArray");
7036
7037                 /* Set up textures as source and destination images */
7038                 BindTextureToImage(m_program_id, destination_texture_id, 0 /* image_unit */, destination_image_uniform_name);
7039                 BindTextureToImage(m_program_id, source_texture_id, 1 /* image_unit */, source_image_uniform_name);
7040
7041                 /* Execute draw */
7042                 glDrawArrays(GL_TRIANGLE_STRIP, 0 /* first vertex */, 4 /* number of vertices */);
7043                 GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
7044         }
7045
7046         /** Create 2D R8UI texture and fills it with zeros
7047          *
7048          * @param width          Width of created texture
7049          * @param height         Height of created texture
7050          * @param out_texture_id Id of created texture, not modified if operation fails
7051          *
7052          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7053          **/
7054         GLenum Create2DR8UIDestinationTexture(GLuint width, GLuint height, GLuint& out_texture_id)
7055         {
7056                 /* Texture size */
7057                 const GLuint texture_size = width * height;
7058
7059                 /* Prepare storage for texture data */
7060                 std::vector<GLubyte> texture_data;
7061                 texture_data.resize(texture_size);
7062
7063                 /* Set all texels */
7064                 for (GLuint i = 0; i < texture_size; ++i)
7065                 {
7066                         texture_data[i] = 0;
7067                 }
7068
7069                 /* Create texture */
7070                 return Create2DR8UITexture(width, height, texture_data, out_texture_id);
7071         }
7072
7073         /** Create 2D R8UI texture and fills it with increasing values, starting from 0
7074          *
7075          * @param width          Width of created texture
7076          * @param height         Height of created texture
7077          * @param out_texture_id Id of created texture, not modified if operation fails
7078          *
7079          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7080          **/
7081         GLenum Create2DR8UISourceTexture(GLuint width, GLuint height, GLuint& out_texture_id)
7082         {
7083                 /* Texture size */
7084                 const GLuint texture_size = width * height;
7085
7086                 /* Value of texel */
7087                 GLubyte texel_value = 0;
7088
7089                 /* Prepare storage for texture data */
7090                 std::vector<GLubyte> texture_data;
7091                 texture_data.resize(texture_size);
7092
7093                 /* Set all texels */
7094                 for (GLuint i = 0; i < texture_size; ++i)
7095                 {
7096                         texture_data[i] = texel_value++;
7097                 }
7098
7099                 /* Create texture */
7100                 return Create2DR8UITexture(width, height, texture_data, out_texture_id);
7101         }
7102
7103         /** Create 2D R8UI texture and fills it with user-provided data
7104          *
7105          * @param width          Width of created texture
7106          * @param height         Height of created texture
7107          * @param texture_data   Texture data
7108          * @param out_texture_id Id of created texture, not modified if operation fails
7109          *
7110          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7111          **/
7112         GLenum Create2DR8UITexture(GLuint width, GLuint height, const std::vector<GLubyte>& texture_data,
7113                                                            GLuint& out_texture_id)
7114         {
7115                 GLenum err                = 0;
7116                 GLuint texture_id = 0;
7117
7118                 /* Generate texture */
7119                 glGenTextures(1, &texture_id);
7120                 err = glGetError();
7121                 if (GL_NO_ERROR != err)
7122                 {
7123                         return err;
7124                 }
7125
7126                 /* Bind texture */
7127                 glBindTexture(GL_TEXTURE_2D, texture_id);
7128                 err = glGetError();
7129                 if (GL_NO_ERROR != err)
7130                 {
7131                         glDeleteTextures(1, &texture_id);
7132                         return err;
7133                 }
7134
7135                 /* Allocate storage and fill texture */
7136                 glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R8UI, width, height, 0 /* border */, GL_RED_INTEGER,
7137                                          GL_UNSIGNED_BYTE, &texture_data[0]);
7138                 err = glGetError();
7139                 if (GL_NO_ERROR != err)
7140                 {
7141                         glDeleteTextures(1, &texture_id);
7142                         return err;
7143                 }
7144
7145                 /* Make texture complete */
7146                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7147                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
7148                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7149                 err = glGetError();
7150                 if (GL_NO_ERROR != err)
7151                 {
7152                         glDeleteTextures(1, &texture_id);
7153                         return err;
7154                 }
7155
7156                 /* Set out_texture_id */
7157                 out_texture_id = texture_id;
7158
7159                 /* Done */
7160                 return GL_NO_ERROR;
7161         }
7162 };
7163
7164 /** Test "imageLoad() and imageStore() for non-layered image bindings" description follows.
7165  *
7166  *  Steps: same as in test 1 (ImageLoadStoreDataAlignmentTest).
7167  *
7168  *  Test non-layered image bindings (BindImageTexture <layered>: false) with:
7169  *  | Type           | Dimensions |
7170  *  | 2D_ARRAY       | 64x64x6    |
7171  *  | 3D             | 64x64x6    |
7172  *  | CUBE_MAP       | 64         |
7173  *  | CUBE_MAP_ARRAY | 64x3       |
7174  *
7175  *  Use RGBA8 format. All layers shall be tested.
7176  *
7177  *  Program should consist of vertex and fragment shader. Vertex shader should
7178  *  pass vertex position through. Fragment shader should do imageLoad() and
7179  *  imageStore() operations at coordinates gl_FragCoord. Fragment shader should
7180  *  use image2D as image type.
7181  **/
7182 class ImageLoadStoreNonLayeredBindingTest : public ShaderImageLoadStoreBase
7183 {
7184 private:
7185         /* Structures */
7186         struct TextureShapeDefinition
7187         {
7188                 GLuint m_edge;
7189                 GLuint m_n_elements;
7190                 GLenum m_type;
7191
7192                 TextureShapeDefinition(GLuint edge, GLuint n_elements, GLenum type)
7193                         : m_edge(edge), m_n_elements(n_elements), m_type(type)
7194                 {
7195                 }
7196         };
7197
7198         /* Typedefs */
7199         typedef std::deque<TextureShapeDefinition> TextureShapeDefinitionList;
7200
7201         /* Fields */
7202         GLuint                                     m_destination_texture_id;
7203         GLuint                                     m_program_id;
7204         TextureShapeDefinitionList m_texture_shape_definitions;
7205         GLuint                                     m_source_texture_id;
7206         GLuint                                     m_vertex_array_object_id;
7207         GLuint                                     m_vertex_buffer_id;
7208
7209 public:
7210         /* Constructor */
7211         ImageLoadStoreNonLayeredBindingTest()
7212                 : m_destination_texture_id(0)
7213                 , m_program_id(0)
7214                 , m_source_texture_id(0)
7215                 , m_vertex_array_object_id(0)
7216                 , m_vertex_buffer_id(0)
7217         {
7218                 /* Nothing to be done here */
7219         }
7220
7221         /* Methods inherited from SubcaseBase */
7222         virtual long Setup()
7223         {
7224                 /* Shaders code */
7225                 const char* const vertex_shader_code = "#version 400 core\n"
7226                                                                                            "#extension GL_ARB_shader_image_load_store : require\n"
7227                                                                                            "\n"
7228                                                                                            "precision highp float;\n"
7229                                                                                            "\n"
7230                                                                                            "in vec4 vs_in_position;\n"
7231                                                                                            "\n"
7232                                                                                            "void main()\n"
7233                                                                                            "{\n"
7234                                                                                            "    gl_Position = vs_in_position;\n"
7235                                                                                            "}\n";
7236
7237                 const char* const fragment_shader_code =
7238                         "#version 400 core\n"
7239                         "#extension GL_ARB_shader_image_load_store : require\n"
7240                         "\n"
7241                         "precision highp float;\n"
7242                         "\n"
7243                         "layout(rgba8) writeonly uniform image2D u_destination_image;\n"
7244                         "layout(rgba8) readonly  uniform image2D u_source_image;\n"
7245                         "\n"
7246                         "void main()\n"
7247                         "{\n"
7248                         "    vec4 loaded_color = imageLoad (u_source_image,      ivec2(gl_FragCoord));\n"
7249                         "                        imageStore(u_destination_image, ivec2(gl_FragCoord), loaded_color);\n"
7250                         "\n"
7251                         "    discard;\n"
7252                         "}\n";
7253
7254                 /* Vertex postions for "full screen" quad, defined as a triangle strip */
7255                 static const GLfloat m_vertex_buffer_data[] = {
7256                         -1.0f, -1.0f, 0.0f, 1.0f, /* left bottom */
7257                         -1.0f, 1.0f,  0.0f, 1.0f, /* left top */
7258                         1.0f,  -1.0f, 0.0f, 1.0f, /* right bottom */
7259                         1.0f,  1.0f,  0.0f, 1.0f, /* right top */
7260                 };
7261
7262                 /* Result of BuildProgram operation */
7263                 bool is_program_correct = true; /* BuildProgram set false when it fails, but it does not set true on success */
7264
7265                 /* Add all tested texture shapes */
7266                 int texture_edge = de::min(64, de::min(getWindowHeight(), getWindowWidth()));
7267                 m_texture_shape_definitions.push_back(
7268                         TextureShapeDefinition(texture_edge /* edge */, 6 /* n_elements */, GL_TEXTURE_2D_ARRAY));
7269                 m_texture_shape_definitions.push_back(
7270                         TextureShapeDefinition(texture_edge /* edge */, 6 /* n_elements */, GL_TEXTURE_3D));
7271                 m_texture_shape_definitions.push_back(
7272                         TextureShapeDefinition(texture_edge /* edge */, 1 /* n_elements */, GL_TEXTURE_CUBE_MAP));
7273                 m_texture_shape_definitions.push_back(
7274                         TextureShapeDefinition(texture_edge /* edge */, 3 /* n_elements */, GL_TEXTURE_CUBE_MAP_ARRAY));
7275
7276                 /* Prepare buffer with vertex positions of "full screen" quad" */
7277                 glGenBuffers(1, &m_vertex_buffer_id);
7278                 GLU_EXPECT_NO_ERROR(glGetError(), "GenBuffers");
7279
7280                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
7281                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
7282
7283                 glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertex_buffer_data), m_vertex_buffer_data, GL_STATIC_DRAW);
7284                 GLU_EXPECT_NO_ERROR(glGetError(), "BufferData");
7285
7286                 /* Generate vertex array object */
7287                 glGenVertexArrays(1, &m_vertex_array_object_id);
7288                 GLU_EXPECT_NO_ERROR(glGetError(), "GenVertexArrays");
7289
7290                 /* Prepare program object */
7291                 m_program_id = BuildProgram(vertex_shader_code, 0 /* src_tcs */, 0 /* src_tes */, 0 /* src_gs */,
7292                                                                         fragment_shader_code, &is_program_correct);
7293                 if (false == is_program_correct)
7294                 {
7295                         return ERROR;
7296                 }
7297
7298                 /* Done */
7299                 return NO_ERROR;
7300         }
7301
7302         virtual long Cleanup()
7303         {
7304                 /* Reset OpenGL state */
7305                 glBindBuffer(GL_ARRAY_BUFFER, 0);
7306                 glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
7307                 glBindTexture(GL_TEXTURE_3D, 0);
7308                 glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
7309                 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
7310                 glBindVertexArray(0);
7311                 glUseProgram(0);
7312
7313                 /* Delete program */
7314                 if (0 != m_program_id)
7315                 {
7316                         glDeleteProgram(m_program_id);
7317                         m_program_id = 0;
7318                 }
7319
7320                 /* Delete textures */
7321                 if (0 != m_destination_texture_id)
7322                 {
7323                         glDeleteTextures(1, &m_destination_texture_id);
7324                         m_destination_texture_id = 0;
7325                 }
7326
7327                 if (0 != m_source_texture_id)
7328                 {
7329                         glDeleteTextures(1, &m_source_texture_id);
7330                         m_source_texture_id = 0;
7331                 }
7332
7333                 /* Delete vertex array object */
7334                 if (0 != m_vertex_array_object_id)
7335                 {
7336                         glDeleteVertexArrays(1, &m_vertex_array_object_id);
7337                         m_vertex_array_object_id = 0;
7338                 }
7339
7340                 /* Delete buffer */
7341                 if (0 != m_vertex_buffer_id)
7342                 {
7343                         glDeleteBuffers(1, &m_vertex_buffer_id);
7344                         m_vertex_buffer_id = 0;
7345                 }
7346
7347                 /* Done */
7348                 return NO_ERROR;
7349         }
7350
7351         virtual long Run()
7352         {
7353                 bool result = true;
7354
7355                 /* For each shape */
7356                 for (TextureShapeDefinitionList::const_iterator it = m_texture_shape_definitions.begin();
7357                          m_texture_shape_definitions.end() != it; ++it)
7358                 {
7359                         const GLuint n_layers = GetTotalNumberOfLayers(it->m_n_elements, it->m_type);
7360
7361                         /* Prepare "source" and "destination" textures */
7362                         GLU_EXPECT_NO_ERROR(
7363                                 CreateRGBA8DestinationTexture(it->m_edge, it->m_n_elements, it->m_type, m_destination_texture_id),
7364                                 "Create2DR8UIDestinationTexture");
7365                         GLU_EXPECT_NO_ERROR(CreateRGBA8SourceTexture(it->m_edge, it->m_n_elements, it->m_type, m_source_texture_id),
7366                                                                 "Create2DR8UISourceTexture");
7367
7368                         /* Copy texture data with imageLoad() and imageStore() operations */
7369                         CopyRGBA8Texture(m_destination_texture_id, m_source_texture_id, n_layers);
7370
7371                         /* Compare "source" and "destination" textures */
7372                         if (false ==
7373                                 CompareRGBA8Textures(m_destination_texture_id, m_source_texture_id, it->m_edge, n_layers, it->m_type))
7374                         {
7375                                 const char* texture_type = "";
7376                                 switch (it->m_type)
7377                                 {
7378                                 case GL_TEXTURE_2D_ARRAY:
7379                                         texture_type = "2d array";
7380                                         break;
7381                                 case GL_TEXTURE_3D:
7382                                         texture_type = "3d";
7383                                         break;
7384                                 case GL_TEXTURE_CUBE_MAP:
7385                                         texture_type = "Cube map";
7386                                         break;
7387                                 case GL_TEXTURE_CUBE_MAP_ARRAY:
7388                                         texture_type = "Cube map array";
7389                                         break;
7390                                 }
7391
7392                                 m_context.getTestContext().getLog()
7393                                         << tcu::TestLog::Message
7394                                         << "Copy  with imageLoad and imageStore failed for texture type: " << texture_type
7395                                         << ". Source and destination textures are different" << tcu::TestLog::EndMessage;
7396
7397                                 result = false;
7398                         }
7399
7400                         /* Destroy "source" and "destination" textures */
7401                         glDeleteTextures(1, &m_destination_texture_id);
7402                         glDeleteTextures(1, &m_source_texture_id);
7403
7404                         m_destination_texture_id = 0;
7405                         m_source_texture_id              = 0;
7406                 }
7407
7408                 if (false == result)
7409                 {
7410                         return ERROR;
7411                 }
7412
7413                 /* Done */
7414                 return NO_ERROR;
7415         }
7416
7417 private:
7418         /* Private methods */
7419
7420         /** Binds a texture to user-specified image unit and update relevant sampler uniform
7421          *
7422          * @param program_id   Program object id
7423          * @param texture_id   Texture id
7424          * @param image_unit   Index of image unit
7425          * @param layer        Index of layer bound to unit
7426          * @param uniform_name Name of image uniform
7427          **/
7428         void BindTextureToImage(GLuint program_id, GLuint texture_id, GLuint image_unit, GLuint layer,
7429                                                         const char* uniform_name)
7430         {
7431                 static const GLint invalid_uniform_location = -1;
7432                 GLint                      image_uniform_location   = 0;
7433
7434                 /* Get uniform location */
7435                 image_uniform_location = glGetUniformLocation(program_id, uniform_name);
7436                 GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
7437                 if (invalid_uniform_location == image_uniform_location)
7438                 {
7439                         throw tcu::InternalError("Uniform location is not available", uniform_name, __FILE__, __LINE__);
7440                 }
7441
7442                 /* Bind texture to image unit */
7443                 glBindImageTexture(image_unit, texture_id, 0 /* level */, GL_FALSE /* layered */, layer, GL_READ_WRITE,
7444                                                    GL_RGBA8);
7445                 GLU_EXPECT_NO_ERROR(glGetError(), "BindImageTexture");
7446
7447                 /* Set uniform to image unit */
7448                 glUniform1i(image_uniform_location, image_unit);
7449                 GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
7450         }
7451
7452         /** Compare two 2D R8UI textures
7453          *
7454          * @param left_texture_id  Id of "left" texture object
7455          * @param right_texture_id Id of "right" texture object
7456          * @param edge             Length of texture edge
7457          * @param n_layers         Number of layers to compare
7458          * @param type             Type of texture
7459          *
7460          * @return true when texture data is found identical, false otherwise
7461          **/
7462         bool CompareRGBA8Textures(GLuint left_texture_id, GLuint right_texture_id, GLuint edge, GLuint n_layers,
7463                                                           GLenum type)
7464         {
7465                 static const GLuint n_components          = 4; /* RGBA */
7466                 const GLuint            texture_data_size = edge * edge * n_layers * n_components;
7467
7468                 /* Storage for texture data */
7469                 std::vector<GLubyte> left_texture_data;
7470                 std::vector<GLubyte> right_texture_data;
7471
7472                 ExtractTextureData(left_texture_id, edge, n_layers, type, left_texture_data);
7473                 ExtractTextureData(right_texture_id, edge, n_layers, type, right_texture_data);
7474
7475                 /* Compare texels */
7476                 return (0 == memcmp(&left_texture_data[0], &right_texture_data[0], texture_data_size));
7477         }
7478
7479         /** Copy contents of "source" texture to "destination" texture with imageLoad() and imageStore() operations
7480          *
7481          * @param destination_texture_id Id of "destination" texture object
7482          * @param source_texture_id      Id of "source" texture object
7483          * @param n_layers               Number of layers
7484          **/
7485         void CopyRGBA8Texture(GLuint destination_texture_id, GLuint source_texture_id, GLuint n_layers)
7486         {
7487                 for (GLuint layer = 0; layer < n_layers; ++layer)
7488                 {
7489                         CopyRGBA8TextureLayer(destination_texture_id, source_texture_id, layer);
7490                 }
7491         }
7492
7493         /** Copy contents of layer from "source" texture to "destination" texture with imageLoad() and imageStore() operations
7494          *
7495          * @param destination_texture_id Id of "destination" texture object
7496          * @param source_texture_id      Id of "source" texture object
7497          * @param layer                  Index of layer
7498          **/
7499         void CopyRGBA8TextureLayer(GLuint destination_texture_id, GLuint source_texture_id, GLuint layer)
7500         {
7501                 /* Uniform names */
7502                 static const char* const destination_image_uniform_name = "u_destination_image";
7503                 static const char* const source_image_uniform_name              = "u_source_image";
7504
7505                 /* Attribute name */
7506                 static const char* const position_attribute_name = "vs_in_position";
7507
7508                 /* Attribute location and invalid value */
7509                 static const GLint invalid_attribute_location  = -1;
7510                 GLint                      position_attribute_location = 0;
7511
7512                 /* Set current program */
7513                 glUseProgram(m_program_id);
7514                 GLU_EXPECT_NO_ERROR(glGetError(), "UseProgram");
7515
7516                 /* Bind vertex array object */
7517                 glBindVertexArray(m_vertex_array_object_id);
7518                 GLU_EXPECT_NO_ERROR(glGetError(), "BindVertexArray");
7519
7520                 /* Bind buffer with quad vertex positions */
7521                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
7522                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
7523
7524                 /* Set up vertex attribute array for position attribute */
7525                 position_attribute_location = glGetAttribLocation(m_program_id, position_attribute_name);
7526                 GLU_EXPECT_NO_ERROR(glGetError(), "GetAttribLocation");
7527                 if (invalid_attribute_location == position_attribute_location)
7528                 {
7529                         throw tcu::InternalError("Attribute location is not available", position_attribute_name, __FILE__,
7530                                                                          __LINE__);
7531                 }
7532
7533                 glVertexAttribPointer(position_attribute_location, 4 /*size */, GL_FLOAT, GL_FALSE /* normalized */,
7534                                                           0 /* stride */, 0 /* pointer */);
7535                 GLU_EXPECT_NO_ERROR(glGetError(), "VertexAttribPointer");
7536
7537                 glEnableVertexAttribArray(position_attribute_location);
7538                 GLU_EXPECT_NO_ERROR(glGetError(), "EnableVertexAttribArray");
7539
7540                 /* Set up textures as source and destination image samplers */
7541                 BindTextureToImage(m_program_id, destination_texture_id, 0 /* image_unit */, layer,
7542                                                    destination_image_uniform_name);
7543                 BindTextureToImage(m_program_id, source_texture_id, 1 /* image_unit */, layer, source_image_uniform_name);
7544
7545                 /* Execute draw */
7546                 glDrawArrays(GL_TRIANGLE_STRIP, 0 /* first vertex */, 4 /* number of vertices */);
7547                 GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
7548         }
7549
7550         /** Creates RGBA8 texture of given type and fills it with zeros
7551          *
7552          * @param edge           Edge of created texture
7553          * @param n_elements     Number of elements in texture array
7554          * @param target         Target of created texture
7555          * @param out_texture_id Id of created texture, not modified if operation fails
7556          *
7557          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7558          **/
7559         GLenum CreateRGBA8DestinationTexture(GLuint edge, GLuint n_elements, GLenum target, GLuint& out_texture_id)
7560         {
7561                 /* Constasts to calculate texture size */
7562                 static const GLuint n_components = 4; /* RGBA */
7563                 const GLuint            layer_size   = edge * edge * n_components;
7564                 const GLuint            n_layers         = GetTotalNumberOfLayers(n_elements, target);
7565                 const GLuint            texture_size = layer_size * n_layers;
7566
7567                 /* Prepare storage for texture data */
7568                 std::vector<GLubyte> texture_data;
7569                 texture_data.resize(texture_size);
7570
7571                 /* Set all texels */
7572                 for (GLuint i = 0; i < texture_size; ++i)
7573                 {
7574                         texture_data[i] = 0;
7575                 }
7576
7577                 /* Create texture */
7578                 return CreateRGBA8Texture(edge, target, n_layers, texture_data, out_texture_id);
7579         }
7580
7581         /** Creates RGBA8 texture and fills it with [x, y, layer, 0xaa]
7582          *
7583          * @param edge           Edge of created texture
7584          * @param n_elements     Number of elements in texture array
7585          * @param target         Target of created texture
7586          * @param out_texture_id Id of created texture, not modified if operation fails
7587          *
7588          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7589          **/
7590         GLenum CreateRGBA8SourceTexture(GLuint edge, GLuint n_elements, GLenum target, GLuint& out_texture_id)
7591         {
7592                 /* Constants to calculate texture size */
7593                 static const GLuint n_components = 4; /* RGBA */
7594                 const GLuint            layer_size   = edge * edge * n_components;
7595                 const GLuint            n_layers         = GetTotalNumberOfLayers(n_elements, target);
7596                 const GLuint            texture_size = layer_size * n_layers;
7597
7598                 /* Value of texel */
7599                 GLubyte texel[4] = { 0, 0, 0, 0xaa };
7600
7601                 /* Prepare storage for texture data */
7602                 std::vector<GLubyte> texture_data;
7603                 texture_data.resize(texture_size);
7604
7605                 /* Set all texels */
7606                 for (GLuint layer = 0; layer < n_layers; ++layer)
7607                 {
7608                         const GLuint layer_offset = layer_size * layer;
7609
7610                         texel[2] = static_cast<GLubyte>(layer);
7611
7612                         for (GLuint y = 0; y < edge; ++y)
7613                         {
7614                                 const GLuint line_offset = y * edge * n_components + layer_offset;
7615
7616                                 texel[1] = static_cast<GLubyte>(y);
7617
7618                                 for (GLuint x = 0; x < edge; ++x)
7619                                 {
7620                                         const GLuint texel_offset = x * n_components + line_offset;
7621                                         texel[0]                                  = static_cast<GLubyte>(x);
7622
7623                                         for (GLuint component = 0; component < n_components; ++component)
7624                                         {
7625                                                 texture_data[texel_offset + component] = texel[component];
7626                                         }
7627                                 }
7628                         }
7629                 }
7630
7631                 /* Create texture */
7632                 return CreateRGBA8Texture(edge, target, n_layers, texture_data, out_texture_id);
7633         }
7634
7635         /** Creates RGBA8 texture of given type and fills it provided data
7636          *
7637          * @param edge           Edge of created texture
7638          * @param n_elements     Number of elements in texture array
7639          * @param target         Target of created texture
7640          * @param texture_data   Texture data
7641          * @param out_texture_id Id of created texture, not modified if operation fails
7642          *
7643          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
7644          **/
7645         GLenum CreateRGBA8Texture(GLuint edge, GLenum target, GLuint n_layers, const std::vector<GLubyte>& texture_data,
7646                                                           GLuint& out_texture_id)
7647         {
7648                 GLenum err                = 0;
7649                 GLuint texture_id = 0;
7650
7651                 /* Generate texture */
7652                 glGenTextures(1, &texture_id);
7653                 err = glGetError();
7654                 if (GL_NO_ERROR != err)
7655                 {
7656                         return err;
7657                 }
7658
7659                 /* Bind texture */
7660                 glBindTexture(target, texture_id);
7661                 err = glGetError();
7662                 if (GL_NO_ERROR != err)
7663                 {
7664                         glDeleteTextures(1, &texture_id);
7665                         return err;
7666                 }
7667
7668                 /* Allocate storage and fill texture */
7669                 if (GL_TEXTURE_CUBE_MAP != target)
7670                 {
7671                         glTexImage3D(target, 0 /* level */, GL_RGBA8, edge, edge, n_layers, 0 /* border */, GL_RGBA,
7672                                                  GL_UNSIGNED_BYTE, &texture_data[0]);
7673                 }
7674                 else
7675                 {
7676                         const GLuint n_components = 4;
7677                         const GLuint layer_size   = edge * edge * n_components;
7678
7679                         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7680                                                  GL_UNSIGNED_BYTE, &texture_data[0 * layer_size]);
7681                         glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7682                                                  GL_UNSIGNED_BYTE, &texture_data[1 * layer_size]);
7683                         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7684                                                  GL_UNSIGNED_BYTE, &texture_data[2 * layer_size]);
7685                         glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7686                                                  GL_UNSIGNED_BYTE, &texture_data[3 * layer_size]);
7687                         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7688                                                  GL_UNSIGNED_BYTE, &texture_data[4 * layer_size]);
7689                         glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0 /* level */, GL_RGBA8, edge, edge, 0 /* border */, GL_RGBA,
7690                                                  GL_UNSIGNED_BYTE, &texture_data[5 * layer_size]);
7691                 }
7692                 err = glGetError();
7693                 if (GL_NO_ERROR != err)
7694                 {
7695                         glDeleteTextures(1, &texture_id);
7696                         return err;
7697                 }
7698
7699                 /* Make texture complete */
7700                 glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
7701                 glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 0);
7702                 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7703                 err = glGetError();
7704                 if (GL_NO_ERROR != err)
7705                 {
7706                         glDeleteTextures(1, &texture_id);
7707                         return err;
7708                 }
7709
7710                 /* Set out_texture_id */
7711                 out_texture_id = texture_id;
7712
7713                 /* Done */
7714                 return GL_NO_ERROR;
7715         }
7716
7717         /** Extracts texture data
7718          *
7719          * @param texture_id   Id of texture object
7720          * @param edge         Length of texture edge
7721          * @param n_layers     Number of layers
7722          * @param target       Target of texture
7723          * @param texture_data Extracted texture data
7724          **/
7725         void ExtractTextureData(GLuint texture_id, GLuint edge, GLuint n_layers, GLenum target,
7726                                                         std::vector<GLubyte>& texture_data)
7727         {
7728                 static const GLuint n_components          = 4; /* RGBA */
7729                 const GLuint            texture_data_size = edge * edge * n_layers * n_components;
7730
7731                 /* Alocate memory for texture data */
7732                 texture_data.resize(texture_data_size);
7733
7734                 /* Bind texture */
7735                 glBindTexture(target, texture_id);
7736                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
7737
7738                 /* Get data */
7739                 if (GL_TEXTURE_CUBE_MAP != target)
7740                 {
7741                         glGetTexImage(target, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
7742                 }
7743                 else
7744                 {
7745                         const GLuint layer_size = edge * edge * n_components;
7746
7747                         glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0 * layer_size]);
7748                         glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[1 * layer_size]);
7749                         glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[2 * layer_size]);
7750                         glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[3 * layer_size]);
7751                         glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[4 * layer_size]);
7752                         glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[5 * layer_size]);
7753                 }
7754
7755                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
7756         }
7757
7758         /** Get number of layers per single element for given type of texture
7759          *
7760          * @param target Target of texture
7761          *
7762          * @return Number of layers
7763          **/
7764         GLuint GetLayersPerElement(GLenum target)
7765         {
7766                 switch (target)
7767                 {
7768                 case GL_TEXTURE_2D_ARRAY:
7769                 case GL_TEXTURE_3D:
7770                         return 1;
7771                         break;
7772                 case GL_TEXTURE_CUBE_MAP:
7773                 case GL_TEXTURE_CUBE_MAP_ARRAY:
7774                         return 6;
7775                         break;
7776                 default:
7777                         throw tcu::InternalError("Not supported texture type", "", __FILE__, __LINE__);
7778                         break;
7779                 }
7780         }
7781
7782         /** Get total number of layers in texture of given type and number of array elements
7783          *
7784          * @param n_elements Number of elements in texture array
7785          * @param target     Target of texture
7786          *
7787          * @return Number of layers
7788          **/
7789         GLuint GetTotalNumberOfLayers(GLuint n_elements, GLenum target)
7790         {
7791                 return GetLayersPerElement(target) * n_elements;
7792         }
7793 };
7794
7795 /** Test "imageLoad() and imageStore() for incomplete textures" description follows.
7796  *
7797  *  Load from incomplete textures should return 0.
7798  *  Store to incomplete textures should be ignored.
7799  *
7800  *  Steps:
7801  *  - create two incomplete textures: "incomplete_source" and
7802  *  "incomplete_destination",
7803  *  - create two complete textures: "complete_source" and
7804  *  "complete_destination",
7805  *  - fill all textures with unique values,
7806  *  - prepare program that will:
7807  *      * load texel from "incomplete_source" and store its value to
7808  *      "complete_destination",
7809  *      * load texel from "complete_source" and store its value to
7810  *      "incomplete_destination".
7811  *  - bind textures to corresponding image uniforms
7812  *  - execute program for all texels,
7813  *  - verify that "incomplete_destination" was not modified and
7814  *  "complete_destination" is filled with zeros.
7815  *
7816  *  Texture is considered incomplete when it has enabled mipmaping (see below)
7817  *  and does not have all mipmap levels defined.  But for the case of Image
7818  *  accessing, it is considered invalid if it is mipmap-incomplete and the
7819  *  level is different to the base level (base-incomplete).
7820  *
7821  *  Creation of incomplete texture:
7822  *  - generate and bind texture object id,
7823  *  - call TexImage2D with <level>: 0,
7824  *  - set GL_TEXTURE_MIN_FILTER? parameter to GL_NEAREST_MIPMAP_LINEAR, (to make
7825  *  sure, it should be initial value),
7826  *  - set GL_TEXTURE_BASE_LEVEL parameter to 0.
7827  *  - set GL_TEXTURE_MAX_LEVEL parameter, for 64x64 set 7 (log2(min(width,
7828  *  height)).
7829  *
7830  *  Creation of complete texture:
7831  *  - generate and bind texture object id,
7832  *  - call TexImage2D with <level>: 0,
7833  *  - set GL_TEXTURE_BASE_LEVEL parameter to 0.
7834  *  - set GL_TEXTURE_MAX_LEVEL parameter to 0.
7835  *
7836  *  Binding:
7837  *  - Set level == base_level for complete destinations.
7838  *  - Set level != base_level for incomplete destinations that are using
7839  *    mipmap-incomplete textures.
7840  *
7841  *  Test with 2D 64x64 RGBA8 textures.
7842  *
7843  *  Program should consist of vertex and fragment shader. Vertex shader should
7844  *  pass vertex position through. Fragment shader should do imageLoad() and
7845  *  imageStore() operations at coordinates gl_FragCoord.
7846  **/
7847 class ImageLoadStoreIncompleteTexturesTest : public ShaderImageLoadStoreBase
7848 {
7849 private:
7850         /* Constants */
7851         /* Magic numbers that will identify textures, which will be used as their
7852          * texel value.
7853          */
7854         static const GLubyte m_complete_destination_magic_number   = 0x11;
7855         static const GLubyte m_complete_source_magic_number                = 0x22;
7856         static const GLubyte m_incomplete_destination_magic_number = 0x33;
7857         static const GLubyte m_incomplete_source_magic_number     = 0x44;
7858
7859         /* Texture edge */
7860         GLuint m_texture_edge;
7861
7862         /* Fields */
7863         GLuint m_complete_destination_texture_id;
7864         GLuint m_complete_source_texture_id;
7865         GLuint m_incomplete_destination_texture_id;
7866         GLuint m_incomplete_source_texture_id;
7867         GLuint m_program_id;
7868         GLuint m_vertex_array_object_id;
7869         GLuint m_vertex_buffer_id;
7870
7871 public:
7872         /* Constructor */
7873         ImageLoadStoreIncompleteTexturesTest()
7874                 : m_texture_edge(0)
7875                 , m_complete_destination_texture_id(0)
7876                 , m_complete_source_texture_id(0)
7877                 , m_incomplete_destination_texture_id(0)
7878                 , m_incomplete_source_texture_id(0)
7879                 , m_program_id(0)
7880                 , m_vertex_array_object_id(0)
7881                 , m_vertex_buffer_id(0)
7882         {
7883                 /* Nothing to be done here */
7884         }
7885
7886         /* Methods inherited from SubcaseBase */
7887         virtual long Setup()
7888         {
7889                 /* Shaders code */
7890                 const char* const vertex_shader_code = "#version 400 core\n"
7891                                                                                            "#extension GL_ARB_shader_image_load_store : require\n"
7892                                                                                            "\n"
7893                                                                                            "precision highp float;\n"
7894                                                                                            "\n"
7895                                                                                            "in vec4 vs_in_position;\n"
7896                                                                                            "\n"
7897                                                                                            "void main()\n"
7898                                                                                            "{\n"
7899                                                                                            "    gl_Position = vs_in_position;\n"
7900                                                                                            "}\n";
7901
7902                 const char* const fragment_shader_code =
7903                         "#version 400 core\n"
7904                         "#extension GL_ARB_shader_image_load_store : require\n"
7905                         "\n"
7906                         "precision highp float;\n"
7907                         "\n"
7908                         "layout(rgba8) writeonly uniform image2D u_complete_destination_image;\n"
7909                         "layout(rgba8) readonly  uniform image2D u_complete_source_image;\n"
7910                         "layout(rgba8) writeonly uniform image2D u_incomplete_destination_image;\n"
7911                         "layout(rgba8) readonly  uniform image2D u_incomplete_source_image;\n"
7912                         "\n"
7913                         "void main()\n"
7914                         "{\n"
7915                         "    vec4 complete_loaded_color   = imageLoad (u_complete_source_image,   ivec2(gl_FragCoord));\n"
7916                         "    vec4 incomplete_loaded_color = imageLoad (u_incomplete_source_image, ivec2(gl_FragCoord));\n"
7917
7918                         "    imageStore(u_complete_destination_image,\n"
7919                         "               ivec2(gl_FragCoord),\n"
7920                         "               incomplete_loaded_color);\n"
7921                         "    imageStore(u_incomplete_destination_image,\n"
7922                         "               ivec2(gl_FragCoord),\n"
7923                         "               complete_loaded_color);\n"
7924                         "\n"
7925                         "    discard;\n"
7926                         "}\n";
7927
7928                 /* Vertex postions for "full screen" quad, made with triangle strip */
7929                 static const GLfloat m_vertex_buffer_data[] = {
7930                         -1.0f, -1.0f, 0.0f, 1.0f, /* left bottom */
7931                         -1.0f, 1.0f,  0.0f, 1.0f, /* left top */
7932                         1.0f,  -1.0f, 0.0f, 1.0f, /* right bottom */
7933                         1.0f,  1.0f,  0.0f, 1.0f, /* right top */
7934                 };
7935
7936                 /* Result of BuildProgram operation */
7937                 bool is_program_correct = true; /* BuildProgram set false when it fails, but it does not set true on success */
7938
7939                 /* Clean previous error */
7940                 glGetError();
7941
7942                 m_texture_edge = de::min(64, de::min(getWindowHeight(), getWindowWidth()));
7943
7944                 /* Prepare textures */
7945                 GLU_EXPECT_NO_ERROR(
7946                         Create2DRGBA8CompleteTexture(m_complete_destination_magic_number, m_complete_destination_texture_id),
7947                         "Create2DRGBA8CompleteTexture");
7948                 GLU_EXPECT_NO_ERROR(Create2DRGBA8CompleteTexture(m_complete_source_magic_number, m_complete_source_texture_id),
7949                                                         "Create2DRGBA8CompleteTexture");
7950                 GLU_EXPECT_NO_ERROR(
7951                         Create2DRGBA8IncompleteTexture(m_incomplete_destination_magic_number, m_incomplete_destination_texture_id),
7952                         "Create2DRGBA8IncompleteTexture");
7953                 GLU_EXPECT_NO_ERROR(
7954                         Create2DRGBA8IncompleteTexture(m_incomplete_source_magic_number, m_incomplete_source_texture_id),
7955                         "Create2DRGBA8IncompleteTexture");
7956
7957                 /* Prepare buffer with vertex positions of "full screen" quad" */
7958                 glGenBuffers(1, &m_vertex_buffer_id);
7959                 GLU_EXPECT_NO_ERROR(glGetError(), "GenBuffers");
7960
7961                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
7962                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
7963
7964                 glBufferData(GL_ARRAY_BUFFER, sizeof(m_vertex_buffer_data), m_vertex_buffer_data, GL_STATIC_DRAW);
7965                 GLU_EXPECT_NO_ERROR(glGetError(), "BufferData");
7966
7967                 /* Generate vertex array object */
7968                 glGenVertexArrays(1, &m_vertex_array_object_id);
7969                 GLU_EXPECT_NO_ERROR(glGetError(), "GenVertexArrays");
7970
7971                 /* Prepare program object */
7972                 m_program_id = BuildProgram(vertex_shader_code, 0 /* src_tcs */, 0 /* src_tes */, 0 /*src_gs */,
7973                                                                         fragment_shader_code, &is_program_correct);
7974
7975                 if (false == is_program_correct)
7976                 {
7977                         return ERROR;
7978                 }
7979
7980                 /* Done */
7981                 return NO_ERROR;
7982         }
7983
7984         virtual long Cleanup()
7985         {
7986                 /* Reset OpenGL state */
7987                 glBindBuffer(GL_ARRAY_BUFFER, 0);
7988                 glBindTexture(GL_TEXTURE_2D, 0);
7989                 glBindVertexArray(0);
7990                 glUseProgram(0);
7991
7992                 /* Delete program */
7993                 if (0 != m_program_id)
7994                 {
7995                         glDeleteProgram(m_program_id);
7996                         m_program_id = 0;
7997                 }
7998
7999                 /* Delete textures */
8000                 if (0 != m_complete_destination_texture_id)
8001                 {
8002                         glDeleteTextures(1, &m_complete_destination_texture_id);
8003                         m_complete_destination_texture_id = 0;
8004                 }
8005
8006                 if (0 != m_complete_source_texture_id)
8007                 {
8008                         glDeleteTextures(1, &m_complete_source_texture_id);
8009                         m_complete_source_texture_id = 0;
8010                 }
8011
8012                 if (0 != m_incomplete_destination_texture_id)
8013                 {
8014                         glDeleteTextures(1, &m_incomplete_destination_texture_id);
8015                         m_incomplete_destination_texture_id = 0;
8016                 }
8017
8018                 if (0 != m_incomplete_source_texture_id)
8019                 {
8020                         glDeleteTextures(1, &m_incomplete_source_texture_id);
8021                         m_incomplete_source_texture_id = 0;
8022                 }
8023
8024                 /* Delete vertex array object */
8025                 if (0 != m_vertex_array_object_id)
8026                 {
8027                         glDeleteVertexArrays(1, &m_vertex_array_object_id);
8028                         m_vertex_array_object_id = 0;
8029                 }
8030
8031                 /* Delete buffer */
8032                 if (0 != m_vertex_buffer_id)
8033                 {
8034                         glDeleteBuffers(1, &m_vertex_buffer_id);
8035                         m_vertex_buffer_id = 0;
8036                 }
8037
8038                 /* Done */
8039                 return NO_ERROR;
8040         }
8041
8042         virtual long Run()
8043         {
8044                 bool result = true;
8045
8046                 /* Copy textures data with imageLoad() and imageStore() operations */
8047                 Copy2DRGBA8Textures(m_complete_destination_texture_id, m_incomplete_destination_texture_id,
8048                                                         m_complete_source_texture_id, m_incomplete_source_texture_id);
8049
8050                 glMemoryBarrier(GL_ALL_BARRIER_BITS);
8051
8052                 /* Verify that store to "incomplete destination" was ignored */
8053                 if (true ==
8054                         CheckIfTextureWasModified(m_incomplete_destination_texture_id, m_incomplete_destination_magic_number))
8055                 {
8056                         m_context.getTestContext().getLog()
8057                                 << tcu::TestLog::Message << "Problem with imageStore, operation modified contents of incomplete texture"
8058                                 << tcu::TestLog::EndMessage;
8059
8060                         result = false;
8061                 }
8062
8063                 /* Verify that load from "incomplete source" returned 0 */
8064                 if (false == CheckIfTextureIsBlack(m_complete_destination_texture_id))
8065                 {
8066                         m_context.getTestContext().getLog()
8067                                 << tcu::TestLog::Message
8068                                 << "Problem with imageLoad, operation returned non 0 result for incomplete texture"
8069                                 << tcu::TestLog::EndMessage;
8070
8071                         result = false;
8072                 }
8073
8074                 if (false == result)
8075                 {
8076                         return ERROR;
8077                 }
8078
8079                 /* Done */
8080                 return NO_ERROR;
8081         }
8082
8083 private:
8084         /* Private methods */
8085
8086         /** Bind texture to image unit and sets image uniform to that unit
8087          *
8088          * @param program_id   Program object id
8089          * @param texture_id   Texture id
8090          * @param level        Texture level
8091          * @param image_unit   Index of image unit
8092          * @param uniform_name Name of image uniform
8093          **/
8094         void BindTextureToImage(GLuint program_id, GLuint texture_id, GLint level, GLuint image_unit, const char* uniform_name)
8095         {
8096                 /* Uniform location and invalid value */
8097                 static const GLint invalid_uniform_location = -1;
8098                 GLint                      image_uniform_location   = 0;
8099
8100                 /* Get uniform location */
8101                 image_uniform_location = glGetUniformLocation(program_id, uniform_name);
8102                 GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
8103                 if (invalid_uniform_location == image_uniform_location)
8104                 {
8105                         throw tcu::InternalError("Uniform location is not available", uniform_name, __FILE__, __LINE__);
8106                 }
8107
8108                 /* Bind texture to image unit */
8109                 glBindImageTexture(image_unit, texture_id, level, GL_FALSE, 0 /* layer */, GL_READ_WRITE, GL_RGBA8);
8110                 GLU_EXPECT_NO_ERROR(glGetError(), "BindImageTexture");
8111
8112                 /* Set uniform to image unit */
8113                 glUniform1i(image_uniform_location, image_unit);
8114                 GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
8115         }
8116
8117         /** Check if texture is filled with black color, zeros
8118          *
8119          * @param texture_id Id of texture object
8120          *
8121          * @return true when texture is fully black, false otherwise
8122          **/
8123         bool CheckIfTextureIsBlack(GLuint texture_id)
8124         {
8125                 /* Constants to calculate size of texture */
8126                 static const GLuint n_components          = 4; /* RGBA */
8127                 const GLuint            texture_data_size = m_texture_edge * m_texture_edge * n_components;
8128
8129                 /* Storage for texture data */
8130                 std::vector<GLubyte> black_texture_data;
8131                 std::vector<GLubyte> texture_data;
8132
8133                 /* Allocate memory */
8134                 black_texture_data.resize(texture_data_size);
8135                 texture_data.resize(texture_data_size);
8136
8137                 /* Set all texels to black */
8138                 for (GLuint i = 0; i < texture_data_size; ++i)
8139                 {
8140                         black_texture_data[i] = 0;
8141                 }
8142
8143                 /* Bind texture */
8144                 glBindTexture(GL_TEXTURE_2D, texture_id);
8145                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
8146
8147                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
8148                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
8149
8150                 /* Compare texels */
8151                 return (0 == memcmp(&texture_data[0], &black_texture_data[0], texture_data_size));
8152         }
8153
8154         /** Check if texture was modified
8155          *
8156          * @param texture_id   Id of texture object
8157          * @param nagic_number Magic number that was to create texture
8158          *
8159          * @return true if texture contents match expected values, false otherwise
8160          **/
8161         bool CheckIfTextureWasModified(GLuint texture_id, GLubyte magic_number)
8162         {
8163                 /* Constants to calculate size of texture */
8164                 static const GLuint n_components          = 4; /* RGBA */
8165                 const GLuint            texture_data_size = m_texture_edge * m_texture_edge * n_components;
8166
8167                 /* Storage for texture data */
8168                 std::vector<GLubyte> expected_texture_data;
8169                 std::vector<GLubyte> texture_data;
8170
8171                 /* Allocate memory */
8172                 expected_texture_data.resize(texture_data_size);
8173                 texture_data.resize(texture_data_size);
8174
8175                 /* Prepare expected texels */
8176                 for (GLuint y = 0; y < m_texture_edge; ++y)
8177                 {
8178                         const GLuint line_offset = y * m_texture_edge * n_components;
8179
8180                         for (GLuint x = 0; x < m_texture_edge; ++x)
8181                         {
8182                                 const GLuint texel_offset = x * n_components + line_offset;
8183
8184                                 SetTexel(&expected_texture_data[texel_offset], static_cast<GLubyte>(x), static_cast<GLubyte>(y),
8185                                                  magic_number);
8186                         }
8187                 }
8188
8189                 /* Bind texture */
8190                 glBindTexture(GL_TEXTURE_2D, texture_id);
8191                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
8192
8193                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texture_data[0]);
8194                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
8195
8196                 /* Compare texels, true when textures are different */
8197                 return (0 != memcmp(&texture_data[0], &expected_texture_data[0], texture_data_size));
8198         }
8199
8200         /** Copy contents of "source" textures to "destination" textures with imageLoad() and imageStore() operations
8201          *
8202          * @param complete_destination_texture_id   Id of "complete destination" texture object
8203          * @param incomplete_destination_texture_id Id of "incomplete destination" texture object
8204          * @param complete_source_texture_id        Id of "complete source" texture object
8205          * @param incomplete_source_texture_id      Id of "incomplete source" texture object
8206          **/
8207         void Copy2DRGBA8Textures(GLuint complete_destination_texture_id, GLuint incomplete_destination_texture_id,
8208                                                          GLuint complete_source_texture_id, GLuint incomplete_source_texture_id)
8209         {
8210                 /* Uniform names */
8211                 static const char* const complete_destination_image_uniform_name   = "u_complete_destination_image";
8212                 static const char* const complete_source_image_uniform_name                = "u_complete_source_image";
8213                 static const char* const incomplete_destination_image_uniform_name = "u_incomplete_destination_image";
8214                 static const char* const incomplete_source_image_uniform_name     = "u_incomplete_source_image";
8215
8216                 /* Attribute name */
8217                 static const char* const position_attribute_name = "vs_in_position";
8218
8219                 /* Attribute location and invalid value */
8220                 static const GLint invalid_attribute_location  = -1;
8221                 GLint                      position_attribute_location = 0;
8222
8223                 /* Set current program */
8224                 glUseProgram(m_program_id);
8225                 GLU_EXPECT_NO_ERROR(glGetError(), "UseProgram");
8226
8227                 /* Bind vertex array object */
8228                 glBindVertexArray(m_vertex_array_object_id);
8229                 GLU_EXPECT_NO_ERROR(glGetError(), "BindVertexArray");
8230
8231                 /* Bind buffer with quad vertex positions */
8232                 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer_id);
8233                 GLU_EXPECT_NO_ERROR(glGetError(), "BindBuffer");
8234
8235                 /* Setup position attribute */
8236                 position_attribute_location = glGetAttribLocation(m_program_id, position_attribute_name);
8237                 GLU_EXPECT_NO_ERROR(glGetError(), "GetAttribLocation");
8238                 if (invalid_attribute_location == position_attribute_location)
8239                 {
8240                         throw tcu::InternalError("Attribute location is not available", position_attribute_name, __FILE__,
8241                                                                          __LINE__);
8242                 }
8243
8244                 glVertexAttribPointer(position_attribute_location, 4 /*size */, GL_FLOAT, GL_FALSE, 0 /* stride */, 0);
8245                 GLU_EXPECT_NO_ERROR(glGetError(), "VertexAttribPointer");
8246
8247                 glEnableVertexAttribArray(position_attribute_location);
8248                 GLU_EXPECT_NO_ERROR(glGetError(), "EnableVertexAttribArray");
8249
8250                 /* Setup textures as source and destination images */
8251                 BindTextureToImage(m_program_id, complete_destination_texture_id,
8252                                                    0 /* texture level */, 0 /* image_unit */,
8253                                                    complete_destination_image_uniform_name);
8254                 BindTextureToImage(m_program_id, complete_source_texture_id,
8255                                                    0 /* texture level */, 1 /* image_unit */,
8256                                                    complete_source_image_uniform_name);
8257                 BindTextureToImage(m_program_id, incomplete_destination_texture_id,
8258                                                    2 /* texture level */, 2 /* image_unit */,
8259                                                    incomplete_destination_image_uniform_name);
8260                 BindTextureToImage(m_program_id, incomplete_source_texture_id,
8261                                                    2 /* texture level */, 3 /* image_unit */,
8262                                                    incomplete_source_image_uniform_name);
8263
8264                 /* Execute draw */
8265                 glDrawArrays(GL_TRIANGLE_STRIP, 0 /* first vertex */, 4 /* number of vertices */);
8266                 GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
8267         }
8268
8269         /** Create complete 2D RGBA8 texture.
8270          *
8271          * @param magic_number   Magic number of texture
8272          * @param out_texture_id Id of created texture, not modified if operation fails
8273          *
8274          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
8275          **/
8276         GLenum Create2DRGBA8CompleteTexture(GLubyte magic_number, GLuint& out_texture_id)
8277         {
8278                 /* Constants to calculate size of texture */
8279                 static const GLuint n_components          = 4; /* RGBA */
8280                 const GLuint            texture_data_size = m_texture_edge * m_texture_edge * n_components;
8281
8282                 /* Error code */
8283                 GLenum err = 0;
8284
8285                 /* Texture id */
8286                 GLuint texture_id = 0;
8287
8288                 /* Prepare storage for texture data */
8289                 std::vector<GLubyte> texture_data;
8290                 texture_data.resize(texture_data_size);
8291
8292                 /* Prepare texture data */
8293                 for (GLuint y = 0; y < m_texture_edge; ++y)
8294                 {
8295                         const GLuint line_offset = y * m_texture_edge * n_components;
8296
8297                         for (GLuint x = 0; x < m_texture_edge; ++x)
8298                         {
8299                                 const GLuint texel_offset = x * n_components + line_offset;
8300
8301                                 SetTexel(&texture_data[texel_offset], static_cast<GLubyte>(x), static_cast<GLubyte>(y), magic_number);
8302                         }
8303                 }
8304
8305                 /* Generate texture */
8306                 glGenTextures(1, &texture_id);
8307                 err = glGetError();
8308                 if (GL_NO_ERROR != err)
8309                 {
8310                         return err;
8311                 }
8312
8313                 /* Bind texture */
8314                 glBindTexture(GL_TEXTURE_2D, texture_id);
8315                 err = glGetError();
8316                 if (GL_NO_ERROR != err)
8317                 {
8318                         glDeleteTextures(1, &texture_id);
8319                         return err;
8320                 }
8321
8322                 /* Allocate storage and fill texture */
8323                 glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA8, m_texture_edge, m_texture_edge, 0 /* border */, GL_RGBA,
8324                                          GL_UNSIGNED_BYTE, &texture_data[0]);
8325                 err = glGetError();
8326                 if (GL_NO_ERROR != err)
8327                 {
8328                         glDeleteTextures(1, &texture_id);
8329                         return err;
8330                 }
8331
8332                 /* Make texture complete */
8333                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8334                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8335                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8336                 err = glGetError();
8337                 if (GL_NO_ERROR != err)
8338                 {
8339                         glDeleteTextures(1, &texture_id);
8340                         return err;
8341                 }
8342
8343                 /* Set out_texture_id */
8344                 out_texture_id = texture_id;
8345
8346                 /* Done */
8347                 return GL_NO_ERROR;
8348         }
8349
8350         /** Create incomplete 2D RGBA8 texture
8351          *
8352          * @param magic_number   Magic number of texture
8353          * @param out_texture_id Id of created texture, not modified if operation fails
8354          *
8355          * @return GL_NO_ERROR if operation was successful, GL error code otherwise
8356          **/
8357         GLenum Create2DRGBA8IncompleteTexture(GLubyte magic_number, GLuint& out_texture_id)
8358         {
8359                 /* Constants to calculate size of texture */
8360                 static const GLuint n_components          = 4; /* RGBA */
8361                 const GLuint            texture_data_size = m_texture_edge * m_texture_edge * n_components;
8362
8363                 /* Error code */
8364                 GLenum err = 0;
8365
8366                 /* Texture id */
8367                 GLuint texture_id = 0;
8368
8369                 /* Prepare storage for texture data */
8370                 std::vector<GLubyte> texture_data;
8371                 texture_data.resize(texture_data_size);
8372
8373                 /* Prepare texture data */
8374                 for (GLuint y = 0; y < m_texture_edge; ++y)
8375                 {
8376                         const GLuint line_offset = y * m_texture_edge * n_components;
8377
8378                         for (GLuint x = 0; x < m_texture_edge; ++x)
8379                         {
8380                                 const GLuint texel_offset = x * n_components + line_offset;
8381
8382                                 SetTexel(&texture_data[texel_offset], static_cast<GLubyte>(x), static_cast<GLubyte>(y), magic_number);
8383                         }
8384                 }
8385
8386                 /* Generate texture */
8387                 glGenTextures(1, &texture_id);
8388                 err = glGetError();
8389                 if (GL_NO_ERROR != err)
8390                 {
8391                         return err;
8392                 }
8393
8394                 /* Bind texture */
8395                 glBindTexture(GL_TEXTURE_2D, texture_id);
8396                 err = glGetError();
8397                 if (GL_NO_ERROR != err)
8398                 {
8399                         glDeleteTextures(1, &texture_id);
8400                         return err;
8401                 }
8402
8403                 /* Allocate storage and fill texture */
8404                 glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA8, m_texture_edge, m_texture_edge, 0 /* border */, GL_RGBA,
8405                                          GL_UNSIGNED_BYTE, &texture_data[0]);
8406                 err = glGetError();
8407                 if (GL_NO_ERROR != err)
8408                 {
8409                         glDeleteTextures(1, &texture_id);
8410                         return err;
8411                 }
8412
8413                 /* Make texture incomplete */
8414                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
8415                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 7);
8416                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
8417                 err = glGetError();
8418                 if (GL_NO_ERROR != err)
8419                 {
8420                         glDeleteTextures(1, &texture_id);
8421                         return err;
8422                 }
8423
8424                 /* Set out_texture_id */
8425                 out_texture_id = texture_id;
8426
8427                 /* Done */
8428                 return GL_NO_ERROR;
8429         }
8430
8431         /** Prepare "unique" texels.
8432          *  Texel is assigned with such values: [x_coordinate, y_coordinate, magic_number, 0xcc].
8433          *
8434          * @param texel        Storage of texel
8435          * @param x_coordinate X coordiante of texel
8436          * @param y_coordinate Y coordinate of texel
8437          * @param magic_number Magic number of texture
8438          **/
8439         void SetTexel(GLubyte texel[4], GLubyte x_coordinate, GLubyte y_coordinate, GLubyte magic_number)
8440         {
8441                 texel[0] = x_coordinate;
8442                 texel[1] = y_coordinate;
8443                 texel[2] = magic_number;
8444                 texel[3] = 0xcc;
8445         }
8446 };
8447
8448 /** Test "Refer to the same image unit using multiple uniforms", description follows.
8449  *
8450  * Steps:
8451  * - prepare program object, see details below,
8452  * - prepare 2D R32I texture, width should be equal to the number of image
8453  * uniforms used by program object, height should be 2, fill first row with
8454  * unique values, fill second row with zeros,
8455  * - bind texture to first image unit,
8456  * - set all image uniforms to first image unit,
8457  * - execute program for a single vertex,
8458  * - verify that:
8459  *     - values in first row were negated,
8460  *     - values from first row were copied to second row,
8461  *
8462  * Repeat steps to test all shader stages that support at least 2 image
8463  * uniforms.
8464  *
8465  * Program has to contain all necessary shader stages. Use boilerplate shaders
8466  * for shader stages that are not important for the test.
8467  *
8468  * Tested shader stage should:
8469  * - Use as many different image formats as possible, image formats compatible
8470  * with R32I:
8471  *     * rg16f
8472  *     * r11f_g11f_b10f
8473  *     * r32f
8474  *     * rgb10_a2ui
8475  *     * rgba8ui
8476  *     * rg16ui
8477  *     * r32ui
8478  *     * rgba8i
8479  *     * rg16i
8480  *     * r32i
8481  *     * rgb10_a2
8482  *     * rgba8
8483  *     * rg16
8484  *     * rgba8_snorm
8485  *     * rg16_snorm.
8486  * - Declare maximum allowed number of image uniforms,
8487  *
8488  *     layout(format) uniform gimage2D u_image;
8489  *
8490  * where <format> is selected image format, <gimage2D> is type of 2D image
8491  * compatible with <format> and <u_image> is unique name of uniform.
8492  * Note that image uniforms cannot be declared as array, due to different image
8493  * formats. Therefore separate uniforms have to be used.
8494  * - Include following code snippet:
8495  * for (int i = 0; i < gl_Max*ImageUniforms; ++i)
8496  * {
8497  *     vec row_1_coord(i,0);
8498  *     vec row_2_coord(i,1);
8499  *
8500  *     row_1_value = imageLoad(u_image[i], row_1_coord);
8501  *     imageStore(u_image[i], row_1_coord, -row_1_value);
8502  *     imageStore(u_image[i], row_2_coord, row_1_value);
8503  * }
8504  * where gl_Max*ImageUniforms is the constant corresponding to tested shader
8505  * stage.
8506  **/
8507 class ImageLoadStoreMultipleUniformsTest : public ShaderImageLoadStoreBase
8508 {
8509 private:
8510         /* Types */
8511         /** Details of image format
8512          *
8513          **/
8514         struct imageFormatDetails
8515         {
8516                 typedef bool (*verificationRoutine)(GLint, GLint, GLint);
8517
8518                 const char*                     m_image_format;
8519                 const char*                     m_image_type;
8520                 const char*                     m_color_type;
8521                 GLenum                          m_image_unit_format;
8522                 verificationRoutine m_verification_routine;
8523         };
8524
8525         template <typename T, GLuint SIZE, GLuint OFFSET, bool = (OFFSET < sizeof(T) * CHAR_BIT)>
8526         struct Masks
8527         {
8528                 /** Get mask of bits used to store in bit-field
8529                  *
8530                  * @return Mask
8531                  **/
8532                 static inline T RawMask()
8533                 {
8534                         static const T mask = ValueMask() << OFFSET;
8535
8536                         return mask;
8537                 }
8538
8539                 /** Get mask of bits used to store value.
8540                  *
8541                  * @return Mask
8542                  **/
8543                 static inline T ValueMask()
8544                 {
8545                         static const T mask = (1 << SIZE) - 1;
8546
8547                         return mask;
8548                 }
8549
8550                 /** Get offset.
8551                  *
8552                  * @return offset
8553                  **/
8554                 static inline T Offset()
8555                 {
8556                         return OFFSET;
8557                 }
8558         };
8559
8560         template <typename T, GLuint SIZE, GLuint OFFSET>
8561         struct Masks<T, SIZE, OFFSET, false>
8562         {
8563                 /** Get mask of bits used to store in bit-field
8564                  *
8565                  * @return Mask
8566                  **/
8567                 static inline T RawMask()
8568                 {
8569                         DE_ASSERT(DE_FALSE && "Shouldn't be called");
8570                         return 0;
8571                 }
8572
8573                 /** Get mask of bits used to store value.
8574                  *
8575                  * @return Mask
8576                  **/
8577                 static inline T ValueMask()
8578                 {
8579                         DE_ASSERT(DE_FALSE && "Shouldn't be called");
8580                         return 0;
8581                 }
8582
8583                 /** Get offset.
8584                  *
8585                  * @return offset
8586                  **/
8587                 static inline T Offset()
8588                 {
8589                         DE_ASSERT(DE_FALSE && "Shouldn't be called");
8590                         return 0;
8591                 }
8592         };
8593
8594         /** Template class for accessing integer values stored in bit-fields
8595          *
8596          **/
8597         template <typename T, GLuint SIZE, GLuint OFFSET>
8598         class Integer
8599         {
8600         public:
8601                 /** Constructor
8602                  *
8603                  **/
8604                 Integer(T raw) : m_raw(raw)
8605                 {
8606                 }
8607
8608                 /** Extract value from bit-field
8609                  *
8610                  * @return Value
8611                  **/
8612                 T Get() const
8613                 {
8614                         const T mask = Masks<T, SIZE, OFFSET>::RawMask();
8615
8616                         const T bits   = m_raw & mask;
8617                         const T result = (unsigned)bits >> Masks<T, SIZE, OFFSET>::Offset();
8618
8619                         return result;
8620                 }
8621
8622                 /** Extract value from bit-field and negate it
8623                  *
8624                  * @return Negated value
8625                  **/
8626                 T GetNegated() const
8627                 {
8628                         const T mask  = Masks<T, SIZE, OFFSET>::ValueMask();
8629                         const T value = Get();
8630
8631                         return Clamp((~value) + 1) & mask;
8632                 }
8633
8634                 T Clamp(T n) const
8635                 {
8636                         const bool isUnsigned = (T(0) < T(-1));
8637                         const T min               = T(isUnsigned ? 0.L : -pow(2.L, int(SIZE - 1)));
8638                         const T max               = T(isUnsigned ? pow(2.L, int(SIZE)) - 1.L : pow(2.L, int(SIZE - 1)) - 1.L);
8639                         const T x                 = n > max ? max : n;
8640                         return x < min ? min : x;
8641                 }
8642
8643         private:
8644                 T m_raw;
8645         };
8646
8647         /* Enums */
8648         /** Shader stage identification
8649          *
8650          **/
8651         enum shaderStage
8652         {
8653                 fragmentShaderStage                              = 2,
8654                 geometryShaderStage                              = 4,
8655                 tesselationControlShaderStage   = 8,
8656                 tesselationEvalutaionShaderStage = 16,
8657                 vertexShaderStage                                = 32,
8658         };
8659
8660         /** Test result
8661          *
8662          **/
8663         enum testResult
8664         {
8665                 testFailed               = -1,
8666                 testNotSupported = 1,
8667                 testPassed               = 0
8668         };
8669
8670         /* Constants */
8671         static const GLint m_min_required_image_uniforms = 2;
8672
8673         /* Fields */
8674         GLuint m_program_to_test_fs_stage_id;
8675         GLuint m_program_to_test_gs_stage_id;
8676         GLuint m_program_to_test_tcs_stage_id;
8677         GLuint m_program_to_test_tes_stage_id;
8678         GLuint m_program_to_test_vs_stage_id;
8679         GLuint m_texture_to_test_fs_stage_id;
8680         GLuint m_texture_to_test_gs_stage_id;
8681         GLuint m_texture_to_test_tcs_stage_id;
8682         GLuint m_texture_to_test_tes_stage_id;
8683         GLuint m_texture_to_test_vs_stage_id;
8684         GLuint m_vertex_array_object_id;
8685
8686 public:
8687         /* Constructor */
8688         ImageLoadStoreMultipleUniformsTest()
8689                 : m_program_to_test_fs_stage_id(0)
8690                 , m_program_to_test_gs_stage_id(0)
8691                 , m_program_to_test_tcs_stage_id(0)
8692                 , m_program_to_test_tes_stage_id(0)
8693                 , m_program_to_test_vs_stage_id(0)
8694                 , m_texture_to_test_fs_stage_id(0)
8695                 , m_texture_to_test_gs_stage_id(0)
8696                 , m_texture_to_test_tcs_stage_id(0)
8697                 , m_texture_to_test_tes_stage_id(0)
8698                 , m_texture_to_test_vs_stage_id(0)
8699                 , m_vertex_array_object_id(0)
8700         {
8701                 /* Nothing to be done here */
8702         }
8703
8704         /* Methods inherited from SubcaseBase */
8705         virtual long Setup()
8706         {
8707                 /* Prepare programs */
8708                 m_program_to_test_fs_stage_id  = buildProgramToTestShaderStage(fragmentShaderStage);
8709                 m_program_to_test_gs_stage_id  = buildProgramToTestShaderStage(geometryShaderStage);
8710                 m_program_to_test_tcs_stage_id = buildProgramToTestShaderStage(tesselationControlShaderStage);
8711                 m_program_to_test_tes_stage_id = buildProgramToTestShaderStage(tesselationEvalutaionShaderStage);
8712                 m_program_to_test_vs_stage_id  = buildProgramToTestShaderStage(vertexShaderStage);
8713
8714                 /* Prepare textures */
8715                 m_texture_to_test_fs_stage_id  = createTextureToTestShaderStage(fragmentShaderStage);
8716                 m_texture_to_test_gs_stage_id  = createTextureToTestShaderStage(geometryShaderStage);
8717                 m_texture_to_test_tcs_stage_id = createTextureToTestShaderStage(tesselationControlShaderStage);
8718                 m_texture_to_test_tes_stage_id = createTextureToTestShaderStage(tesselationEvalutaionShaderStage);
8719                 m_texture_to_test_vs_stage_id  = createTextureToTestShaderStage(vertexShaderStage);
8720
8721                 /* Generate vertex array object */
8722                 glGenVertexArrays(1, &m_vertex_array_object_id);
8723                 GLU_EXPECT_NO_ERROR(glGetError(), "GenVertexArrays");
8724
8725                 /* Bind vertex array object */
8726                 glBindVertexArray(m_vertex_array_object_id);
8727                 GLU_EXPECT_NO_ERROR(glGetError(), "BindVertexArray");
8728
8729                 /* Set vertices number for patches */
8730                 glPatchParameteri(GL_PATCH_VERTICES, 1);
8731
8732                 /* Done */
8733                 return NO_ERROR;
8734         }
8735
8736         virtual long Cleanup()
8737         {
8738                 glUseProgram(0);
8739
8740                 /* Delete programs */
8741                 if (0 != m_program_to_test_fs_stage_id)
8742                 {
8743                         glDeleteProgram(m_program_to_test_fs_stage_id);
8744                         m_program_to_test_fs_stage_id = 0;
8745                 }
8746
8747                 if (0 != m_program_to_test_gs_stage_id)
8748                 {
8749                         glDeleteProgram(m_program_to_test_gs_stage_id);
8750                         m_program_to_test_gs_stage_id = 0;
8751                 }
8752
8753                 if (0 != m_program_to_test_tcs_stage_id)
8754                 {
8755                         glDeleteProgram(m_program_to_test_tcs_stage_id);
8756                         m_program_to_test_tcs_stage_id = 0;
8757                 }
8758
8759                 if (0 != m_program_to_test_tes_stage_id)
8760                 {
8761                         glDeleteProgram(m_program_to_test_tes_stage_id);
8762                         m_program_to_test_tes_stage_id = 0;
8763                 }
8764
8765                 if (0 != m_program_to_test_vs_stage_id)
8766                 {
8767                         glDeleteProgram(m_program_to_test_vs_stage_id);
8768                         m_program_to_test_vs_stage_id = 0;
8769                 }
8770
8771                 /* Delete textures */
8772                 if (0 != m_texture_to_test_fs_stage_id)
8773                 {
8774                         glDeleteTextures(1, &m_texture_to_test_fs_stage_id);
8775                         m_texture_to_test_fs_stage_id = 0;
8776                 }
8777
8778                 if (0 != m_texture_to_test_gs_stage_id)
8779                 {
8780                         glDeleteTextures(1, &m_texture_to_test_gs_stage_id);
8781                         m_texture_to_test_gs_stage_id = 0;
8782                 }
8783
8784                 if (0 != m_texture_to_test_tcs_stage_id)
8785                 {
8786                         glDeleteTextures(1, &m_texture_to_test_tcs_stage_id);
8787                         m_texture_to_test_tcs_stage_id = 0;
8788                 }
8789
8790                 if (0 != m_texture_to_test_tes_stage_id)
8791                 {
8792                         glDeleteTextures(1, &m_texture_to_test_tes_stage_id);
8793                         m_texture_to_test_tes_stage_id = 0;
8794                 }
8795
8796                 if (0 != m_texture_to_test_vs_stage_id)
8797                 {
8798                         glDeleteTextures(1, &m_texture_to_test_vs_stage_id);
8799                         m_texture_to_test_vs_stage_id = 0;
8800                 }
8801
8802                 /* Delete vertex array object id */
8803                 if (0 != m_vertex_array_object_id)
8804                 {
8805                         glDeleteVertexArrays(1, &m_vertex_array_object_id);
8806                         m_vertex_array_object_id = 0;
8807                 }
8808
8809                 /* Done */
8810                 return NO_ERROR;
8811         }
8812
8813         virtual long Run()
8814         {
8815                 bool result = true;
8816
8817                 if (testFailed == testShaderStage(fragmentShaderStage))
8818                 {
8819                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Problems with fragment shader stage!"
8820                                                                                                 << tcu::TestLog::EndMessage;
8821
8822                         result = false;
8823                 }
8824
8825                 if (testFailed == testShaderStage(geometryShaderStage))
8826                 {
8827                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Problems with geometry shader stage!"
8828                                                                                                 << tcu::TestLog::EndMessage;
8829
8830                         result = false;
8831                 }
8832
8833                 if (testFailed == testShaderStage(tesselationControlShaderStage))
8834                 {
8835                         m_context.getTestContext().getLog() << tcu::TestLog::Message
8836                                                                                                 << "Problems with tesselation control shader stage!"
8837                                                                                                 << tcu::TestLog::EndMessage;
8838
8839                         result = false;
8840                 }
8841
8842                 if (testFailed == testShaderStage(tesselationEvalutaionShaderStage))
8843                 {
8844                         m_context.getTestContext().getLog() << tcu::TestLog::Message
8845                                                                                                 << "Problems with tesselation evaluation shader stage!"
8846                                                                                                 << tcu::TestLog::EndMessage;
8847
8848                         result = false;
8849                 }
8850
8851                 if (testFailed == testShaderStage(vertexShaderStage))
8852                 {
8853                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Problems with vertex shader stage!"
8854                                                                                                 << tcu::TestLog::EndMessage;
8855
8856                         result = false;
8857                 }
8858
8859                 if (false == result)
8860                 {
8861                         return ERROR;
8862                 }
8863
8864                 /* Done */
8865                 return NO_ERROR;
8866         }
8867
8868 private:
8869         /* Static routines */
8870         /** Provide image format details for given index
8871          *
8872          * @param index       Index
8873          * @param out_details Image format detail instance
8874          **/
8875         static void getImageUniformDeclarationDetails(GLuint index, imageFormatDetails& out_details)
8876         {
8877                 static const ImageLoadStoreMultipleUniformsTest::imageFormatDetails default_format_details = {
8878                         "r32i", "iimage2D", "ivec4", GL_R32I, ImageLoadStoreMultipleUniformsTest::verifyInteger
8879                 };
8880
8881                 static const ImageLoadStoreMultipleUniformsTest::imageFormatDetails format_details[] = {
8882                         { "rg16f", "image2D", "vec4", GL_RG16F, ImageLoadStoreMultipleUniformsTest::verifyFloat<GLushort> },
8883                         { "r11f_g11f_b10f", "image2D", "vec4", GL_R11F_G11F_B10F,
8884                           ImageLoadStoreMultipleUniformsTest::verifyFloatUnsigned<GLuint> },
8885                         { "r32f", "image2D", "vec4", GL_R32F, ImageLoadStoreMultipleUniformsTest::verifyFloat<GLuint> },
8886                         { "rgb10_a2", "image2D", "vec4", GL_RGB10_A2,
8887                           ImageLoadStoreMultipleUniformsTest::verifyFloatUnsigned<GLuint> },
8888                         { "rgba8", "image2D", "vec4", GL_RGBA8, ImageLoadStoreMultipleUniformsTest::verifyFloatUnsigned<GLuint> },
8889                         { "rg16", "image2D", "vec4", GL_RG16, ImageLoadStoreMultipleUniformsTest::verifyFloatUnsigned<GLuint> },
8890                         { "rgba8_snorm", "image2D", "vec4", GL_RGBA8_SNORM,
8891                           ImageLoadStoreMultipleUniformsTest::verifyFloatSignedNorm<GLbyte> },
8892                         { "rg16_snorm", "image2D", "vec4", GL_RG16_SNORM,
8893                           ImageLoadStoreMultipleUniformsTest::verifyFloatSignedNorm<GLshort> },
8894                         { "rgb10_a2ui", "uimage2D", "uvec4", GL_RGB10_A2UI,
8895                           ImageLoadStoreMultipleUniformsTest::verifyInteger<10, 10, 10, 2, GLuint> },
8896                         { "rgba8ui", "uimage2D", "uvec4", GL_RGBA8UI,
8897                           ImageLoadStoreMultipleUniformsTest::verifyInteger<8, 8, 8, 8, GLuint> },
8898                         { "rg16ui", "uimage2D", "uvec4", GL_RG16UI,
8899                           ImageLoadStoreMultipleUniformsTest::verifyInteger<16, 16, 0, 0, GLuint> },
8900                         { "r32ui", "uimage2D", "uvec4", GL_R32UI, ImageLoadStoreMultipleUniformsTest::verifyInteger },
8901                         { "rgba8i", "iimage2D", "ivec4", GL_RGBA8I,
8902                           ImageLoadStoreMultipleUniformsTest::verifyInteger<8, 8, 8, 8, GLint> },
8903                         { "rg16i", "iimage2D", "ivec4", GL_RG16I,
8904                           ImageLoadStoreMultipleUniformsTest::verifyInteger<16, 16, 0, 0, GLint> }
8905                 };
8906
8907                 static const GLuint n_imageUniformFormatDetails =
8908                         sizeof(format_details) / sizeof(ImageLoadStoreMultipleUniformsTest::imageFormatDetails);
8909
8910                 if (n_imageUniformFormatDetails <= index)
8911                 {
8912                         out_details = default_format_details;
8913                 }
8914                 else
8915                 {
8916                         out_details = format_details[index];
8917                 }
8918         }
8919
8920         /** Write name of image uniform at given index to output stream
8921          *
8922          * @param stream Output stream
8923          * @param index  Index
8924          **/
8925         static void writeImageUniformNameToStream(std::ostream& stream, GLuint index)
8926         {
8927                 /* u_image_0 */
8928                 stream << "u_image_" << index;
8929         }
8930
8931         /** Write name of variable used to store value loaded from image at given index to output stream
8932          *
8933          * @param stream Output stream
8934          * @param index  Index
8935          **/
8936         static void writeLoadedValueVariableNameToStream(std::ostream& stream, GLuint index)
8937         {
8938                 /* loaded_value_0 */
8939                 stream << "loaded_value_" << index;
8940         }
8941
8942         /** Write name of variable used to store coordinate of texel at given row to output stream
8943          *
8944          * @param stream Output stream
8945          * @param index  Index of image uniform
8946          * @param row    Row of image
8947          **/
8948         static void writeCoordinatesVariableNameToStream(std::ostream& stream, GLuint index, GLuint row)
8949         {
8950                 /* row_0_coordinates_0 */
8951                 stream << "row_" << row << "_coordinates_" << index;
8952         }
8953
8954         struct imageUniformDeclaration
8955         {
8956                 imageUniformDeclaration(GLuint index) : m_index(index)
8957                 {
8958                 }
8959
8960                 GLuint m_index;
8961         };
8962
8963         /** Write declaration of image uniform at given index to output stream
8964          *
8965          * @param stream                   Output stream
8966          * @param imageUniformDeclaration  Declaration details
8967          *
8968          * @return stream
8969          **/
8970         friend std::ostream& operator<<(std::ostream& stream, const imageUniformDeclaration& declaration)
8971         {
8972                 ImageLoadStoreMultipleUniformsTest::imageFormatDetails format_details;
8973                 getImageUniformDeclarationDetails(declaration.m_index, format_details);
8974
8975                 /* layout(r32f) uniform image2D u_image_0; */
8976                 stream << "layout(" << format_details.m_image_format << ") uniform " << format_details.m_image_type << " ";
8977
8978                 ImageLoadStoreMultipleUniformsTest::writeImageUniformNameToStream(stream, declaration.m_index);
8979
8980                 stream << ";";
8981
8982                 return stream;
8983         }
8984
8985         struct imageLoadCall
8986         {
8987                 imageLoadCall(GLuint index) : m_index(index)
8988                 {
8989                 }
8990
8991                 GLuint m_index;
8992         };
8993
8994         /* Stream operators */
8995         /** Write code that execute imageLoad routine for image at given index to output stream
8996          *
8997          * @param stream Output stream
8998          * @param load   imageLoad call details
8999          *
9000          * @return stream
9001          **/
9002         friend std::ostream& operator<<(std::ostream& stream, const imageLoadCall& load)
9003         {
9004                 ImageLoadStoreMultipleUniformsTest::imageFormatDetails format_details;
9005                 getImageUniformDeclarationDetails(load.m_index, format_details);
9006
9007                 /* vec4 loaded_value_0 = imageLoad(u_image_0, row_0_coordinates_0); */
9008                 stream << format_details.m_color_type << " ";
9009
9010                 writeLoadedValueVariableNameToStream(stream, load.m_index);
9011
9012                 stream << " = imageLoad(";
9013
9014                 writeImageUniformNameToStream(stream, load.m_index);
9015
9016                 stream << ", ";
9017
9018                 writeCoordinatesVariableNameToStream(stream, load.m_index, 0 /* row */);
9019
9020                 stream << ");";
9021
9022                 return stream;
9023         }
9024
9025         struct imageStoreCall
9026         {
9027                 imageStoreCall(GLuint index, GLuint row) : m_index(index), m_row(row)
9028                 {
9029                 }
9030
9031                 GLuint m_index;
9032                 GLuint m_row;
9033         };
9034
9035         /** Write code that execute imageStore to image at given index to output stream
9036          *
9037          * @param stream Output stream
9038          * @param store  imageStore call details
9039          *
9040          * @return stream
9041          **/
9042         friend std::ostream& operator<<(std::ostream& stream, const imageStoreCall& store)
9043         {
9044                 /* imageStore(u_image_0, row_0_coordinates_0, -loaded_value_0); */
9045                 stream << "imageStore(";
9046
9047                 writeImageUniformNameToStream(stream, store.m_index);
9048
9049                 stream << ", ";
9050
9051                 writeCoordinatesVariableNameToStream(stream, store.m_index, store.m_row);
9052
9053                 if (0 == store.m_row)
9054                 {
9055                         stream << ", -";
9056                 }
9057                 else
9058                 {
9059                         stream << ", ";
9060                 }
9061
9062                 writeLoadedValueVariableNameToStream(stream, store.m_index);
9063                 stream << ");";
9064
9065                 return stream;
9066         }
9067
9068         struct coordinatesVariableDeclaration
9069         {
9070                 coordinatesVariableDeclaration(GLuint index, GLuint row) : m_index(index), m_row(row)
9071                 {
9072                 }
9073                 GLuint m_index;
9074                 GLuint m_row;
9075         };
9076
9077         /** Write declaration of variable for coordinate at given row to output stream
9078          *
9079          * @param stream      Output stream
9080          * @param declaration Declaration details
9081          *
9082          * @return stream
9083          **/
9084         friend std::ostream& operator<<(std::ostream& stream, const coordinatesVariableDeclaration& declaration)
9085         {
9086                 stream << "const ivec2 ";
9087
9088                 writeCoordinatesVariableNameToStream(stream, declaration.m_index, declaration.m_row);
9089
9090                 stream << " = ivec2(" << declaration.m_index << ", " << declaration.m_row << ");";
9091
9092                 return stream;
9093         }
9094
9095         /* Methods */
9096         /** Build program to test specified shader stage
9097          *
9098          * Throws exception in case of any failure
9099          *
9100          * @param stage Stage id
9101          *
9102          * @return Program id
9103          **/
9104         GLuint buildProgramToTestShaderStage(shaderStage stage)
9105         {
9106                 static const char* const boilerplate_fragment_shader_code =
9107                         "#version 400 core\n"
9108                         "#extension GL_ARB_shader_image_load_store : require\n"
9109                         "\n"
9110                         "precision highp float;\n"
9111                         "\n"
9112                         "void main()\n"
9113                         "{\n"
9114                         "    discard;\n"
9115                         "}\n";
9116
9117                 static const char* const boilerplate_tesselation_evaluation_shader_code =
9118                         "#version 400 core\n"
9119                         "#extension GL_ARB_shader_image_load_store : require\n"
9120                         "\n"
9121                         "precision highp float;\n"
9122                         "\n"
9123                         "layout(quads, equal_spacing, ccw) in;\n"
9124                         "\n"
9125                         "void main()\n"
9126                         "{\n"
9127                         "\n"
9128                         "}\n";
9129
9130                 static const char* const boilerplate_vertex_shader_code =
9131                         "#version 400 core\n"
9132                         "#extension GL_ARB_shader_image_load_store : require\n"
9133                         "\n"
9134                         "precision highp float;\n"
9135                         "\n"
9136                         "layout(location = 0) in vec4 i_position;\n"
9137                         "\n"
9138                         "void main()\n"
9139                         "{\n"
9140                         "  gl_Position = i_position;\n"
9141                         "}\n";
9142
9143                 const char* fragment_shader_code                           = boilerplate_fragment_shader_code;
9144                 const char* geometry_shader_code                           = 0;
9145                 bool            is_program_built                                   = true;
9146                 GLuint          program_object_id                                  = 0;
9147                 const char* tesselation_control_shader_code     = 0;
9148                 const char* tesselation_evaluation_shader_code = 0;
9149                 std::string tested_shader_stage_code;
9150                 const char* vertex_shader_code = boilerplate_vertex_shader_code;
9151
9152                 /* Get source code for tested shader stage */
9153                 prepareShaderForTestedShaderStage(stage, tested_shader_stage_code);
9154
9155                 if (true == tested_shader_stage_code.empty())
9156                 {
9157                         return 0;
9158                 }
9159
9160                 /* Set up source code for all required stages */
9161                 switch (stage)
9162                 {
9163                 case fragmentShaderStage:
9164                         fragment_shader_code = tested_shader_stage_code.c_str();
9165                         break;
9166
9167                 case geometryShaderStage:
9168                         geometry_shader_code = tested_shader_stage_code.c_str();
9169                         break;
9170
9171                 case tesselationControlShaderStage:
9172                         tesselation_control_shader_code = tested_shader_stage_code.c_str();
9173                         tesselation_evaluation_shader_code = boilerplate_tesselation_evaluation_shader_code;
9174                         break;
9175
9176                 case tesselationEvalutaionShaderStage:
9177                         tesselation_evaluation_shader_code = tested_shader_stage_code.c_str();
9178                         break;
9179
9180                 case vertexShaderStage:
9181                         vertex_shader_code = tested_shader_stage_code.c_str();
9182                         break;
9183
9184                 default:
9185                         TCU_FAIL("Invalid shader stage");
9186                 }
9187
9188                 /* Build program */
9189                 program_object_id =
9190                         BuildProgram(vertex_shader_code, tesselation_control_shader_code, tesselation_evaluation_shader_code,
9191                                                  geometry_shader_code, fragment_shader_code, &is_program_built);
9192
9193                 /* Check if program was built */
9194                 if (false == is_program_built)
9195                 {
9196                         throw tcu::InternalError("Failed to build program", "", __FILE__, __LINE__);
9197                 }
9198
9199                 /* Done */
9200                 return program_object_id;
9201         }
9202
9203         /** Create texture to test given shader stage
9204          *
9205          * Throws exception in case of any failure
9206          *
9207          * @param stage Stage id
9208          *
9209          * @return Texture id
9210          **/
9211         GLuint createTextureToTestShaderStage(shaderStage stage)
9212         {
9213                 GLenum                     error                          = glGetError();
9214                 const GLint                max_image_uniforms = getMaximumImageUniformsForStage(stage);
9215                 GLuint                     texture_id             = 0;
9216                 std::vector<GLint> texture_data;
9217
9218                 const GLsizei height = 2;
9219                 const GLsizei width  = max_image_uniforms;
9220
9221                 if (m_min_required_image_uniforms > max_image_uniforms)
9222                 {
9223                         return 0;
9224                 }
9225
9226                 /* Generate texture id */
9227                 glGenTextures(1, &texture_id);
9228                 GLU_EXPECT_NO_ERROR(glGetError(), "GenTextures");
9229
9230                 /* Bind texture */
9231                 glBindTexture(GL_TEXTURE_2D, texture_id);
9232                 error = glGetError();
9233                 if (GL_NO_ERROR != error)
9234                 {
9235                         glDeleteTextures(1, &texture_id);
9236                         GLU_EXPECT_NO_ERROR(error, "BindTexture");
9237                 }
9238
9239                 /* Prepare storage for texture data */
9240                 texture_data.resize(width * height);
9241                 for (GLint i = 0; i < max_image_uniforms; ++i)
9242                 {
9243                         texture_data[i]                 = getExpectedValue(i);
9244                         texture_data[i + width] = 0;
9245                 }
9246
9247                 /* Create first level of texture */
9248                 glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R32I, width, height, 0 /*border */, GL_RED_INTEGER, GL_INT,
9249                                          &texture_data[0]);
9250                 error = glGetError();
9251                 if (GL_NO_ERROR != error)
9252                 {
9253                         glDeleteTextures(1, &texture_id);
9254                         GLU_EXPECT_NO_ERROR(error, "TexImage2D");
9255                 }
9256
9257                 /* Make texture complete */
9258                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
9259                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
9260                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9261                 error = glGetError();
9262                 if (GL_NO_ERROR != error)
9263                 {
9264                         glDeleteTextures(1, &texture_id);
9265                         GLU_EXPECT_NO_ERROR(error, "TexParameteri");
9266                 }
9267
9268                 /* Done */
9269                 return texture_id;
9270         }
9271
9272         /** Get value of texel for image at given index
9273          *
9274          * @param index Index of image uniform
9275          *
9276          * @return Value of texel
9277          **/
9278         GLint getExpectedValue(GLint index)
9279         {
9280                 // To fix denorm issues with r32f, rg16f and r11f_g11f_b10f
9281                 // we set one bit in the exponent of each component of those pixel format
9282                 return 0x40104200 + index;
9283         }
9284
9285         /** Get name of uniform at given index
9286          *
9287          * @param index    Index of uniform
9288          * @param out_name Name of uniform
9289          **/
9290         void getImageUniformName(GLuint index, std::string& out_name)
9291         {
9292                 std::stringstream stream;
9293
9294                 writeImageUniformNameToStream(stream, index);
9295
9296                 out_name = stream.str();
9297         }
9298
9299         /** Get maximum number of image uniforms allowed for given shader stage
9300          *
9301          * @param stage Stage id
9302          *
9303          * @return Maximum allowed image uniforms
9304          **/
9305         GLint getMaximumImageUniformsForStage(shaderStage stage)
9306         {
9307                 GLint  max_image_uniforms = 0;
9308                 GLenum pname                      = 0;
9309
9310                 switch (stage)
9311                 {
9312                 case fragmentShaderStage:
9313                         pname = GL_MAX_FRAGMENT_IMAGE_UNIFORMS;
9314                         break;
9315
9316                 case geometryShaderStage:
9317                         pname = GL_MAX_GEOMETRY_IMAGE_UNIFORMS;
9318                         break;
9319
9320                 case tesselationControlShaderStage:
9321                         pname = GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS;
9322                         break;
9323
9324                 case tesselationEvalutaionShaderStage:
9325                         pname = GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS;
9326                         break;
9327
9328                 case vertexShaderStage:
9329                         pname = GL_MAX_VERTEX_IMAGE_UNIFORMS;
9330                         break;
9331
9332                 default:
9333                         TCU_FAIL("Invalid shader stage");
9334                 }
9335
9336                 glGetIntegerv(pname, &max_image_uniforms);
9337                 GLU_EXPECT_NO_ERROR(glGetError(), "GetIntegerv");
9338
9339                 return max_image_uniforms;
9340         }
9341
9342         /** Prepare source for tested shader stage
9343          *
9344          * @param stage    Stage id
9345          * @param out_code Source code
9346          **/
9347         void prepareShaderForTestedShaderStage(shaderStage stage, std::string& out_code)
9348         {
9349                 GLint                     max_image_uniforms    = getMaximumImageUniformsForStage(stage);
9350                 const char*               stage_specific_layout = "";
9351                 const char*               stage_specific_predicate = "true";
9352                 std::stringstream stream;
9353
9354                 if (m_min_required_image_uniforms > max_image_uniforms)
9355                 {
9356                         return;
9357                 }
9358
9359                 /* Expected result follows
9360                  *
9361                  * #version 400 core
9362                  * #extension GL_ARB_shader_image_load_store : require
9363                  *
9364                  * precision highp float;
9365                  *
9366                  * stage_specific_layout goes here
9367                  *
9368                  * Uniform declarations go here
9369                  *
9370                  * void main()
9371                  * {
9372                  *     const ivec2 row_0_coordinates(0, 0);
9373                  *     const ivec2 row_1_coordinates(0, 1);
9374                  *
9375                  *     For each index <0, GL_MAX_*_IMAGE_UNIFORMS>
9376                  *
9377                  *     vec4 loaded_value_0 = imageLoad(u_image_0, row_0_coordinates);
9378                  *
9379                  *     imageStore(u_image_0, row_0_coordinates, -loaded_value_0);
9380                  *     imageStore(u_image_0, row_1_coordinates, loaded_value_0);
9381                  * }
9382                  */
9383
9384                 /* Get piece of code specific for stage */
9385                 switch (stage)
9386                 {
9387                 case fragmentShaderStage:
9388                         break;
9389
9390                 case geometryShaderStage:
9391                         stage_specific_layout = "layout(points) in;\n"
9392                                                                         "layout(points, max_vertices = 1) out;\n"
9393                                                                         "\n";
9394                         break;
9395
9396                 case tesselationControlShaderStage:
9397                         stage_specific_layout = "layout(vertices = 4) out;\n"
9398                                                                         "\n";
9399                         stage_specific_predicate = "gl_InvocationID == 0";
9400                         break;
9401
9402                 case tesselationEvalutaionShaderStage:
9403                         stage_specific_layout = "layout(quads, equal_spacing, ccw) in;\n"
9404                                                                         "\n";
9405                         break;
9406
9407                 case vertexShaderStage:
9408                         break;
9409
9410                 default:
9411                         TCU_FAIL("Invalid shader stage");
9412                 }
9413
9414                 /* Preamble */
9415                 stream << "#version 400 core\n"
9416                                   "#extension GL_ARB_shader_image_load_store : require\n"
9417                                   "\n"
9418                                   "precision highp float;\n"
9419                                   "\n"
9420                            << stage_specific_layout;
9421
9422                 /* Image uniforms declarations */
9423                 for (GLint i = 0; i < max_image_uniforms; ++i)
9424                 {
9425                         stream << imageUniformDeclaration(i) << "\n";
9426                 }
9427
9428                 /* Main opening */
9429                 stream << "\n"
9430                                   "void main()\n"
9431                                   "{\n";
9432
9433                 stream << "    if (" << stage_specific_predicate << ")\n";
9434                 stream << "    {\n";
9435
9436                 /* imageLoad and imageStores for each uniform */
9437                 for (GLint i = 0; i < max_image_uniforms; ++i)
9438                 {
9439                         stream << "        " << coordinatesVariableDeclaration(i, 0) << "\n"
9440                                    << "        " << coordinatesVariableDeclaration(i, 1) << "\n"
9441                                    << "\n"
9442                                    << "        " << imageLoadCall(i) << "\n"
9443                                    << "\n"
9444                                    << "        " << imageStoreCall(i, 0) << "\n"
9445                                    << "        " << imageStoreCall(i, 1) << "\n";
9446
9447                         if (max_image_uniforms > i + 1)
9448                         {
9449                                 stream << "\n";
9450                         }
9451                 }
9452
9453                 stream << "    }\n";
9454
9455                 /* Main closing */
9456                 stream << "}\n\n";
9457
9458                 /* Done */
9459                 out_code = stream.str();
9460         }
9461
9462         /** Test given shader stage
9463          *
9464          * @param stage Stage id
9465          *
9466          * @return m_test_not_supported if shader stage does not support at least m_min_required_image_uniforms image uniforms;
9467          *         testFailed when test result is negative;
9468          *         m_test_passed when test result is positive;
9469          **/
9470         testResult testShaderStage(shaderStage stage)
9471         {
9472                 std::string                image_uniform_name;
9473                 static const GLint invalid_uniform_location = -1;
9474                 const GLint                max_image_uniforms           = getMaximumImageUniformsForStage(stage);
9475                 GLenum                     primitive_mode                       = GL_POINTS;
9476                 GLuint                     program_id                           = 0;
9477                 testResult                 result                                       = testPassed;
9478                 std::vector<GLint> texture_data;
9479                 GLuint                     texture_id = 0;
9480
9481                 static const GLuint height = 2;
9482                 const GLuint            width  = max_image_uniforms;
9483
9484                 const GLuint            positive_value_index = width;
9485                 static const GLuint negated_value_index  = 0;
9486
9487                 if (m_min_required_image_uniforms > max_image_uniforms)
9488                 {
9489                         return testNotSupported;
9490                 }
9491
9492                 /* Select program and texture ids for given stage */
9493                 switch (stage)
9494                 {
9495                 case fragmentShaderStage:
9496                         program_id = m_program_to_test_fs_stage_id;
9497                         texture_id = m_texture_to_test_fs_stage_id;
9498                         break;
9499
9500                 case geometryShaderStage:
9501                         program_id = m_program_to_test_gs_stage_id;
9502                         texture_id = m_texture_to_test_gs_stage_id;
9503                         break;
9504
9505                 case tesselationControlShaderStage:
9506                         primitive_mode = GL_PATCHES;
9507                         program_id       = m_program_to_test_tcs_stage_id;
9508                         texture_id       = m_texture_to_test_tcs_stage_id;
9509                         break;
9510
9511                 case tesselationEvalutaionShaderStage:
9512                         primitive_mode = GL_PATCHES;
9513                         program_id       = m_program_to_test_tes_stage_id;
9514                         texture_id       = m_texture_to_test_tes_stage_id;
9515                         break;
9516
9517                 case vertexShaderStage:
9518                         program_id = m_program_to_test_vs_stage_id;
9519                         texture_id = m_texture_to_test_vs_stage_id;
9520                         break;
9521
9522                 default:
9523                         TCU_FAIL("Invalid shader stage");
9524                 }
9525
9526                 /* Set program */
9527                 glUseProgram(program_id);
9528                 GLU_EXPECT_NO_ERROR(glGetError(), "UseProgram");
9529
9530                 /* Bind texture to image units */
9531                 for (GLint i = 0; i < max_image_uniforms; ++i)
9532                 {
9533                         imageFormatDetails format_details;
9534                         getImageUniformDeclarationDetails(i, format_details);
9535
9536                         glBindImageTexture(i /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
9537                                                            GL_READ_WRITE, format_details.m_image_unit_format);
9538                         GLU_EXPECT_NO_ERROR(glGetError(), "BindImageTexture");
9539                 }
9540
9541                 /* Set all image uniforms to corresponding image units */
9542                 for (GLint i = 0; i < max_image_uniforms; ++i)
9543                 {
9544                         /* Get name */
9545                         getImageUniformName(i, image_uniform_name);
9546
9547                         /* Get location */
9548                         GLint image_uniform_location = glGetUniformLocation(program_id, image_uniform_name.c_str());
9549                         GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
9550
9551                         if (invalid_uniform_location == image_uniform_location)
9552                         {
9553                                 throw tcu::InternalError("Uniform location is not available", image_uniform_name.c_str(), __FILE__,
9554                                                                                  __LINE__);
9555                         }
9556
9557                         /* Set uniform value */
9558                         glUniform1i(image_uniform_location, i /* image_unit */);
9559                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
9560                 }
9561
9562                 /* Execute draw */
9563                 glDrawArrays(primitive_mode, 0 /* first vertex */, 1 /* one vertex */);
9564                 GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
9565
9566                 glMemoryBarrier(GL_ALL_BARRIER_BITS);
9567
9568                 texture_data.resize(width * height);
9569
9570                 /* Get texture data */
9571                 glBindTexture(GL_TEXTURE_2D, texture_id);
9572                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
9573
9574                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_INT, &texture_data[0]);
9575                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
9576
9577                 /* Verify each image uniform */
9578                 for (GLint i = 0; i < max_image_uniforms; ++i)
9579                 {
9580                         imageFormatDetails format_details;
9581                         getImageUniformDeclarationDetails(i, format_details);
9582
9583                         if (false ==
9584                                 format_details.m_verification_routine(getExpectedValue(i), texture_data[positive_value_index + i],
9585                                                                                                           texture_data[negated_value_index + i]))
9586                         {
9587                                 m_context.getTestContext().getLog()
9588                                         << tcu::TestLog::Message << "Invalid result!"
9589                                         << " Image format: " << format_details.m_image_format << " Original value: "
9590                                         << "0x" << std::setw(8) << std::setfill('0') << std::setbase(16) << getExpectedValue(i)
9591                                         << " Copied value: "
9592                                         << "0x" << std::setw(8) << std::setfill('0') << std::setbase(16)
9593                                         << texture_data[positive_value_index + i] << " Negated value: "
9594                                         << "0x" << std::setw(8) << std::setfill('0') << std::setbase(16)
9595                                         << texture_data[negated_value_index + i] << tcu::TestLog::EndMessage;
9596
9597                                 result = testFailed;
9598                         }
9599                 }
9600
9601                 /* Done */
9602                 return result;
9603         }
9604
9605         /** Verifies if original_value, positive_value and negated_value match
9606          *
9607          * @tparam T Type used during verification process, it should match float values by size
9608          *
9609          * @param original_value Original value of texel, used when creating a texture
9610          * @param positive_value Value stored by shader as read
9611          * @param negated_value  Value stored by shader after negation
9612          *
9613          * @return true if values match, false otherwise
9614          **/
9615         template <typename T>
9616         static bool verifyFloat(GLint original_value, GLint positive_value, GLint negated_value)
9617         {
9618                 if (original_value != positive_value)
9619                 {
9620                         return false;
9621                 }
9622
9623                 static const GLuint n_elements            = sizeof(GLint) / sizeof(T); /* 1, 2, 4 */
9624                 static const GLuint sign_bit_index      = sizeof(T) * 8 - 1;               /* 7, 15, 31 */
9625                 static const T          sign_bit_mask    = 1 << sign_bit_index;    /* 0x80.. */
9626                 static const T          sign_bit_inv_mask = (T)~sign_bit_mask;             /* 0x7f.. */
9627
9628                 const T* positive_elements = (T*)&positive_value;
9629                 const T* negated_elements  = (T*)&negated_value;
9630
9631                 for (GLuint i = 0; i < n_elements; ++i)
9632                 {
9633                         const T positive_element = positive_elements[i];
9634                         const T negated_element  = negated_elements[i];
9635
9636                         const T positive_sign_bit = positive_element & sign_bit_mask;
9637                         const T negated_sign_bit  = negated_element & sign_bit_mask;
9638
9639                         const T positive_data = positive_element & sign_bit_inv_mask;
9640                         const T negated_data  = negated_element & sign_bit_inv_mask;
9641
9642                         /* Compare data bits */
9643                         if (positive_data != negated_data)
9644                         {
9645                                 return false;
9646                         }
9647
9648                         /* Verify that sign bit is inverted */
9649                         if (positive_sign_bit == negated_sign_bit)
9650                         {
9651                                 return false;
9652                         }
9653                 }
9654
9655                 return true;
9656         }
9657
9658         /** Verifies if original_value, positive_value and negated_value match
9659          *
9660          * @tparam T Type used during verification process, it should match float values by size
9661          *
9662          * @param original_value Original value of texel, used when creating a texture
9663          * @param positive_value Value stored by shader as read
9664          * @param negated_value  Value stored by shader after negation
9665          *
9666          * @return true if values match, false otherwise
9667          **/
9668         template <typename T>
9669         static bool verifyFloatSignedNorm(GLint original_value, GLint positive_value, GLint negated_value)
9670         {
9671                 if (original_value != positive_value)
9672                 {
9673                         return false;
9674                 }
9675
9676                 static const GLuint n_elements = sizeof(GLint) / sizeof(T); /* 1, 2, 4 */
9677
9678                 const T* positive_elements = (T*)&positive_value;
9679                 const T* negated_elements  = (T*)&negated_value;
9680
9681                 for (GLuint i = 0; i < n_elements; ++i)
9682                 {
9683                         const T positive_element = positive_elements[i];
9684                         const T negated_element  = negated_elements[i];
9685
9686                         /* Compare data bits */
9687                         if (positive_element != -negated_element)
9688                         {
9689                                 return false;
9690                         }
9691                 }
9692
9693                 return true;
9694         }
9695
9696         /** Verifies if original_value, positive_value and negated_value match
9697          *
9698          * @tparam R Number of bits for red channel
9699          * @tparam G Number of bits for green channel
9700          * @tparam B Number of bits for blue channel
9701          * @tparam A Number of bits for alpha channel
9702          *
9703          * @param original_value Original value of texel, used when creating a texture
9704          * @param positive_value Value stored by shader as read
9705          * @param negated_value  Value stored by shader after negation
9706          *
9707          * @return true if values match, false otherwise
9708          **/
9709         template <GLuint R, GLuint G, GLuint B, GLuint A, typename T>
9710         static bool verifyInteger(GLint original_value, GLint positive_value, GLint negated_value)
9711         {
9712                 if (original_value != positive_value)
9713                 {
9714                         return false;
9715                 }
9716
9717                 Integer<T, R, 0> positive_red(positive_value);
9718                 Integer<T, R, 0> negated_red(negated_value);
9719
9720                 Integer<T, G, R> positive_green(positive_value);
9721                 Integer<T, G, R> negated_green(negated_value);
9722
9723                 Integer<T, B, R + G> positive_blue(positive_value);
9724                 Integer<T, B, R + G> negated_blue(negated_value);
9725
9726                 Integer<T, A, R + G + B> positive_alpha(positive_value);
9727                 Integer<T, A, R + G + B> negated_alpha(negated_value);
9728
9729                 if (((0 != R) && (positive_red.GetNegated() != negated_red.Get())) ||
9730                         ((0 != B) && (positive_blue.GetNegated() != negated_blue.Get())) ||
9731                         ((0 != G) && (positive_green.GetNegated() != negated_green.Get())) ||
9732                         ((0 != A) && (positive_alpha.GetNegated() != negated_alpha.Get())))
9733                 {
9734                         return false;
9735                 }
9736
9737                 return true;
9738         }
9739
9740         /** Verifies if original_value, positive_value and negated_value match
9741          *
9742          * @param original_value Original value of texel, used when creating a texture
9743          * @param positive_value Value stored by shader as read
9744          * @param negated_value  Value stored by shader after negation
9745          *
9746          * @return true if values match, false otherwise
9747          **/
9748         static bool verifyInteger(GLint original_value, GLint positive_value, GLint negated_value)
9749         {
9750                 if (original_value != positive_value)
9751                 {
9752                         return false;
9753                 }
9754
9755                 if (positive_value != -negated_value)
9756                 {
9757                         return false;
9758                 }
9759
9760                 return true;
9761         }
9762
9763         /** Verifies if original_value, positive_value and negated_value match
9764          *
9765          * @param original_value Original value of texel, used when creating a texture
9766          * @param positive_value Value stored by shader as read
9767          * @param negated_value  Value stored by shader after negation
9768          *
9769          * @return true if values match, false otherwise
9770          **/
9771         template <typename T>
9772         static bool verifyFloatUnsigned(GLint original_value, GLint positive_value, GLint negated_value)
9773         {
9774                 if (original_value != positive_value)
9775                 {
9776                         return false;
9777                 }
9778
9779                 if (0 != negated_value)
9780                 {
9781                         return false;
9782                 }
9783
9784                 return true;
9785         }
9786 };
9787
9788 /** Test "Early fragment tests" description follows.
9789  *
9790  *  BasicGLSLEarlyFragTests verifies that:
9791  *  - early z test is applied when enabled,
9792  *  - early z test is not applied when disabled.
9793  *
9794  *  Proposed modifications:
9795  *  - verify that early z test does not discard all fragments when enabled,
9796  *  - verify that early stencil test is applied when enabled,
9797  *  - verify that early stencil test does not discard all fragments when
9798  *  enabled,
9799  *  - verify that early stencil test is not applied when disabled.
9800  *
9801  *  Steps:
9802  *  - prepare 2 programs that store 1.0 at red channel to image in fragment
9803  *  shader stage:
9804  *      a) one program should enable early fragment tests
9805  *      ("layout(early_fragment_tests) in;"),
9806  *      b) second program should disable early fragment tests,
9807  *  - prepare frame buffer with 64x64 R32F color and GL_DEPTH_STENCIL
9808  *  depth-stencil attachments,
9809  *  - prepare 2D texture 64x64 R32F,
9810  *  - enable depth test,
9811  *  - verify that early z test is applied when enabled:
9812  *      - use program enabling early fragment tests,
9813  *      - clean frame buffer with color: 0, stencil: 0 and depth 0.5,
9814  *      - fill texture with zeros,
9815  *      - bind texture to image uniform,
9816  *      - draw "full screen" quad (left bottom corner at -1,-1 and right top
9817  *      corner at 1,1) at z: 0.75
9818  *      - verify that texture is still filled with zeros,
9819  *  - verify that early z test does not discard all fragments:
9820  *      - use program enabling early fragment tests,
9821  *      - clean frame buffer with color: 0, stencil: 0 and depth 0.5,
9822  *      - fill texture with zeros,
9823  *      - bind texture to image uniform,
9824  *      - draw "full screen" quad at z: 0.25
9825  *      - verify that texture is now filled with 1.0,
9826  *  -verify that early z test is not applied when disabled:
9827  *      - use program disabling early fragment tests,
9828  *      - clean frame buffer with color: 0, stencil: 0 and depth 0.5,
9829  *      - fill texture with zeros,
9830  *      - bind texture to image uniform,
9831  *      - draw "full screen" quad at z: 0.75
9832  *      - verify that texture is now filled with 1.0.
9833  *  - disable depth test
9834  *  - enable stencil test
9835  *  - verify that early stencil test is applied when enabled:
9836  *      - use program enabling early fragment tests,
9837  *      - clean frame buffer with color: 0, stencil: 0 and depth 1,
9838  *      - fill texture with zeros,
9839  *      - set stencil test to:
9840  *          - <func> to GL_LESS,
9841  *          - <ref> to 128,
9842  *          - <mask> 0xffffffff,
9843  *      - bind texture to image uniform,
9844  *      - draw "full screen" quad at z: 0,
9845  *      - verify that texture is still filled with zeros,
9846  *  - verify that early stencil test does not discard all fragments:
9847  *      - use program enabling early fragment tests,
9848  *      - clean frame buffer with color: 0, stencil: 128 and depth 1,
9849  *      - fill texture with zeros,
9850  *      - set stencil test to:
9851  *          - <func> to GL_LESS,
9852  *          - <ref> to 0,
9853  *          - <mask> 0xffffffff,
9854  *      - bind texture to image uniform,
9855  *      - draw "full screen" quad at z: 0,
9856  *      - verify that texture is now filled with 1.0,
9857  *  - verify that early stencil test is not applied when disabled:
9858  *      - use program disabling early fragment tests,
9859  *      - clean frame buffer with color: 0, stencil: 0 and depth 1,
9860  *      - fill texture with zeros,
9861  *      - set stencil test to:
9862  *          - <func> to GL_LESS,
9863  *          - <ref> to 128,
9864  *          - <mask> 0xffffffff,
9865  *      - bind texture to image uniform,
9866  *      - draw "full screen" quad at z: 0,
9867  *      - verify that texture is now filled with 1.0
9868  **/
9869 class ImageLoadStoreEarlyFragmentTestsTest : public ShaderImageLoadStoreBase
9870 {
9871 private:
9872         /* Constants */
9873         GLuint                     m_image_edge;
9874         static const GLint m_invalid_uniform_location = -1;
9875
9876         /* Types */
9877         /** Store id and uniform locations for a single program object
9878          *
9879          **/
9880         struct programDetails
9881         {
9882                 GLint  m_depth_uniform_location;
9883                 GLint  m_image_uniform_location;
9884                 GLuint m_program_id;
9885
9886                 programDetails()
9887                         : m_depth_uniform_location(ImageLoadStoreEarlyFragmentTestsTest::m_invalid_uniform_location)
9888                         , m_image_uniform_location(ImageLoadStoreEarlyFragmentTestsTest::m_invalid_uniform_location)
9889                         , m_program_id(0)
9890                 {
9891                         /* Nothing to be done here */
9892                 }
9893         };
9894
9895         /* Fileds */
9896         /* Storage for texture data */
9897         std::vector<GLfloat> m_clean_texture_data;
9898         std::vector<GLfloat> m_extracted_texture_data;
9899
9900         /* Program details */
9901         programDetails m_disabled_early_tests;
9902         programDetails m_enabled_early_tests;
9903
9904         /* Ids of GL objects */
9905         GLuint m_color_renderbuffer_id;
9906         GLuint m_depth_stencil_renderbuffer_id;
9907         GLuint m_framebuffer_id;
9908         GLuint m_texture_id;
9909         GLuint m_vertex_array_object_id;
9910
9911 public:
9912         /* Constructor */
9913         ImageLoadStoreEarlyFragmentTestsTest()
9914                 : m_image_edge(0)
9915                 , m_color_renderbuffer_id(0)
9916                 , m_depth_stencil_renderbuffer_id(0)
9917                 , m_framebuffer_id(0)
9918                 , m_texture_id(0)
9919                 , m_vertex_array_object_id(0)
9920         {
9921                 /* Nothing to be done here */
9922         }
9923
9924         /* Methods inherited from SubcaseBase */
9925         virtual long Cleanup()
9926         {
9927                 /* Restore defaults */
9928                 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
9929                 glBindRenderbuffer(GL_RENDERBUFFER, 0);
9930                 glBindTexture(GL_TEXTURE_2D, 0);
9931                 glBindVertexArray(0);
9932                 glDisable(GL_DEPTH_TEST);
9933                 glDisable(GL_STENCIL_TEST);
9934                 glUseProgram(0);
9935
9936                 /* Delete objects */
9937                 if (0 != m_disabled_early_tests.m_program_id)
9938                 {
9939                         glDeleteProgram(m_disabled_early_tests.m_program_id);
9940                         m_disabled_early_tests.m_program_id = 0;
9941                 }
9942
9943                 if (0 != m_enabled_early_tests.m_program_id)
9944                 {
9945                         glDeleteProgram(m_enabled_early_tests.m_program_id);
9946                         m_enabled_early_tests.m_program_id = 0;
9947                 }
9948
9949                 if (0 != m_color_renderbuffer_id)
9950                 {
9951                         glDeleteRenderbuffers(1, &m_color_renderbuffer_id);
9952                         m_color_renderbuffer_id = 0;
9953                 }
9954
9955                 if (0 != m_depth_stencil_renderbuffer_id)
9956                 {
9957                         glDeleteRenderbuffers(1, &m_depth_stencil_renderbuffer_id);
9958                         m_depth_stencil_renderbuffer_id = 0;
9959                 }
9960
9961                 if (0 != m_framebuffer_id)
9962                 {
9963                         glDeleteFramebuffers(1, &m_framebuffer_id);
9964                         m_framebuffer_id = 0;
9965                 }
9966
9967                 if (0 != m_texture_id)
9968                 {
9969                         glDeleteTextures(1, &m_texture_id);
9970                         m_texture_id = 0;
9971                 }
9972
9973                 if (0 != m_vertex_array_object_id)
9974                 {
9975                         glDeleteVertexArrays(1, &m_vertex_array_object_id);
9976                         m_vertex_array_object_id = 0;
9977                 }
9978
9979                 /* Done */
9980                 return NO_ERROR;
9981         }
9982
9983         virtual long Run()
9984         {
9985                 bool result = true;
9986
9987                 /* Bind texture to first image unit */
9988                 glBindImageTexture(0 /* first image unit */, m_texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
9989                                                    GL_READ_WRITE, GL_R32F);
9990                 GLU_EXPECT_NO_ERROR(glGetError(), "BindImageTexture");
9991
9992                 /* Run tests for depth test */
9993                 if (false == testEarlyZ())
9994                 {
9995                         result = false;
9996                 }
9997
9998                 /* Run tests for stencil test */
9999                 if (false == testEarlyStencil())
10000                 {
10001                         result = false;
10002                 }
10003
10004                 /* Return ERROR if any problem was found */
10005                 if (false == result)
10006                 {
10007                         return ERROR;
10008                 }
10009
10010                 /* Done */
10011                 return NO_ERROR;
10012         }
10013
10014         virtual long Setup()
10015         {
10016                 m_image_edge = de::min(64, de::min(getWindowHeight(), getWindowWidth()));
10017
10018                 /* Prepare storage for texture data */
10019                 m_clean_texture_data.resize(m_image_edge * m_image_edge);
10020                 m_extracted_texture_data.resize(m_image_edge * m_image_edge);
10021
10022                 /* Prepare programs, framebuffer and texture */
10023                 buildPrograms();
10024                 createFramebuffer();
10025                 createTexture();
10026
10027                 /* Generate vertex array object */
10028                 glGenVertexArrays(1, &m_vertex_array_object_id);
10029                 GLU_EXPECT_NO_ERROR(glGetError(), "GenVertexArrays");
10030
10031                 /* Bind vertex array object */
10032                 glBindVertexArray(m_vertex_array_object_id);
10033                 GLU_EXPECT_NO_ERROR(glGetError(), "BindVertexArray");
10034
10035                 /* Set clear color */
10036                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
10037                 GLU_EXPECT_NO_ERROR(glGetError(), "ClearColor");
10038
10039                 /* Done */
10040                 return NO_ERROR;
10041         }
10042
10043 private:
10044         /** Build two programs: with enabled and disabled early fragment tests
10045          *
10046          **/
10047         void buildPrograms()
10048         {
10049                 static const char* const fragment_shader_with_disabled_early_tests =
10050                         "#version 400 core\n"
10051                         "#extension GL_ARB_shader_image_load_store : require\n"
10052                         "\n"
10053                         "precision highp float;\n"
10054                         "\n"
10055                         "layout(r32f) uniform image2D u_image;\n"
10056                         "\n"
10057                         "void main()\n"
10058                         "{\n"
10059                         "    vec4 color = vec4(1.0, 0, 0, 0);\n"
10060                         "\n"
10061                         "    imageStore(u_image, ivec2(gl_FragCoord.xy), color);\n"
10062                         "\n"
10063                         "    discard;\n"
10064                         "}\n\n";
10065
10066                 static const char* const fragment_shader_with_enabled_early_tests =
10067                         "#version 400 core\n"
10068                         "#extension GL_ARB_shader_image_load_store : require\n"
10069                         "\n"
10070                         "precision highp float;\n"
10071                         "\n"
10072                         "layout(early_fragment_tests) in;\n"
10073                         "\n"
10074                         "layout(r32f) uniform image2D u_image;\n"
10075                         "\n"
10076                         "void main()\n"
10077                         "{\n"
10078                         "    vec4 color = vec4(1.0, 0, 0, 0);\n"
10079                         "\n"
10080                         "    imageStore(u_image, ivec2(gl_FragCoord.xy), color);\n"
10081                         "\n"
10082                         "    discard;\n"
10083                         "}\n\n";
10084
10085                 static const char* const geometry_shader_code = "#version 400 core\n"
10086                                                                                                                 "#extension GL_ARB_shader_image_load_store : require\n"
10087                                                                                                                 "\n"
10088                                                                                                                 "precision highp float;\n"
10089                                                                                                                 "\n"
10090                                                                                                                 "layout(points)                           in;\n"
10091                                                                                                                 "layout(triangle_strip, max_vertices = 4) out;\n"
10092                                                                                                                 "\n"
10093                                                                                                                 "uniform float u_depth;\n"
10094                                                                                                                 "\n"
10095                                                                                                                 "void main()\n"
10096                                                                                                                 "{\n"
10097                                                                                                                 "    // Left-bottom\n"
10098                                                                                                                 "    gl_Position = vec4(-1, -1, u_depth, 1);\n"
10099                                                                                                                 "    EmitVertex();\n"
10100                                                                                                                 "\n"
10101                                                                                                                 "    // Left-top\n"
10102                                                                                                                 "    gl_Position = vec4(-1,  1, u_depth, 1);\n"
10103                                                                                                                 "    EmitVertex();\n"
10104                                                                                                                 "\n"
10105                                                                                                                 "    // Right-bottom\n"
10106                                                                                                                 "    gl_Position = vec4( 1, -1, u_depth, 1);\n"
10107                                                                                                                 "    EmitVertex();\n"
10108                                                                                                                 "\n"
10109                                                                                                                 "    // Right-top\n"
10110                                                                                                                 "    gl_Position = vec4( 1,  1, u_depth, 1);\n"
10111                                                                                                                 "    EmitVertex();\n"
10112                                                                                                                 "}\n\n";
10113
10114                 static const char* const vertex_shader_code = "#version 400 core\n"
10115                                                                                                           "#extension GL_ARB_shader_image_load_store : require\n"
10116                                                                                                           "\n"
10117                                                                                                           "precision highp float;\n"
10118                                                                                                           "\n"
10119                                                                                                           "void main()\n"
10120                                                                                                           "{\n"
10121                                                                                                           "}\n\n";
10122
10123                 prepareProgramDetails(fragment_shader_with_disabled_early_tests, geometry_shader_code, vertex_shader_code,
10124                                                           m_disabled_early_tests);
10125
10126                 prepareProgramDetails(fragment_shader_with_enabled_early_tests, geometry_shader_code, vertex_shader_code,
10127                                                           m_enabled_early_tests);
10128         }
10129
10130         /** Fill texture with zeros
10131          *
10132          **/
10133         void cleanTexture()
10134         {
10135                 glTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, m_image_edge, m_image_edge,
10136                                                 GL_RED, GL_FLOAT, &m_clean_texture_data[0]);
10137                 GLU_EXPECT_NO_ERROR(glGetError(), "TexSubImage2D");
10138         }
10139
10140         /** Create and bind (draw) framebuffer with color and depth-stencil attachments
10141          *
10142          **/
10143         void createFramebuffer()
10144         {
10145                 /* Generate render buffers */
10146                 glGenRenderbuffers(1, &m_color_renderbuffer_id);
10147                 GLU_EXPECT_NO_ERROR(glGetError(), "GenRenderbuffers");
10148
10149                 glGenRenderbuffers(1, &m_depth_stencil_renderbuffer_id);
10150                 GLU_EXPECT_NO_ERROR(glGetError(), "GenRenderbuffers");
10151
10152                 /* Generate and bind framebuffer object */
10153                 glGenFramebuffers(1, &m_framebuffer_id);
10154                 GLU_EXPECT_NO_ERROR(glGetError(), "GenFramebuffers");
10155
10156                 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_framebuffer_id);
10157                 GLU_EXPECT_NO_ERROR(glGetError(), "BindFramebuffer");
10158
10159                 /* Prepare color render buffer */
10160                 glBindRenderbuffer(GL_RENDERBUFFER, m_color_renderbuffer_id);
10161                 GLU_EXPECT_NO_ERROR(glGetError(), "BindRenderbuffer");
10162
10163                 glRenderbufferStorage(GL_RENDERBUFFER, GL_R32F, m_image_edge, m_image_edge);
10164                 GLU_EXPECT_NO_ERROR(glGetError(), "RenderbufferStorage");
10165
10166                 /* Set up color attachment */
10167                 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_renderbuffer_id);
10168                 GLU_EXPECT_NO_ERROR(glGetError(), "FramebufferRenderbuffer");
10169
10170                 /* Prepare depth-stencil render buffer */
10171                 glBindRenderbuffer(GL_RENDERBUFFER, m_depth_stencil_renderbuffer_id);
10172                 GLU_EXPECT_NO_ERROR(glGetError(), "BindRenderbuffer");
10173
10174                 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_image_edge, m_image_edge);
10175                 GLU_EXPECT_NO_ERROR(glGetError(), "RenderbufferStorage");
10176
10177                 /* Set up depth-stencil attachment */
10178                 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
10179                                                                   m_depth_stencil_renderbuffer_id);
10180                 GLU_EXPECT_NO_ERROR(glGetError(), "FramebufferRenderbuffer");
10181         }
10182
10183         /** Create 2D R32F texture
10184          *
10185          **/
10186         void createTexture()
10187         {
10188                 glGenTextures(1, &m_texture_id);
10189                 GLU_EXPECT_NO_ERROR(glGetError(), "GenTextures");
10190
10191                 glBindTexture(GL_TEXTURE_2D, m_texture_id);
10192                 GLU_EXPECT_NO_ERROR(glGetError(), "BindTexture");
10193
10194                 glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, m_image_edge, m_image_edge);
10195                 GLU_EXPECT_NO_ERROR(glGetError(), "TexStorage2D");
10196         }
10197
10198         /** Extracts red channel from texture and verify if all texels are set to specified value
10199          *
10200          * @param value Expected value
10201          *
10202          * @return true if all texel match expected value, false otherwise
10203          **/
10204         bool isTextureFilledWithValue(GLfloat value)
10205         {
10206                 glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, &m_extracted_texture_data[0]);
10207                 GLU_EXPECT_NO_ERROR(glGetError(), "GetTexImage");
10208
10209                 for (GLuint i = 0; i < m_image_edge * m_image_edge; ++i)
10210                 {
10211                         if (value != m_extracted_texture_data[i])
10212                         {
10213                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Texel at location " << i
10214                                                                                                         << " has invalid value: " << m_extracted_texture_data[i]
10215                                                                                                         << " expected: " << value << tcu::TestLog::EndMessage;
10216
10217                                 return false;
10218                         }
10219                 }
10220
10221                 return true;
10222         }
10223
10224         /** Build program, extract location of uniforms and store results in programDetails instance
10225          *
10226          * Throws tcu::InternalError if uniforms are inactive
10227          *
10228          * @param fragment_shader_code Source of fragment shader
10229          * @param geometry_shader_code Source of geometry shader
10230          * @param vertex_shader_code   Source of vertex shader
10231          * @param out_program_details  Instance of programDetails
10232          **/
10233         void prepareProgramDetails(const char* fragment_shader_code, const char* geometry_shader_code,
10234                                                            const char* vertex_shader_code, programDetails& out_program_details)
10235         {
10236                 static const char* const depth_uniform_name = "u_depth";
10237                 static const char* const image_uniform_name = "u_image";
10238                 bool                                     is_program_built   = true;
10239
10240                 GLuint program_id = BuildProgram(vertex_shader_code, 0 /* src_tcs */, 0 /* src_tes */, geometry_shader_code,
10241                                                                                  fragment_shader_code, &is_program_built);
10242
10243                 if (false == is_program_built)
10244                 {
10245                         throw tcu::InternalError("Failed to build program", "", __FILE__, __LINE__);
10246                 }
10247
10248                 /* Get depth uniform location */
10249                 GLint depth_uniform_location = glGetUniformLocation(program_id, depth_uniform_name);
10250                 GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
10251
10252                 if (m_invalid_uniform_location == depth_uniform_location)
10253                 {
10254                         throw tcu::InternalError("Uniform is not active", image_uniform_name, __FILE__, __LINE__);
10255                 }
10256
10257                 /* Get image uniform location */
10258                 GLint image_uniform_location = glGetUniformLocation(program_id, image_uniform_name);
10259                 GLU_EXPECT_NO_ERROR(glGetError(), "GetUniformLocation");
10260
10261                 if (m_invalid_uniform_location == image_uniform_location)
10262                 {
10263                         throw tcu::InternalError("Uniform is not active", image_uniform_name, __FILE__, __LINE__);
10264                 }
10265
10266                 /* Store results */
10267                 out_program_details.m_depth_uniform_location = depth_uniform_location;
10268                 out_program_details.m_image_uniform_location = image_uniform_location;
10269                 out_program_details.m_program_id                         = program_id;
10270         }
10271
10272         /** Test if early fragment stencil test works as expected.
10273          *
10274          * @return true if successful, false otherwise
10275          **/
10276         bool testEarlyStencil()
10277         {
10278                 bool result = true;
10279
10280                 glEnable(GL_STENCIL_TEST);
10281                 GLU_EXPECT_NO_ERROR(glGetError(), "glEnable");
10282
10283                 glClearDepthf(1.0f);
10284                 GLU_EXPECT_NO_ERROR(glGetError(), "ClearDepthf");
10285
10286                 /* verify that early stencil test is applied when enabled */
10287                 {
10288                         glUseProgram(m_enabled_early_tests.m_program_id);
10289                         GLU_EXPECT_NO_ERROR(glGetError(), "glUseProgram");
10290
10291                         glClearStencil(0);
10292                         GLU_EXPECT_NO_ERROR(glGetError(), "ClearStencil");
10293
10294                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10295                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10296
10297                         cleanTexture();
10298
10299                         glStencilFunc(GL_LESS, 128, 0xffffffff);
10300                         GLU_EXPECT_NO_ERROR(glGetError(), "StencilFunc");
10301
10302                         glUniform1i(m_enabled_early_tests.m_image_uniform_location, 0 /* first unit */);
10303                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
10304
10305                         glUniform1f(m_enabled_early_tests.m_depth_uniform_location, 0.0f /* depth */);
10306                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1f");
10307
10308                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10309                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10310
10311                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10312                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10313
10314                         if (false == isTextureFilledWithValue(0.0f))
10315                         {
10316                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
10317                                                                                                         << "Problem with early stencil test. It is not applied"
10318                                                                                                         << tcu::TestLog::EndMessage;
10319
10320                                 result = false;
10321                         }
10322                 }
10323
10324                 /* verify that early stencil test does not discard all fragments */
10325                 {
10326                         glClearStencil(128);
10327                         GLU_EXPECT_NO_ERROR(glGetError(), "ClearStencil");
10328
10329                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10330                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10331
10332                         cleanTexture();
10333
10334                         glStencilFunc(GL_LESS, 0, 0xffffffff);
10335                         GLU_EXPECT_NO_ERROR(glGetError(), "StencilFunc");
10336
10337                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10338                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10339
10340                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10341                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10342
10343                         if (false == isTextureFilledWithValue(1.0f))
10344                         {
10345                                 m_context.getTestContext().getLog()
10346                                         << tcu::TestLog::Message
10347                                         << "Problem with early stencil test. It discards fragments, that shall be drawn"
10348                                         << tcu::TestLog::EndMessage;
10349
10350                                 result = false;
10351                         }
10352                 }
10353
10354                 /* verify that early stencil test is not applied when disabled */
10355                 {
10356                         glUseProgram(m_disabled_early_tests.m_program_id);
10357                         GLU_EXPECT_NO_ERROR(glGetError(), "glUseProgram");
10358
10359                         glClearStencil(0);
10360                         GLU_EXPECT_NO_ERROR(glGetError(), "ClearStencil");
10361
10362                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10363                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10364
10365                         cleanTexture();
10366
10367                         glStencilFunc(GL_LESS, 128, 0xffffffff);
10368                         GLU_EXPECT_NO_ERROR(glGetError(), "StencilFunc");
10369
10370                         glUniform1i(m_disabled_early_tests.m_image_uniform_location, 0 /* first unit */);
10371                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
10372
10373                         glUniform1f(m_disabled_early_tests.m_depth_uniform_location, 0.0f /* depth */);
10374                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1f");
10375
10376                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10377                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10378
10379                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10380                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10381
10382                         if (false == isTextureFilledWithValue(1.0f))
10383                         {
10384                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
10385                                                                                                         << "Problem with early stencil test. It is applied when disabled"
10386                                                                                                         << tcu::TestLog::EndMessage;
10387
10388                                 result = false;
10389                         }
10390                 }
10391
10392                 glDisable(GL_STENCIL_TEST);
10393                 GLU_EXPECT_NO_ERROR(glGetError(), "Disable");
10394
10395                 /* Done */
10396                 return result;
10397         }
10398
10399         /** Test if early fragment depth test works as expected.
10400          *
10401          * @return true if successful, false otherwise
10402          **/
10403         bool testEarlyZ()
10404         {
10405                 bool result = true;
10406
10407                 glEnable(GL_DEPTH_TEST);
10408                 GLU_EXPECT_NO_ERROR(glGetError(), "glEnable");
10409
10410                 glClearDepthf(0.5f);
10411                 GLU_EXPECT_NO_ERROR(glGetError(), "ClearDepthf");
10412
10413                 glClearStencil(0);
10414                 GLU_EXPECT_NO_ERROR(glGetError(), "ClearStencil");
10415
10416                 /* verify that early z test is applied when enabled */
10417                 {
10418                         glUseProgram(m_enabled_early_tests.m_program_id);
10419                         GLU_EXPECT_NO_ERROR(glGetError(), "glUseProgram");
10420
10421                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10422                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10423
10424                         cleanTexture();
10425
10426                         glUniform1i(m_enabled_early_tests.m_image_uniform_location, 0 /* first unit */);
10427                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
10428
10429                         glUniform1f(m_enabled_early_tests.m_depth_uniform_location, 0.5f /* depth */);
10430                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1f");
10431
10432                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10433                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10434
10435                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10436                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10437
10438                         if (false == isTextureFilledWithValue(0.0f))
10439                         {
10440                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
10441                                                                                                         << "Problem with early z test. It is not applied"
10442                                                                                                         << tcu::TestLog::EndMessage;
10443
10444                                 result = false;
10445                         }
10446                 }
10447
10448                 /* verify that early z test does not discard all fragments */
10449                 {
10450                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10451                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10452
10453                         cleanTexture();
10454
10455                         glUniform1i(m_enabled_early_tests.m_image_uniform_location, 0 /* first unit */);
10456                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
10457
10458                         glUniform1f(m_enabled_early_tests.m_depth_uniform_location, -0.5f /* depth */);
10459                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1f");
10460
10461                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10462                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10463
10464                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10465                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10466
10467                         if (false == isTextureFilledWithValue(1.0f))
10468                         {
10469                                 m_context.getTestContext().getLog()
10470                                         << tcu::TestLog::Message << "Problem with early z test. It discards fragments, that shall be drawn"
10471                                         << tcu::TestLog::EndMessage;
10472
10473                                 result = false;
10474                         }
10475                 }
10476
10477                 /* verify that early z test is not applied when disabled */
10478                 {
10479                         glUseProgram(m_disabled_early_tests.m_program_id);
10480                         GLU_EXPECT_NO_ERROR(glGetError(), "glUseProgram");
10481
10482                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
10483                         GLU_EXPECT_NO_ERROR(glGetError(), "Clear");
10484
10485                         cleanTexture();
10486
10487                         glUniform1i(m_disabled_early_tests.m_image_uniform_location, 0 /* first unit */);
10488                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1i");
10489
10490                         glUniform1f(m_disabled_early_tests.m_depth_uniform_location, 0.5f /* depth */);
10491                         GLU_EXPECT_NO_ERROR(glGetError(), "Uniform1f");
10492
10493                         glDrawArrays(GL_POINTS, 0 /* first */, 1 /* number of vertices */);
10494                         GLU_EXPECT_NO_ERROR(glGetError(), "DrawArrays");
10495
10496                         glMemoryBarrier(GL_ALL_BARRIER_BITS);
10497                         GLU_EXPECT_NO_ERROR(glGetError(), "MemoryBarrier");
10498
10499                         if (false == isTextureFilledWithValue(1.0f))
10500                         {
10501                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
10502                                                                                                         << "Problem with early z test. It is applied when disabled"
10503                                                                                                         << tcu::TestLog::EndMessage;
10504
10505                                 result = false;
10506                         }
10507                 }
10508
10509                 glDisable(GL_DEPTH_TEST);
10510                 GLU_EXPECT_NO_ERROR(glGetError(), "Disable");
10511
10512                 /* Done */
10513                 return result;
10514         }
10515 };
10516
10517 //-----------------------------------------------------------------------------
10518 // 4.1 NegativeUniform
10519 //-----------------------------------------------------------------------------
10520 class NegativeUniform : public ShaderImageLoadStoreBase
10521 {
10522         GLuint m_program;
10523
10524         virtual long Setup()
10525         {
10526                 m_program = 0;
10527                 return NO_ERROR;
10528         }
10529
10530         virtual long Run()
10531         {
10532                 const char* glsl_vs = "#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL
10533                                                           "  gl_Position = i_position;" NL "}";
10534                 const char* glsl_fs = "#version 420 core" NL "writeonly uniform image2D g_image;" NL "void main() {" NL
10535                                                           "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image, coord, vec4(0.0));" NL
10536                                                           "  discard;" NL "}";
10537                 m_program = BuildProgram(glsl_vs, NULL, NULL, NULL, glsl_fs);
10538
10539                 GLint max_image_units;
10540                 glGetIntegerv(GL_MAX_IMAGE_UNITS, &max_image_units);
10541                 glUseProgram(m_program);
10542
10543                 glUniform1i(glGetUniformLocation(m_program, "g_image"), -1);
10544                 if (glGetError() != GL_INVALID_VALUE)
10545                 {
10546                         m_context.getTestContext().getLog()
10547                                 << tcu::TestLog::Message << "glUniform1i should generate INVALID_VALUE when <value> is less than zero."
10548                                 << tcu::TestLog::EndMessage;
10549                         return ERROR;
10550                 }
10551                 glUniform1i(glGetUniformLocation(m_program, "g_image"), max_image_units);
10552                 if (glGetError() != GL_INVALID_VALUE)
10553                 {
10554                         m_context.getTestContext().getLog()
10555                                 << tcu::TestLog::Message
10556                                 << "glUniform1i should generate INVALID_VALUE when <value> is greater than or equal to the value of "
10557                                 << "MAX_IMAGE_UNITS." << tcu::TestLog::EndMessage;
10558                         return ERROR;
10559                 }
10560
10561                 GLint i = -3;
10562                 glUniform1iv(glGetUniformLocation(m_program, "g_image"), 1, &i);
10563                 if (glGetError() != GL_INVALID_VALUE)
10564                 {
10565                         m_context.getTestContext().getLog()
10566                                 << tcu::TestLog::Message << "glUniform1iv should generate INVALID_VALUE when <value> is less than zero."
10567                                 << tcu::TestLog::EndMessage;
10568                         return ERROR;
10569                 }
10570                 i = max_image_units + 1;
10571                 glUniform1iv(glGetUniformLocation(m_program, "g_image"), 1, &i);
10572                 if (glGetError() != GL_INVALID_VALUE)
10573                 {
10574                         m_context.getTestContext().getLog()
10575                                 << tcu::TestLog::Message << "glUniform1iv should generate INVALID_VALUE when <value> is greater "
10576                                                                                         "than or equal to the value of MAX_IMAGE_UNITS."
10577                                 << tcu::TestLog::EndMessage;
10578                         return ERROR;
10579                 }
10580
10581                 glUniform1ui(glGetUniformLocation(m_program, "g_image"), 0);
10582                 if (glGetError() != GL_INVALID_OPERATION)
10583                 {
10584                         m_context.getTestContext().getLog()
10585                                 << tcu::TestLog::Message
10586                                 << "glUniform1iv should generate INVALID_OPERATION if the location refers to an image variable."
10587                                 << tcu::TestLog::EndMessage;
10588                         return ERROR;
10589                 }
10590                 glUniform2i(glGetUniformLocation(m_program, "g_image"), 0, 0);
10591                 if (glGetError() != GL_INVALID_OPERATION)
10592                 {
10593                         m_context.getTestContext().getLog()
10594                                 << tcu::TestLog::Message
10595                                 << "glUniform2i should generate INVALID_OPERATION if the location refers to an image variable."
10596                                 << tcu::TestLog::EndMessage;
10597                         return ERROR;
10598                 }
10599
10600                 {
10601                         glUseProgram(0);
10602
10603                         glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image"), -1);
10604                         if (glGetError() != GL_INVALID_VALUE)
10605                         {
10606                                 m_context.getTestContext().getLog()
10607                                         << tcu::TestLog::Message
10608                                         << "glProgramUniform1i should generate INVALID_VALUE when <value> is less than zero."
10609                                         << tcu::TestLog::EndMessage;
10610                                 return ERROR;
10611                         }
10612                         glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image"), max_image_units);
10613                         if (glGetError() != GL_INVALID_VALUE)
10614                         {
10615                                 m_context.getTestContext().getLog()
10616                                         << tcu::TestLog::Message
10617                                         << "glProgramUniform1i should generate INVALID_VALUE when <value> is greater than or equal to the "
10618                                            "value of MAX_IMAGE_UNITS."
10619                                         << tcu::TestLog::EndMessage;
10620                                 return ERROR;
10621                         }
10622
10623                         GLint ii = -3;
10624                         glProgramUniform1iv(m_program, glGetUniformLocation(m_program, "g_image"), 1, &ii);
10625                         if (glGetError() != GL_INVALID_VALUE)
10626                         {
10627                                 m_context.getTestContext().getLog()
10628                                         << tcu::TestLog::Message
10629                                         << "glProgramUniform1iv should generate INVALID_VALUE when <value> is less than zero."
10630                                         << tcu::TestLog::EndMessage;
10631                                 return ERROR;
10632                         }
10633                         ii = max_image_units + 1;
10634                         glProgramUniform1iv(m_program, glGetUniformLocation(m_program, "g_image"), 1, &ii);
10635                         if (glGetError() != GL_INVALID_VALUE)
10636                         {
10637                                 m_context.getTestContext().getLog()
10638                                         << tcu::TestLog::Message << "glProgramUniform1iv should generate INVALID_VALUE when <value> "
10639                                                                                                 "is greater than or equal to the value of MAX_IMAGE_UNITS."
10640                                         << tcu::TestLog::EndMessage;
10641                                 return ERROR;
10642                         }
10643
10644                         glProgramUniform1ui(m_program, glGetUniformLocation(m_program, "g_image"), 0);
10645                         if (glGetError() != GL_INVALID_OPERATION)
10646                         {
10647                                 m_context.getTestContext().getLog()
10648                                         << tcu::TestLog::Message << "glProgramUniform1ui should generate INVALID_OPERATION if the "
10649                                                                                                 "location refers to an image variable."
10650                                         << tcu::TestLog::EndMessage;
10651                                 return ERROR;
10652                         }
10653                         glProgramUniform2i(m_program, glGetUniformLocation(m_program, "g_image"), 0, 0);
10654                         if (glGetError() != GL_INVALID_OPERATION)
10655                         {
10656                                 m_context.getTestContext().getLog()
10657                                         << tcu::TestLog::Message << "glProgramUniform2i should generate INVALID_OPERATION if the "
10658                                                                                                 "location refers to an image variable."
10659                                         << tcu::TestLog::EndMessage;
10660                                 return ERROR;
10661                         }
10662                 }
10663
10664                 return NO_ERROR;
10665         }
10666
10667         virtual long Cleanup()
10668         {
10669                 glUseProgram(0);
10670                 glDeleteProgram(m_program);
10671                 return NO_ERROR;
10672         }
10673 };
10674 //-----------------------------------------------------------------------------
10675 // 4.2 NegativeBind
10676 //-----------------------------------------------------------------------------
10677 class NegativeBind : public ShaderImageLoadStoreBase
10678 {
10679         virtual long Setup()
10680         {
10681                 return NO_ERROR;
10682         }
10683
10684         virtual long Run()
10685         {
10686                 glBindImageTexture(100, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA);
10687                 if (glGetError() != GL_INVALID_VALUE)
10688                 {
10689                         m_context.getTestContext().getLog()
10690                                 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <unit> is "
10691                                                                                         "greater than or equal to the value of MAX_IMAGE_UNITS."
10692                                 << tcu::TestLog::EndMessage;
10693                         return ERROR;
10694                 }
10695
10696                 glBindImageTexture(0, 123, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA);
10697                 if (glGetError() != GL_INVALID_VALUE)
10698                 {
10699                         m_context.getTestContext().getLog()
10700                                 << tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <texture> is not "
10701                                                                                         "the name of an existing texture object."
10702                                 << tcu::TestLog::EndMessage;
10703                         return ERROR;
10704                 }
10705
10706                 glBindImageTexture(1, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA + 1234);
10707                 if (glGetError() != GL_INVALID_VALUE)
10708                 {
10709                         m_context.getTestContext().getLog()
10710                                 << tcu::TestLog::Message
10711                                 << "BindImageTexture should generate INVALID_VALUE if <format> is not a legal format."
10712                                 << tcu::TestLog::EndMessage;
10713                         return ERROR;
10714                 }
10715                 return NO_ERROR;
10716         }
10717
10718         virtual long Cleanup()
10719         {
10720                 return NO_ERROR;
10721         }
10722 };
10723 //-----------------------------------------------------------------------------
10724 // 4.3 NegativeCompileErrors
10725 //-----------------------------------------------------------------------------
10726 class NegativeCompileErrors : public ShaderImageLoadStoreBase
10727 {
10728         virtual long Run()
10729         {
10730                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10731                                          "layout(rgba32f) writeonly readonly uniform image2D g_image;" NL "void main() {" NL
10732                                          "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
10733                         return ERROR;
10734
10735                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10736                                          "layout(rgba32f) writeonly uniform image2D g_image;" NL "void main() {" NL
10737                                          "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
10738                         return ERROR;
10739
10740                 if (!Compile("#version 420 core" NL "in vec4 i_color;" NL "layout(location = 0) out vec4 o_color;" NL
10741                                          "layout(rgba32f) readonly uniform image2D g_image;" NL "void main() {" NL
10742                                          "  imageStore(g_image, ivec2(0), i_color);" NL "  o_color = i_color;" NL "}"))
10743                         return ERROR;
10744
10745                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL "uniform image2D g_image;" NL
10746                                          "void main() {" NL "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
10747                         return ERROR;
10748
10749                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10750                                          "readonly uniform image2D g_image;" NL "void main() {" NL
10751                                          "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
10752                         return ERROR;
10753
10754                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10755                                          "layout(rg16i) uniform image1D g_image;" NL "void main() {" NL "  o_color = vec4(1.0);" NL "}"))
10756                         return ERROR;
10757
10758                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10759                                          "layout(rg16) uniform iimage2D g_image;" NL "void main() {" NL "  o_color = vec4(1.0);" NL "}"))
10760                         return ERROR;
10761
10762                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10763                                          "layout(r32f) coherent uniform image2D g_image;" NL "void main() {" NL
10764                                          "  imageAtomicAdd(g_image, ivec2(1), 10);" NL "  o_color = vec4(1.0);" NL "}"))
10765                         return ERROR;
10766
10767                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10768                                          "layout(r16i) coherent uniform iimage2D g_image;" NL "void main() {" NL
10769                                          "  imageAtomicAdd(g_image, ivec2(1), 1u);" NL "  o_color = vec4(1.0);" NL "}"))
10770                         return ERROR;
10771
10772                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10773                                          "layout(r32ui) uniform iimage3D g_image;" NL "void main() {" NL
10774                                          "  imageStore(g_image, ivec3(1), ivec4(1));" NL "  o_color = vec4(1.0);" NL "}"))
10775                         return ERROR;
10776
10777                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10778                                          "layout(rgba8) uniform uimage2DArray g_image;" NL "void main() {" NL
10779                                          "  imageStore(g_image, ivec3(0), uvec4(1));" NL "  o_color = vec4(1.0);" NL "}"))
10780                         return ERROR;
10781
10782                 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10783                                          "layout(rgba32f) coherent uniform image2D g_image;" NL "vec4 Load(image2D image) {" NL
10784                                          "  return imageLoad(image, vec2(0));" NL "}" NL "void main() {" NL "  o_color = Load(g_image);" NL
10785                                          "}"))
10786                         return ERROR;
10787
10788                 return NO_ERROR;
10789         }
10790
10791         bool Compile(const std::string& source)
10792         {
10793                 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
10794
10795                 const char* const src = source.c_str();
10796                 glShaderSource(sh, 1, &src, NULL);
10797                 glCompileShader(sh);
10798
10799                 GLchar log[1024];
10800                 glGetShaderInfoLog(sh, sizeof(log), NULL, log);
10801                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
10802                                                                                         << log << tcu::TestLog::EndMessage;
10803
10804                 GLint status;
10805                 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
10806                 glDeleteShader(sh);
10807
10808                 if (status == GL_TRUE)
10809                 {
10810                         m_context.getTestContext().getLog()
10811                                 << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage;
10812                         return false;
10813                 }
10814
10815                 return true;
10816         }
10817 };
10818 //-----------------------------------------------------------------------------
10819 // 4.4 NegativeLinkErrors
10820 //-----------------------------------------------------------------------------
10821 class NegativeLinkErrors : public ShaderImageLoadStoreBase
10822 {
10823         virtual long Run()
10824         {
10825                 if (!SupportedInVS(1))
10826                         return NOT_SUPPORTED;
10827
10828                 if (!Link("#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
10829                                   "layout(rgba32f) uniform image1D g_image;" NL "void main() {" NL
10830                                   "  imageStore(g_image, gl_VertexID, vec4(0));" NL "  gl_Position = i_position;" NL "}",
10831                                   "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10832                                   "layout(rgba32f) uniform image2D g_image;" NL "void main() {" NL
10833                                   "  imageStore(g_image, ivec2(gl_FragCoord), vec4(1.0));" NL "  o_color = vec4(1.0);" NL "}"))
10834                         return ERROR;
10835
10836                 if (!Link("#version 420 core" NL "layout(location = 0) in vec4 i_position;" NL
10837                                   "layout(rgba32f) uniform image1D g_image;" NL "void main() {" NL
10838                                   "  imageStore(g_image, gl_VertexID, vec4(0));" NL "  gl_Position = i_position;" NL "}",
10839                                   "#version 420 core" NL "layout(location = 0) out vec4 o_color;" NL
10840                                   "layout(rg32f) uniform image1D g_image;" NL "void main() {" NL
10841                                   "  imageStore(g_image, int(gl_FragCoord.x), vec4(1.0));" NL "  o_color = vec4(1.0);" NL "}"))
10842                         return ERROR;
10843
10844                 return NO_ERROR;
10845         }
10846
10847         bool Link(const std::string& vs, const std::string& fs)
10848         {
10849                 const GLuint p = glCreateProgram();
10850
10851                 const GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
10852                 glAttachShader(p, vsh);
10853                 glDeleteShader(vsh);
10854                 const char* const vssrc = vs.c_str();
10855                 glShaderSource(vsh, 1, &vssrc, NULL);
10856                 glCompileShader(vsh);
10857
10858                 const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
10859                 glAttachShader(p, fsh);
10860                 glDeleteShader(fsh);
10861                 const char* const fssrc = fs.c_str();
10862                 glShaderSource(fsh, 1, &fssrc, NULL);
10863                 glCompileShader(fsh);
10864
10865                 GLint status;
10866                 glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
10867                 if (status == GL_FALSE)
10868                 {
10869                         glDeleteProgram(p);
10870                         m_context.getTestContext().getLog()
10871                                 << tcu::TestLog::Message << "VS compilation should be ok." << tcu::TestLog::EndMessage;
10872                         return false;
10873                 }
10874                 glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
10875                 if (status == GL_FALSE)
10876                 {
10877                         glDeleteProgram(p);
10878                         m_context.getTestContext().getLog()
10879                                 << tcu::TestLog::Message << "FS compilation should be ok." << tcu::TestLog::EndMessage;
10880                         return false;
10881                 }
10882
10883                 glLinkProgram(p);
10884
10885                 GLchar log[1024];
10886                 glGetProgramInfoLog(p, sizeof(log), NULL, log);
10887                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
10888                                                                                         << log << tcu::TestLog::EndMessage;
10889
10890                 glGetProgramiv(p, GL_LINK_STATUS, &status);
10891                 glDeleteProgram(p);
10892
10893                 if (status == GL_TRUE)
10894                 {
10895                         m_context.getTestContext().getLog()
10896                                 << tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage;
10897                         return false;
10898                 }
10899
10900                 return true;
10901         }
10902 };
10903
10904 /** Negative Test "Active image uniform limits", description follows.
10905  *
10906  *  Program that exceeds resource limits should not compile and/or link.
10907  *
10908  *  Steps:
10909  *  - try to compile and link a program that uses too many image uniforms in
10910  *  fragment shader stage,
10911  *  - try to compile and link a program that uses too many image uniforms in
10912  *  vertex shader stage,
10913  *  - try to compile and link a program that uses too many image uniforms in
10914  *  tessellation control shader stage,
10915  *  - try to compile and link a program that uses too many image uniforms in
10916  *  tessellation evaluation shader stage,
10917  *  - try to compile and link a program that uses too many image uniforms in
10918  *  geometry shader stage,
10919  *  - try to compile and link a program that uses too many image uniforms in all
10920  *  shader stages combined, any single stage should not exceed its limits, this
10921  *  step might be impossible to fulfill.
10922  *
10923  *  Test should use the following declaration of image uniforms:
10924  *  layout(r32i) uniform iimage2D u_image[N_UNIFORMS];
10925  *
10926  *  For cases where limit for single stage is tested, N_UNIFORMS should be
10927  *  defined as gl_Max*ImageUniforms + 1, where gl_Max*ImageUniforms is constant
10928  *  corresponding to tested shader stage.
10929  *
10930  *  For case where limit for combined stages is tested:
10931  *  - u_image name should be appended with the name of shader stage, like
10932  *  u_image_vertex,
10933  *  - N_UNIFORMS should be defined as gl_Max*ImageUniforms, where
10934  *  gl_Max*ImageUniforms is constant corresponding to tested shader stage,
10935  *  - compilation and linking shall succeed, when sum of all
10936  *  gl_Max*ImageUniforms corresponding to shader stages is equal (or less) to
10937  *  gl_MaxCombinedImageUniforms.
10938  *
10939  *  All defined image uniforms have to be active. Each shader stage that declare
10940  *  image uniforms should include following code snippet:
10941  *  value = 1;
10942  *  for (int i = 0; i < N_UNIFORMS; ++i)
10943  *  {
10944  *      value = imageAtomicAdd(u_image[i], coord, value);
10945  *  }
10946  **/
10947 class ImageLoadStoreUniformLimitsTest : public ShaderImageLoadStoreBase
10948 {
10949 private:
10950         /* Fields */
10951         /* Results */
10952         bool m_result_for_combined;
10953         bool m_result_for_fragment_shader;
10954         bool m_result_for_geometry_shader;
10955         bool m_result_for_tesselation_control_shader;
10956         bool m_result_for_tesselatioon_evaluation_shader;
10957         bool m_result_for_vertex_shader;
10958
10959 public:
10960         /* Constructor */
10961         ImageLoadStoreUniformLimitsTest()
10962                 : m_result_for_combined(false)
10963                 , m_result_for_fragment_shader(false)
10964                 , m_result_for_geometry_shader(false)
10965                 , m_result_for_tesselation_control_shader(false)
10966                 , m_result_for_tesselatioon_evaluation_shader(false)
10967                 , m_result_for_vertex_shader(false)
10968         {
10969                 /* Nothing to be done */
10970         }
10971
10972         /* Methods inherited from SubcaseBase */
10973         virtual long Cleanup()
10974         {
10975                 /* Done */
10976                 return NO_ERROR;
10977         }
10978
10979         virtual long Run()
10980         {
10981                 m_context.getTestContext().getLog() << tcu::TestLog::Message
10982                                                                                         << "This test tries to build invalid programs, expect error messages about "
10983                                                                                            "exceeded number of active image uniforms"
10984                                                                                         << tcu::TestLog::EndMessage;
10985
10986                 testFragmentShaderStage();
10987                 testGeometryShaderStage();
10988                 testTesselationControlShaderStage();
10989                 testTesselationEvaluationShaderStage();
10990                 testVertexShaderStage();
10991                 testCombinedShaderStages();
10992
10993                 /* Return error if any stage failed */
10994                 if ((false == m_result_for_combined) || (false == m_result_for_fragment_shader) ||
10995                         (false == m_result_for_geometry_shader) || (false == m_result_for_tesselation_control_shader) ||
10996                         (false == m_result_for_tesselatioon_evaluation_shader) || (false == m_result_for_vertex_shader))
10997                 {
10998                         return ERROR;
10999                 }
11000
11001                 /* Done */
11002                 return NO_ERROR;
11003         }
11004
11005         virtual long Setup()
11006         {
11007                 /* Done */
11008                 return NO_ERROR;
11009         }
11010
11011 private:
11012         /** Test fragment shader stage
11013          *
11014          **/
11015         void testFragmentShaderStage()
11016         {
11017                 static const char* const fragment_shader_code =
11018                         "#version 400 core\n"
11019                         "#extension GL_ARB_shader_image_load_store : require\n"
11020                         "\n"
11021                         "precision highp float;\n"
11022                         "\n"
11023                         "#define N_UNIFORMS gl_MaxFragmentImageUniforms + 1\n"
11024                         "\n"
11025                         "flat in ivec2 vs_fs_coord;\n"
11026                         "\n"
11027                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11028                         "\n"
11029                         "void main()\n"
11030                         "{\n"
11031                         "    int value = 1;\n"
11032                         "\n"
11033                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11034                         "    {\n"
11035                         "        value = imageAtomicAdd(u_image[i], vs_fs_coord, value);\n"
11036                         "    }\n"
11037                         "\n"
11038                         "    discard;\n"
11039                         "}\n\n";
11040
11041                 static const char* const vertex_shader_code = "#version 400 core\n"
11042                                                                                                           "#extension GL_ARB_shader_image_load_store : require\n"
11043                                                                                                           "\n"
11044                                                                                                           "precision highp float;\n"
11045                                                                                                           "\n"
11046                                                                                                           "     in  ivec2 vs_in_coord;\n"
11047                                                                                                           "flat out ivec2 vs_fs_coord;\n"
11048                                                                                                           "\n"
11049                                                                                                           "void main()\n"
11050                                                                                                           "{\n"
11051                                                                                                           "    vs_fs_coord = vs_in_coord;\n"
11052                                                                                                           "}\n\n";
11053
11054                 m_result_for_fragment_shader = !doesProgramLink(fragment_shader_code, 0 /* geometry_shader_code */,
11055                                                                                                                 0 /* tesselation_control_shader_code */,
11056                                                                                                                 0 /* tesselation_evaluation_shader_code */, vertex_shader_code);
11057
11058                 if (false == m_result_for_fragment_shader)
11059                 {
11060                         m_context.getTestContext().getLog()
11061                                 << tcu::TestLog::Message
11062                                 << "Program which exceeds limit of GL_MAX_FRAGMENT_IMAGE_UNIFORMS was linked successfully."
11063                                 << " File: " << __FILE__ << " Line: " << __LINE__ << " Shader code:\n"
11064                                 << fragment_shader_code << tcu::TestLog::EndMessage;
11065                 }
11066         }
11067
11068         /** Test geometry shader stage
11069          *
11070          **/
11071         void testGeometryShaderStage()
11072         {
11073                 static const char* const fragment_shader_code = "#version 400 core\n"
11074                                                                                                                 "#extension GL_ARB_shader_image_load_store : require\n"
11075                                                                                                                 "\n"
11076                                                                                                                 "precision highp float;\n"
11077                                                                                                                 "\n"
11078                                                                                                                 "void main()\n"
11079                                                                                                                 "{\n"
11080                                                                                                                 "    discard;\n"
11081                                                                                                                 "}\n\n";
11082
11083                 static const char* const geometry_shader_code =
11084                         "#version 400 core\n"
11085                         "#extension GL_ARB_shader_image_load_store : require\n"
11086                         "\n"
11087                         "precision highp float;\n"
11088                         "\n"
11089                         "layout(points)                   in;\n"
11090                         "layout(points, max_vertices = 1) out;\n"
11091                         "\n"
11092                         "#define N_UNIFORMS gl_MaxGeometryImageUniforms + 1\n"
11093                         "\n"
11094                         "in ivec2 vs_gs_coord[];\n"
11095                         "\n"
11096                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11097                         "\n"
11098                         "void main()\n"
11099                         "{\n"
11100                         "    int value = 1;\n"
11101                         "\n"
11102                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11103                         "    {\n"
11104                         "        value = imageAtomicAdd(u_image[i], vs_gs_coord[0], value);\n"
11105                         "    }\n"
11106                         "}\n\n";
11107
11108                 static const char* const vertex_shader_code = "#version 400 core\n"
11109                                                                                                           "#extension GL_ARB_shader_image_load_store : require\n"
11110                                                                                                           "\n"
11111                                                                                                           "precision highp float;\n"
11112                                                                                                           "\n"
11113                                                                                                           "in  ivec2 vs_in_coord;\n"
11114                                                                                                           "out ivec2 vs_gs_coord;\n"
11115                                                                                                           "\n"
11116                                                                                                           "void main()\n"
11117                                                                                                           "{\n"
11118                                                                                                           "    vs_gs_coord = vs_in_coord;\n"
11119                                                                                                           "}\n\n";
11120
11121                 m_result_for_geometry_shader =
11122                         !doesProgramLink(fragment_shader_code, geometry_shader_code, 0 /* tesselation_control_shader_code */,
11123                                                          0 /* tesselation_evaluation_shader_code */, vertex_shader_code);
11124
11125                 if (false == m_result_for_geometry_shader)
11126                 {
11127                         m_context.getTestContext().getLog()
11128                                 << tcu::TestLog::Message
11129                                 << "Program which exceeds limit of GL_MAX_GEOMETRY_IMAGE_UNIFORMS was linked successfully."
11130                                 << " File: " << __FILE__ << " Line: " << __LINE__ << " Shader code:\n"
11131                                 << geometry_shader_code << tcu::TestLog::EndMessage;
11132                 }
11133         }
11134
11135         /** Test tesselation control shader stage
11136          *
11137          **/
11138         void testTesselationControlShaderStage()
11139         {
11140                 static const char* const fragment_shader_code = "#version 400 core\n"
11141                                                                                                                 "#extension GL_ARB_shader_image_load_store : require\n"
11142                                                                                                                 "\n"
11143                                                                                                                 "precision highp float;\n"
11144                                                                                                                 "\n"
11145                                                                                                                 "void main()\n"
11146                                                                                                                 "{\n"
11147                                                                                                                 "    discard;\n"
11148                                                                                                                 "}\n\n";
11149
11150                 static const char* const tesselation_control_shader_code =
11151                         "#version 400 core\n"
11152                         "#extension GL_ARB_shader_image_load_store : require\n"
11153                         "\n"
11154                         "precision highp float;\n"
11155                         "\n"
11156                         "layout(vertices = 4) out;\n"
11157                         "\n"
11158                         "#define N_UNIFORMS gl_MaxTessControlImageUniforms + 1\n"
11159                         "\n"
11160                         "in ivec2 vs_tcs_coord[];\n"
11161                         "\n"
11162                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11163                         "\n"
11164                         "void main()\n"
11165                         "{\n"
11166                         "    int value = 1;\n"
11167                         "\n"
11168                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11169                         "    {\n"
11170                         "        value = imageAtomicAdd(u_image[i], vs_tcs_coord[0], value);\n"
11171                         "    }\n"
11172                         "}\n\n";
11173
11174                 static const char* const tesselation_evaluation_shader_code =
11175                         "#version 400 core\n"
11176                         "#extension GL_ARB_shader_image_load_store : require\n"
11177                         "\n"
11178                         "precision highp float;\n"
11179                         "\n"
11180                         "layout(quads, equal_spacing, ccw) in;\n"
11181                         "\n"
11182                         "void main()\n"
11183                         "{\n"
11184                         "}\n";
11185
11186                 static const char* const vertex_shader_code = "#version 400 core\n"
11187                                                                                                           "#extension GL_ARB_shader_image_load_store : require\n"
11188                                                                                                           "\n"
11189                                                                                                           "precision highp float;\n"
11190                                                                                                           "\n"
11191                                                                                                           "in  ivec2 vs_in_coord;\n"
11192                                                                                                           "out ivec2 vs_tcs_coord;\n"
11193                                                                                                           "\n"
11194                                                                                                           "void main()\n"
11195                                                                                                           "{\n"
11196                                                                                                           "    vs_tcs_coord = vs_in_coord;\n"
11197                                                                                                           "}\n\n";
11198
11199                 m_result_for_tesselation_control_shader =
11200                         !doesProgramLink(fragment_shader_code, 0 /* geometry_shader_code */, tesselation_control_shader_code,
11201                                                          tesselation_evaluation_shader_code, vertex_shader_code);
11202
11203                 if (false == m_result_for_tesselation_control_shader)
11204                 {
11205                         m_context.getTestContext().getLog()
11206                                 << tcu::TestLog::Message
11207                                 << "Program which exceeds limit of GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS was linked successfully."
11208                                 << " File: " << __FILE__ << " Line: " << __LINE__ << " Shader code:\n"
11209                                 << tesselation_control_shader_code << tcu::TestLog::EndMessage;
11210                 }
11211         }
11212
11213         /** Test teselation evaluation shader stage
11214          *
11215          **/
11216         void testTesselationEvaluationShaderStage()
11217         {
11218                 static const char* const fragment_shader_code = "#version 400 core\n"
11219                                                                                                                 "#extension GL_ARB_shader_image_load_store : require\n"
11220                                                                                                                 "\n"
11221                                                                                                                 "precision highp float;\n"
11222                                                                                                                 "\n"
11223                                                                                                                 "void main()\n"
11224                                                                                                                 "{\n"
11225                                                                                                                 "    discard;\n"
11226                                                                                                                 "}\n\n";
11227
11228                 static const char* const tesselation_evaluation_shader_code =
11229                         "#version 400 core\n"
11230                         "#extension GL_ARB_shader_image_load_store : require\n"
11231                         "\n"
11232                         "precision highp float;\n"
11233                         "\n"
11234                         "layout(quads, equal_spacing, ccw) in;\n"
11235                         "\n"
11236                         "#define N_UNIFORMS gl_MaxTessEvaluationImageUniforms + 1\n"
11237                         "\n"
11238                         "in ivec2 vs_tes_coord[];\n"
11239                         "\n"
11240                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11241                         "\n"
11242                         "void main()\n"
11243                         "{\n"
11244                         "    int value = 1;\n"
11245                         "\n"
11246                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11247                         "    {\n"
11248                         "        value = imageAtomicAdd(u_image[i], vs_tes_coord[0], value);\n"
11249                         "    }\n"
11250                         "}\n\n";
11251
11252                 static const char* const vertex_shader_code = "#version 400 core\n"
11253                                                                                                           "#extension GL_ARB_shader_image_load_store : require\n"
11254                                                                                                           "\n"
11255                                                                                                           "precision highp float;\n"
11256                                                                                                           "\n"
11257                                                                                                           "in  ivec2 vs_in_coord;\n"
11258                                                                                                           "out ivec2 vs_tes_coord;\n"
11259                                                                                                           "\n"
11260                                                                                                           "void main()\n"
11261                                                                                                           "{\n"
11262                                                                                                           "    vs_tes_coord = vs_in_coord;\n"
11263                                                                                                           "}\n\n";
11264
11265                 m_result_for_tesselatioon_evaluation_shader = !doesProgramLink(
11266                         fragment_shader_code, 0 /* geometry_shader_code */, 0 /* tesselation_control_shader_code */,
11267                         tesselation_evaluation_shader_code, vertex_shader_code);
11268
11269                 if (false == m_result_for_tesselatioon_evaluation_shader)
11270                 {
11271                         m_context.getTestContext().getLog()
11272                                 << tcu::TestLog::Message
11273                                 << "Program which exceeds limit of GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS was linked successfully."
11274                                 << " File: " << __FILE__ << " Line: " << __LINE__ << " Shader code:\n"
11275                                 << tesselation_evaluation_shader_code << tcu::TestLog::EndMessage;
11276                 }
11277         }
11278
11279         /** Test vertex shader stage
11280          *
11281          **/
11282         void testVertexShaderStage()
11283         {
11284                 static const char* const fragment_shader_code = "#version 400 core\n"
11285                                                                                                                 "#extension GL_ARB_shader_image_load_store : require\n"
11286                                                                                                                 "\n"
11287                                                                                                                 "precision highp float;\n"
11288                                                                                                                 "\n"
11289                                                                                                                 "void main()\n"
11290                                                                                                                 "{\n"
11291                                                                                                                 "    discard;\n"
11292                                                                                                                 "}\n\n";
11293
11294                 static const char* const vertex_shader_code =
11295                         "#version 400 core\n"
11296                         "#extension GL_ARB_shader_image_load_store : require\n"
11297                         "\n"
11298                         "precision highp float;\n"
11299                         "\n"
11300                         "in ivec2 vs_in_coord;\n"
11301                         "\n"
11302                         "#define N_UNIFORMS gl_MaxVertexImageUniforms + 1\n"
11303                         "\n"
11304                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11305                         "\n"
11306                         "void main()\n"
11307                         "{\n"
11308                         "    int value = 1;\n"
11309                         "\n"
11310                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11311                         "    {\n"
11312                         "        value = imageAtomicAdd(u_image[i], vs_in_coord, value);\n"
11313                         "    }\n"
11314                         "}\n\n";
11315
11316                 m_result_for_vertex_shader = !doesProgramLink(fragment_shader_code, 0 /* geometry_shader_code */,
11317                                                                                                           0 /* tesselation_control_shader_code */,
11318                                                                                                           0 /* tesselation_evaluation_shader_code */, vertex_shader_code);
11319
11320                 if (false == m_result_for_vertex_shader)
11321                 {
11322                         m_context.getTestContext().getLog()
11323                                 << tcu::TestLog::Message
11324                                 << "Program which exceeds limit of GL_MAX_VERTEX_IMAGE_UNIFORMS was linked successfully."
11325                                 << " File: " << __FILE__ << " Line: " << __LINE__ << " Shader code:\n"
11326                                 << vertex_shader_code << tcu::TestLog::EndMessage;
11327                 }
11328         }
11329
11330         /** Test combined shader stages
11331          *
11332          **/
11333         void testCombinedShaderStages()
11334         {
11335                 std::string fragment_shader_code =
11336                         "#version 400 core\n"
11337                         "#extension GL_ARB_shader_image_load_store : require\n"
11338                         "\n"
11339                         "precision highp float;\n"
11340                         "\n"
11341                         "#define N_UNIFORMS gl_MaxFragmentImageUniforms\n"
11342                         "\n"
11343                         "flat in ivec2 gs_fs_coord;\n"
11344                         "\n"
11345                         "layout(r32i) uniform iimage2D u_image_fragment[N_UNIFORMS];\n"
11346                         "\n"
11347                         "void main()\n"
11348                         "{\n"
11349                         "    int value = 1;\n"
11350                         "\n"
11351                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11352                         "    {\n"
11353                         "        value = imageAtomicAdd(u_image_fragment[i], gs_fs_coord, value);\n"
11354                         "    }\n"
11355                         "\n"
11356                         "    discard;\n"
11357                         "}\n\n";
11358
11359                 std::string geometry_shader_code =
11360                         "#version 400 core\n"
11361                         "#extension GL_ARB_shader_image_load_store : require\n"
11362                         "\n"
11363                         "precision highp float;\n"
11364                         "\n"
11365                         "layout(points)                   in;\n"
11366                         "layout(points, max_vertices = 1) out;\n"
11367                         "\n"
11368                         "#define N_UNIFORMS gl_MaxGeometryImageUniforms\n"
11369                         "\n"
11370                         "flat in  ivec2 tes_gs_coord[];\n"
11371                         "flat out ivec2 gs_fs_coord;\n"
11372                         "\n"
11373                         "#ifdef IMAGES\n"
11374                         "layout(r32i) uniform iimage2D u_image_geometry[N_UNIFORMS];\n"
11375                         "#endif\n"
11376                         "\n"
11377                         "void main()\n"
11378                         "{\n"
11379                         "#ifdef IMAGES\n"
11380                         "    int value = 1;\n"
11381                         "\n"
11382                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11383                         "    {\n"
11384                         "        value = imageAtomicAdd(u_image_geometry[i], tes_gs_coord[0], value);\n"
11385                         "    }\n"
11386                         "\n"
11387                         "#endif\n"
11388                         "    gs_fs_coord = tes_gs_coord[0];\n"
11389                         "    EmitVertex();\n"
11390                         "}\n\n";
11391
11392                 std::string tesselation_control_shader_code =
11393                         "#version 400 core\n"
11394                         "#extension GL_ARB_shader_image_load_store : require\n"
11395                         "\n"
11396                         "precision highp float;\n"
11397                         "\n"
11398                         "layout(vertices = 4) out;\n"
11399                         "\n"
11400                         "#define N_UNIFORMS gl_MaxTessControlImageUniforms\n"
11401                         "\n"
11402                         "flat in  ivec2 vs_tcs_coord[];\n"
11403                         "flat out ivec2 tcs_tes_coord[];\n"
11404                         "\n"
11405                         "#ifdef IMAGES\n"
11406                         "layout(r32i) uniform iimage2D u_image_tess_control[N_UNIFORMS];\n"
11407                         "#endif\n"
11408                         "\n"
11409                         "void main()\n"
11410                         "{\n"
11411                         "#ifdef IMAGES\n"
11412                         "    int value = 1;\n"
11413                         "\n"
11414                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11415                         "    {\n"
11416                         "        value = imageAtomicAdd(u_image_tess_control[i], vs_tcs_coord[0], value);\n"
11417                         "    }\n"
11418                         "\n"
11419                         "#endif\n"
11420                         "    tcs_tes_coord[gl_InvocationID] = vs_tcs_coord[0];\n"
11421                         "}\n\n";
11422
11423                 std::string tesselation_evaluation_shader_code =
11424                         "#version 400 core\n"
11425                         "#extension GL_ARB_shader_image_load_store : require\n"
11426                         "\n"
11427                         "precision highp float;\n"
11428                         "\n"
11429                         "layout(quads, equal_spacing, ccw) in;\n"
11430                         "\n"
11431                         "#define N_UNIFORMS gl_MaxTessEvaluationImageUniforms\n"
11432                         "\n"
11433                         "flat in  ivec2 tcs_tes_coord[];\n"
11434                         "flat out ivec2 tes_gs_coord;\n"
11435                         "\n"
11436                         "#ifdef IMAGES\n"
11437                         "layout(r32i) uniform iimage2D u_image_tess_evaluation[N_UNIFORMS];\n"
11438                         "#endif\n"
11439                         "\n"
11440                         "void main()\n"
11441                         "{\n"
11442                         "#ifdef IMAGES\n"
11443                         "    int value = 1;\n"
11444                         "\n"
11445                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11446                         "    {\n"
11447                         "        value = imageAtomicAdd(u_image_tess_evaluation[i], tcs_tes_coord[0], value);\n"
11448                         "    }\n"
11449                         "\n"
11450                         "#endif\n"
11451                         "    tes_gs_coord = tcs_tes_coord[0];\n"
11452                         "}\n\n";
11453
11454                 std::string vertex_shader_code =
11455                         "#version 400 core\n"
11456                         "#extension GL_ARB_shader_image_load_store : require\n"
11457                         "\n"
11458                         "precision highp float;\n"
11459                         "\n"
11460                         "     in  ivec2 vs_in_coord;\n"
11461                         "flat out ivec2 vs_tcs_coord;\n"
11462                         "\n"
11463                         "#define N_UNIFORMS gl_MaxVertexImageUniforms\n"
11464                         "\n"
11465                         "#ifdef IMAGES\n"
11466                         "layout(r32i) uniform iimage2D u_image[N_UNIFORMS];\n"
11467                         "#endif\n"
11468                         "\n"
11469                         "void main()\n"
11470                         "{\n"
11471                         "#ifdef IMAGES\n"
11472                         "    int value = 1;\n"
11473                         "\n"
11474                         "    for (int i = 0; i < N_UNIFORMS; ++i)\n"
11475                         "    {\n"
11476                         "        value = imageAtomicAdd(u_image[i], vs_in_coord, value);\n"
11477                         "    }\n"
11478                         "\n"
11479                         "#endif\n"
11480                         "    vs_tcs_coord = vs_tcs_coord;\n"
11481                         "}\n\n";
11482
11483                 /* Active image uniform limits */
11484                 GLint max_combined_image_uniforms                               = 0;
11485                 GLint max_fragment_image_uniforms                               = 0;
11486                 GLint max_geometry_image_uniforms                               = 0;
11487                 GLint max_tesselation_control_image_uniforms    = 0;
11488                 GLint max_tesselation_evaluation_image_uniforms = 0;
11489                 GLint max_vertex_image_uniforms                                 = 0;
11490
11491                 /* Get limit values */
11492                 glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &max_combined_image_uniforms);
11493                 glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &max_fragment_image_uniforms);
11494                 glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &max_geometry_image_uniforms);
11495                 glGetIntegerv(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, &max_tesselation_control_image_uniforms);
11496                 glGetIntegerv(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, &max_tesselation_evaluation_image_uniforms);
11497                 glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &max_vertex_image_uniforms);
11498                 GLU_EXPECT_NO_ERROR(glGetError(), "GetIntegerv");
11499
11500                 if (max_vertex_image_uniforms)
11501                         vertex_shader_code.insert(18, "#define IMAGES\n");
11502                 if (max_geometry_image_uniforms)
11503                         geometry_shader_code.insert(18, "#define IMAGES\n");
11504                 if (max_tesselation_control_image_uniforms)
11505                         tesselation_control_shader_code.insert(18, "#define IMAGES\n");
11506                 if (max_tesselation_evaluation_image_uniforms)
11507                         tesselation_evaluation_shader_code.insert(18, "#define IMAGES\n");
11508
11509                 /* Check if program builds */
11510                 m_result_for_combined =
11511                         !doesProgramLink(fragment_shader_code.c_str(),
11512                                                          geometry_shader_code.c_str(),
11513                                                          tesselation_control_shader_code.c_str(),
11514                                                          tesselation_evaluation_shader_code.c_str(),
11515                                                          vertex_shader_code.c_str());
11516
11517                 /* Result depends on the limit values */
11518                 if (max_combined_image_uniforms >=
11519                         (max_fragment_image_uniforms + max_geometry_image_uniforms + max_tesselation_control_image_uniforms +
11520                          max_tesselation_evaluation_image_uniforms + max_vertex_image_uniforms))
11521                 {
11522                         /* In this case, combined image uniforms limit cannot be exeeded, therefore successful linking is expected */
11523                         m_result_for_combined = !m_result_for_combined;
11524
11525                         if (false == m_result_for_combined)
11526                         {
11527                                 m_context.getTestContext().getLog()
11528                                         << tcu::TestLog::Message << "There was an error while building a program."
11529                                         << " File: " << __FILE__ << " Line: " << __LINE__ << " Vertex shader code:\n"
11530                                         << vertex_shader_code << "\nTesselation control shader code:\n"
11531                                         << tesselation_control_shader_code << "\nTesselation evaluation shader code:\n"
11532                                         << tesselation_evaluation_shader_code << "\nGeometry shader code:\n"
11533                                         << geometry_shader_code << "\nFragment shader code:\n"
11534                                         << fragment_shader_code << tcu::TestLog::EndMessage;
11535                         }
11536                 }
11537                 else
11538                 {
11539                         /* In this case, combined image uniforms can be exceeded, therefore failed linking is expected */
11540                         if (false == m_result_for_combined)
11541                         {
11542                                 m_context.getTestContext().getLog()
11543                                         << tcu::TestLog::Message
11544                                         << "Program which exceeds limit of GL_MAX_COMBINED_IMAGE_UNIFORMS was linked successfully."
11545                                         << " File: " << __FILE__ << " Line: " << __LINE__ << " Vertex shader code:\n"
11546                                         << vertex_shader_code << "\nTesselation control shader code:\n"
11547                                         << tesselation_control_shader_code << "\nTesselation evaluation shader code:\n"
11548                                         << tesselation_evaluation_shader_code << "\nGeometry shader code:\n"
11549                                         << geometry_shader_code << "\nFragment shader code:\n"
11550                                         << fragment_shader_code << tcu::TestLog::EndMessage;
11551                         }
11552                 }
11553         }
11554
11555         /** Check if program builds successfully
11556          *
11557          * @param fragment_shader_code               Source code for fragment shader stage
11558          * @param geometry_shader_code               Source code for geometry shader stage
11559          * @param tesselation_control_shader_code    Source code for tesselation control shader stage
11560          * @param tesselation_evaluation_shader_code Source code for tesselation evaluation shader stage
11561          * @param vertex_shader_code                 Source code for vertex shader stage
11562          *
11563          * @return true if program was built without errors, false otherwise
11564          **/
11565         bool doesProgramLink(const char* fragment_shader_code, const char* geometry_shader_code,
11566                                                  const char* tesselation_control_shader_code, const char* tesselation_evaluation_shader_code,
11567                                                  const char* vertex_shader_code)
11568         {
11569                 bool   is_program_built = true;
11570                 GLuint program_id               = 0;
11571
11572                 program_id =
11573                         BuildProgram(vertex_shader_code, tesselation_control_shader_code, tesselation_evaluation_shader_code,
11574                                                  geometry_shader_code, fragment_shader_code, &is_program_built);
11575
11576                 if (0 != program_id)
11577                 {
11578                         glDeleteProgram(program_id);
11579                 }
11580
11581                 return is_program_built;
11582         }
11583 };
11584 }
11585
11586 ShaderImageLoadStoreTests::ShaderImageLoadStoreTests(deqp::Context& context)
11587         : TestCaseGroup(context, "shader_image_load_store", "")
11588 {
11589 }
11590
11591 ShaderImageLoadStoreTests::~ShaderImageLoadStoreTests(void)
11592 {
11593 }
11594
11595 void ShaderImageLoadStoreTests::init()
11596 {
11597         using namespace deqp;
11598         addChild(new TestSubcase(m_context, "basic-api-get", TestSubcase::Create<BasicAPIGet>));
11599         addChild(new TestSubcase(m_context, "basic-api-bind", TestSubcase::Create<BasicAPIBind>));
11600         addChild(new TestSubcase(m_context, "basic-api-barrier", TestSubcase::Create<BasicAPIBarrier>));
11601         addChild(new TestSubcase(m_context, "basic-api-texParam", TestSubcase::Create<BasicAPITexParam>));
11602         addChild(new TestSubcase(m_context, "basic-allFormats-store", TestSubcase::Create<BasicAllFormatsStore>));
11603         addChild(new TestSubcase(m_context, "basic-allFormats-load", TestSubcase::Create<BasicAllFormatsLoad>));
11604         addChild(new TestSubcase(m_context, "basic-allFormats-storeGeometryStages",
11605                                                          TestSubcase::Create<BasicAllFormatsStoreGeometryStages>));
11606         addChild(new TestSubcase(m_context, "basic-allFormats-loadGeometryStages",
11607                                                          TestSubcase::Create<BasicAllFormatsLoadGeometryStages>));
11608         addChild(new TestSubcase(m_context, "basic-allFormats-loadStoreComputeStage",
11609                                                          TestSubcase::Create<BasicAllFormatsLoadStoreComputeStage>));
11610         addChild(new TestSubcase(m_context, "basic-allTargets-store", TestSubcase::Create<BasicAllTargetsStore>));
11611         addChild(new TestSubcase(m_context, "basic-allTargets-load-nonMS", TestSubcase::Create<BasicAllTargetsLoadNonMS>));
11612         addChild(new TestSubcase(m_context, "basic-allTargets-load-ms", TestSubcase::Create<BasicAllTargetsLoadMS>));
11613         addChild(new TestSubcase(m_context, "basic-allTargets-atomic", TestSubcase::Create<BasicAllTargetsAtomic>));
11614         addChild(
11615                 new TestSubcase(m_context, "basic-allTargets-loadStoreVS", TestSubcase::Create<BasicAllTargetsLoadStoreVS>));
11616         addChild(
11617                 new TestSubcase(m_context, "basic-allTargets-loadStoreTCS", TestSubcase::Create<BasicAllTargetsLoadStoreTCS>));
11618         addChild(
11619                 new TestSubcase(m_context, "basic-allTargets-loadStoreTES", TestSubcase::Create<BasicAllTargetsLoadStoreTES>));
11620         addChild(
11621                 new TestSubcase(m_context, "basic-allTargets-loadStoreGS", TestSubcase::Create<BasicAllTargetsLoadStoreGS>));
11622         addChild(
11623                 new TestSubcase(m_context, "basic-allTargets-loadStoreCS", TestSubcase::Create<BasicAllTargetsLoadStoreCS>));
11624         addChild(new TestSubcase(m_context, "basic-allTargets-atomicVS", TestSubcase::Create<BasicAllTargetsAtomicVS>));
11625         addChild(new TestSubcase(m_context, "basic-allTargets-atomicTCS", TestSubcase::Create<BasicAllTargetsAtomicTCS>));
11626         addChild(new TestSubcase(m_context, "basic-allTargets-atomicGS", TestSubcase::Create<BasicAllTargetsAtomicGS>));
11627         addChild(new TestSubcase(m_context, "basic-allTargets-atomicCS", TestSubcase::Create<BasicAllTargetsAtomicCS>));
11628         addChild(new TestSubcase(m_context, "basic-glsl-misc", TestSubcase::Create<BasicGLSLMisc>));
11629         addChild(new TestSubcase(m_context, "basic-glsl-earlyFragTests", TestSubcase::Create<BasicGLSLEarlyFragTests>));
11630         addChild(new TestSubcase(m_context, "basic-glsl-const", TestSubcase::Create<BasicGLSLConst>));
11631         addChild(new TestSubcase(m_context, "advanced-sync-imageAccess", TestSubcase::Create<AdvancedSyncImageAccess>));
11632         addChild(new TestSubcase(m_context, "advanced-sync-vertexArray", TestSubcase::Create<AdvancedSyncVertexArray>));
11633         addChild(new TestSubcase(m_context, "advanced-sync-drawIndirect", TestSubcase::Create<AdvancedSyncDrawIndirect>));
11634         addChild(new TestSubcase(m_context, "advanced-sync-textureUpdate", TestSubcase::Create<AdvancedSyncTextureUpdate>));
11635         addChild(new TestSubcase(m_context, "advanced-sync-imageAccess2", TestSubcase::Create<AdvancedSyncImageAccess2>));
11636         addChild(new TestSubcase(m_context, "advanced-sync-bufferUpdate", TestSubcase::Create<AdvancedSyncBufferUpdate>));
11637         addChild(new TestSubcase(m_context, "advanced-allStages-oneImage", TestSubcase::Create<AdvancedAllStagesOneImage>));
11638         addChild(new TestSubcase(m_context, "advanced-memory-dependentInvocation",
11639                                                          TestSubcase::Create<AdvancedMemoryDependentInvocation>));
11640         addChild(new TestSubcase(m_context, "advanced-memory-order", TestSubcase::Create<AdvancedMemoryOrder>));
11641         addChild(new TestSubcase(m_context, "advanced-sso-simple", TestSubcase::Create<AdvancedSSOSimple>));
11642         addChild(new TestSubcase(m_context, "advanced-sso-atomicCounters", TestSubcase::Create<AdvancedSSOAtomicCounters>));
11643         addChild(new TestSubcase(m_context, "advanced-sso-subroutine", TestSubcase::Create<AdvancedSSOSubroutine>));
11644         addChild(new TestSubcase(m_context, "advanced-sso-perSample", TestSubcase::Create<AdvancedSSOPerSample>));
11645         addChild(new TestSubcase(m_context, "advanced-copyImage", TestSubcase::Create<AdvancedCopyImage>));
11646         addChild(new TestSubcase(m_context, "advanced-allMips", TestSubcase::Create<AdvancedAllMips>));
11647         addChild(new TestSubcase(m_context, "advanced-cast", TestSubcase::Create<AdvancedCast>));
11648         addChild(
11649                 new TestSubcase(m_context, "single-byte_data_alignment", TestSubcase::Create<ImageLoadStoreDataAlignmentTest>));
11650         addChild(
11651                 new TestSubcase(m_context, "non-layered_binding", TestSubcase::Create<ImageLoadStoreNonLayeredBindingTest>));
11652         addChild(
11653                 new TestSubcase(m_context, "incomplete_textures", TestSubcase::Create<ImageLoadStoreIncompleteTexturesTest>));
11654         addChild(new TestSubcase(m_context, "multiple-uniforms", TestSubcase::Create<ImageLoadStoreMultipleUniformsTest>));
11655         addChild(
11656                 new TestSubcase(m_context, "early-fragment-tests", TestSubcase::Create<ImageLoadStoreEarlyFragmentTestsTest>));
11657         addChild(new TestSubcase(m_context, "negative-uniform", TestSubcase::Create<NegativeUniform>));
11658         addChild(new TestSubcase(m_context, "negative-bind", TestSubcase::Create<NegativeBind>));
11659         addChild(new TestSubcase(m_context, "negative-compileErrors", TestSubcase::Create<NegativeCompileErrors>));
11660         addChild(new TestSubcase(m_context, "negative-linkErrors", TestSubcase::Create<NegativeLinkErrors>));
11661         addChild(new TestSubcase(m_context, "uniform-limits", TestSubcase::Create<ImageLoadStoreUniformLimitsTest>));
11662 }
11663 }