Home | History | Annotate | Download | only in gl
      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 "gl4cES31CompatibilityTests.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 <cstdarg>
     32 #include <map>
     33 
     34 namespace gl4cts
     35 {
     36 namespace es31compatibility
     37 {
     38 using namespace glw;
     39 namespace
     40 {
     41 typedef tcu::Vec2  vec2;
     42 typedef tcu::Vec4  vec4;
     43 typedef tcu::IVec4 ivec4;
     44 typedef tcu::UVec4 uvec4;
     45 typedef tcu::Mat4  mat4;
     46 
     47 enum Target
     48 {
     49 	T2D = 0,
     50 	T3D,
     51 	TCM,
     52 	T2DA
     53 };
     54 
     55 const char* const kGLSLVer = "#version 310 es";
     56 const char* const kGLSLSIA = NL "#extension GL_OES_shader_image_atomic : require";
     57 const char* const kGLSLPrec =
     58 	NL "precision highp float;" NL "precision highp int;" NL "precision highp sampler2D;" NL
     59 	   "precision highp sampler3D;" NL "precision highp samplerCube;" NL "precision highp sampler2DArray;" NL
     60 	   "precision highp isampler2D;" NL "precision highp isampler3D;" NL "precision highp isamplerCube;" NL
     61 	   "precision highp isampler2DArray;" NL "precision highp usampler2D;" NL "precision highp usampler3D;" NL
     62 	   "precision highp usamplerCube;" NL "precision highp usampler2DArray;" NL "precision highp image2D;" NL
     63 	   "precision highp image3D;" NL "precision highp imageCube;" NL "precision highp image2DArray;" NL
     64 	   "precision highp iimage2D;" NL "precision highp iimage3D;" NL "precision highp iimageCube;" NL
     65 	   "precision highp iimage2DArray;" NL "precision highp uimage2D;" NL "precision highp uimage3D;" NL
     66 	   "precision highp uimageCube;" NL "precision highp uimage2DArray;";
     67 
     68 class ShaderImageLoadStoreBase : public deqp::SubcaseBase
     69 {
     70 public:
     71 	virtual std::string Title()
     72 	{
     73 		return "";
     74 	}
     75 
     76 	virtual std::string Purpose()
     77 	{
     78 		return "";
     79 	}
     80 
     81 	virtual std::string Method()
     82 	{
     83 		return "";
     84 	}
     85 
     86 	virtual std::string PassCriteria()
     87 	{
     88 		return "";
     89 	}
     90 
     91 	bool IsVSFSAvailable(int requiredVS, int requiredFS)
     92 	{
     93 		GLint imagesVS, imagesFS;
     94 		glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &imagesVS);
     95 		glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &imagesFS);
     96 		if (imagesVS >= requiredVS && imagesFS >= requiredFS)
     97 			return true;
     98 		else
     99 		{
    100 			std::ostringstream reason;
    101 			reason << "Required " << requiredVS << " VS image uniforms but only " << imagesVS << " available."
    102 				   << std::endl
    103 				   << "Required " << requiredFS << " FS image uniforms but only " << imagesFS << " available."
    104 				   << std::endl;
    105 			OutputNotSupported(reason.str());
    106 			return false;
    107 		}
    108 	}
    109 	bool IsSSBInVSFSAvailable(int required)
    110 	{
    111 		GLint blocksVS, blocksFS;
    112 		glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);
    113 		glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);
    114 		if (blocksVS >= required && blocksFS >= required)
    115 			return true;
    116 		else
    117 		{
    118 			std::ostringstream reason;
    119 			reason << "Required " << required << " VS storage blocks but only " << blocksVS << " available."
    120 				   << std::endl
    121 				   << "Required " << required << " FS storage blocks but only " << blocksFS << " available."
    122 				   << std::endl;
    123 			OutputNotSupported(reason.str());
    124 			return false;
    125 		}
    126 	}
    127 
    128 	bool IsImageAtomicSupported()
    129 	{
    130 		bool is_at_least_gl_45 =
    131 			(glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    132 		bool is_arb_es31_compatibility = m_context.getContextInfo().isExtensionSupported("GL_ARB_ES3_1_compatibility");
    133 		if (!(is_at_least_gl_45 || is_arb_es31_compatibility))
    134 		{
    135 			std::ostringstream reason;
    136 			reason << "Required GL_OES_shader_image_atomic is not available." << std::endl;
    137 			OutputNotSupported(reason.str());
    138 			return false;
    139 		}
    140 		return true;
    141 	}
    142 
    143 	bool AreOutputsAvailable(int required)
    144 	{
    145 		GLint outputs;
    146 		glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &outputs);
    147 		if (outputs < required)
    148 		{
    149 			std::ostringstream reason;
    150 			reason << "Required " << required << " shader output resources but only " << outputs << " available."
    151 				   << std::endl;
    152 			OutputNotSupported(reason.str());
    153 			return false;
    154 		}
    155 		return true;
    156 	}
    157 
    158 	int getWindowWidth()
    159 	{
    160 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    161 		return renderTarget.getWidth();
    162 	}
    163 
    164 	int getWindowHeight()
    165 	{
    166 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    167 		return renderTarget.getHeight();
    168 	}
    169 
    170 	inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon)
    171 	{
    172 		if (fabs(c0[0] - c1[0]) > epsilon[0])
    173 			return false;
    174 		if (fabs(c0[1] - c1[1]) > epsilon[1])
    175 			return false;
    176 		if (fabs(c0[2] - c1[2]) > epsilon[2])
    177 			return false;
    178 		if (fabs(c0[3] - c1[3]) > epsilon[3])
    179 			return false;
    180 		return true;
    181 	}
    182 
    183 	bool Equal(const vec4& v0, const vec4& v1, GLenum internalformat)
    184 	{
    185 		if (internalformat == GL_RGBA8_SNORM || internalformat == GL_RGBA8)
    186 		{
    187 			return ColorEqual(v0, v1, vec4(0.01f));
    188 		}
    189 		return (v0[0] == v1[0]) && (v0[1] == v1[1]) && (v0[2] == v1[2]) && (v0[3] == v1[3]);
    190 	}
    191 	bool Equal(const ivec4& a, const ivec4& b, GLenum)
    192 	{
    193 		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
    194 	}
    195 	bool Equal(const uvec4& a, const uvec4& b, GLenum)
    196 	{
    197 		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
    198 	}
    199 
    200 	template <class T>
    201 	std::string ToString(T v)
    202 	{
    203 		std::ostringstream s;
    204 		s << "[";
    205 		for (int i = 0; i < 4; ++i)
    206 			s << v[i] << (i == 3 ? "" : ",");
    207 		s << "]";
    208 		return s.str();
    209 	}
    210 
    211 	template <typename T>
    212 	bool CompareValues(T* map_data, int kSize, const T& expected_value, GLenum internalformat = 0, int layers = 1)
    213 	{
    214 		for (int i = 0; i < kSize * kSize * layers; ++i)
    215 		{
    216 			if (!Equal(map_data[i], expected_value, internalformat))
    217 			{
    218 				m_context.getTestContext().getLog()
    219 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
    220 					<< ". Value should be: " << ToString(expected_value).c_str() << "." << tcu::TestLog::EndMessage;
    221 				return false;
    222 			}
    223 		}
    224 		return true;
    225 	}
    226 	template <typename T>
    227 	bool CompareValues(bool always, T* map_data, int kSize, const T& expected_value, GLenum internalformat = 0,
    228 					   int layers = 1)
    229 	{
    230 		(void)internalformat;
    231 		for (int i = 0; i < kSize * kSize * layers; ++i)
    232 		{
    233 			if (always)
    234 			{
    235 				m_context.getTestContext().getLog()
    236 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
    237 					<< ". Value should be: " << ToString(expected_value).c_str() << "." << tcu::TestLog::EndMessage;
    238 			}
    239 		}
    240 		return true;
    241 	}
    242 
    243 	bool CheckFB(vec4 expected)
    244 	{
    245 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    246 		const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
    247 		vec4 g_color_eps = vec4(1.f / (float)(1 << pixelFormat.redBits), 1.f / (float)(1 << pixelFormat.greenBits),
    248 								1.f / (float)(1 << pixelFormat.blueBits), 1.f);
    249 		vec4				 g_color_max = vec4(255);
    250 		std::vector<GLubyte> fb(getWindowWidth() * getWindowHeight() * 4);
    251 		int					 fb_w = getWindowWidth();
    252 		int					 fb_h = getWindowHeight();
    253 		glReadPixels(0, 0, fb_w, fb_h, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]);
    254 		for (GLint i = 0, y = 0; y < fb_h; ++y)
    255 			for (GLint x = 0; x < fb_w; ++x, i += 4)
    256 			{
    257 				if (fabs(fb[i + 0] / g_color_max[0] - expected[0]) > g_color_eps[0] ||
    258 					fabs(fb[i + 1] / g_color_max[1] - expected[1]) > g_color_eps[1] ||
    259 					fabs(fb[i + 2] / g_color_max[2] - expected[2]) > g_color_eps[2])
    260 				{
    261 					m_context.getTestContext().getLog()
    262 						<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << ", " << y
    263 						<< "). Color is (" << fb[i + 0] / g_color_max[0] << ", " << fb[i + 1] / g_color_max[1] << ", "
    264 						<< fb[i + 2] / g_color_max[2] << "). Color should be (" << expected[0] << ", " << expected[1]
    265 						<< ", " << expected[2] << ")." << tcu::TestLog::EndMessage;
    266 					return false;
    267 				}
    268 			}
    269 		return true;
    270 	}
    271 
    272 	bool CompileShader(GLuint shader)
    273 	{
    274 		glCompileShader(shader);
    275 
    276 		GLint status;
    277 		glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    278 		if (status == GL_FALSE)
    279 		{
    280 			GLsizei length;
    281 			GLchar  log[1024];
    282 			glGetShaderInfoLog(shader, sizeof(log), &length, log);
    283 			if (length > 1)
    284 			{
    285 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
    286 													<< log << tcu::TestLog::EndMessage;
    287 			}
    288 			return false;
    289 		}
    290 		return true;
    291 	}
    292 
    293 	bool LinkProgram(GLuint program)
    294 	{
    295 		glLinkProgram(program);
    296 
    297 		GLint status;
    298 		glGetProgramiv(program, GL_LINK_STATUS, &status);
    299 		if (status == GL_FALSE)
    300 		{
    301 			GLsizei length;
    302 			GLchar  log[1024];
    303 			glGetProgramInfoLog(program, sizeof(log), &length, log);
    304 			if (length > 1)
    305 			{
    306 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
    307 													<< log << tcu::TestLog::EndMessage;
    308 			}
    309 			return false;
    310 		}
    311 		return true;
    312 	}
    313 
    314 	GLuint BuildProgram(const char* src_vs, const char* src_fs, bool SIAvs = false, bool SIAfs = false)
    315 	{
    316 		std::ostringstream osvs, osfs;
    317 		osvs << kGLSLVer << (SIAvs ? kGLSLSIA : "\n") << kGLSLPrec;
    318 		osfs << kGLSLVer << (SIAfs ? kGLSLSIA : "\n") << kGLSLPrec;
    319 		std::string hvs = osvs.str();
    320 		std::string hfs = osfs.str();
    321 
    322 		const GLuint p = glCreateProgram();
    323 
    324 		if (src_vs)
    325 		{
    326 			GLuint sh = glCreateShader(GL_VERTEX_SHADER);
    327 			glAttachShader(p, sh);
    328 			glDeleteShader(sh);
    329 			const char* const src[2] = { hvs.c_str(), src_vs };
    330 			glShaderSource(sh, 2, src, NULL);
    331 			if (!CompileShader(sh))
    332 			{
    333 				m_context.getTestContext().getLog()
    334 					<< tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage;
    335 				return p;
    336 			}
    337 		}
    338 		if (src_fs)
    339 		{
    340 			GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
    341 			glAttachShader(p, sh);
    342 			glDeleteShader(sh);
    343 			const char* const src[2] = { hfs.c_str(), src_fs };
    344 			glShaderSource(sh, 2, src, NULL);
    345 			if (!CompileShader(sh))
    346 			{
    347 				m_context.getTestContext().getLog()
    348 					<< tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage;
    349 				return p;
    350 			}
    351 		}
    352 		if (!LinkProgram(p))
    353 		{
    354 			if (src_vs)
    355 				m_context.getTestContext().getLog()
    356 					<< tcu::TestLog::Message << hvs.c_str() << src_vs << tcu::TestLog::EndMessage;
    357 			if (src_fs)
    358 				m_context.getTestContext().getLog()
    359 					<< tcu::TestLog::Message << hfs.c_str() << src_fs << tcu::TestLog::EndMessage;
    360 			return p;
    361 		}
    362 
    363 		return p;
    364 	}
    365 
    366 	GLuint CreateComputeProgram(const std::string& cs, bool SIA = false)
    367 	{
    368 		std::ostringstream oscs;
    369 		oscs << kGLSLVer << (SIA ? kGLSLSIA : "\n") << kGLSLPrec;
    370 		std::string  hcs = oscs.str();
    371 		const GLuint p   = glCreateProgram();
    372 
    373 		if (!cs.empty())
    374 		{
    375 			const GLuint sh = glCreateShader(GL_COMPUTE_SHADER);
    376 			glAttachShader(p, sh);
    377 			glDeleteShader(sh);
    378 			const char* const src[2] = { hcs.c_str(), cs.c_str() };
    379 			glShaderSource(sh, 2, src, NULL);
    380 			if (!CompileShader(sh))
    381 			{
    382 				m_context.getTestContext().getLog()
    383 					<< tcu::TestLog::Message << src[0] << src[1] << tcu::TestLog::EndMessage;
    384 				return p;
    385 			}
    386 		}
    387 		if (!LinkProgram(p))
    388 		{
    389 			if (!cs.empty())
    390 				m_context.getTestContext().getLog()
    391 					<< tcu::TestLog::Message << hcs.c_str() << cs.c_str() << tcu::TestLog::EndMessage;
    392 			return p;
    393 		}
    394 
    395 		return p;
    396 	}
    397 
    398 	GLuint BuildShaderProgram(GLenum type, const char* src)
    399 	{
    400 		const char* const src3[3] = { kGLSLVer, kGLSLPrec, src };
    401 		const GLuint	  p		  = glCreateShaderProgramv(type, 3, src3);
    402 		GLint			  status;
    403 		glGetProgramiv(p, GL_LINK_STATUS, &status);
    404 		if (status == GL_FALSE)
    405 		{
    406 			GLchar log[1024];
    407 			glGetProgramInfoLog(p, sizeof(log), NULL, log);
    408 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
    409 												<< log << "\n"
    410 												<< src3[0] << "\n"
    411 												<< src3[1] << "\n"
    412 												<< src3[2] << tcu::TestLog::EndMessage;
    413 		}
    414 		return p;
    415 	}
    416 
    417 	void CreateFullViewportQuad(GLuint* vao, GLuint* vbo, GLuint* ebo)
    418 	{
    419 		assert(vao && vbo);
    420 
    421 		// interleaved data (vertex, color0 (green), color1 (blue), color2 (red))
    422 		const float v[] = {
    423 			-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,
    424 			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,
    425 			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,
    426 		};
    427 		glGenBuffers(1, vbo);
    428 		glBindBuffer(GL_ARRAY_BUFFER, *vbo);
    429 		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
    430 		glBindBuffer(GL_ARRAY_BUFFER, 0);
    431 
    432 		if (ebo)
    433 		{
    434 			std::vector<GLushort> index_data(4);
    435 			for (int i = 0; i < 4; ++i)
    436 			{
    437 				index_data[i] = static_cast<GLushort>(i);
    438 			}
    439 			glGenBuffers(1, ebo);
    440 			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo);
    441 			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 4, &index_data[0], GL_STATIC_DRAW);
    442 			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    443 		}
    444 
    445 		glGenVertexArrays(1, vao);
    446 		glBindVertexArray(*vao);
    447 		glBindBuffer(GL_ARRAY_BUFFER, *vbo);
    448 		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 11, 0);
    449 
    450 		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 2));
    451 
    452 		glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11,
    453 
    454 							  reinterpret_cast<void*>(sizeof(float) * 5));
    455 
    456 		glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 11, reinterpret_cast<void*>(sizeof(float) * 8));
    457 
    458 		glBindBuffer(GL_ARRAY_BUFFER, 0);
    459 		glEnableVertexAttribArray(0);
    460 		glEnableVertexAttribArray(1);
    461 		glEnableVertexAttribArray(2);
    462 		glEnableVertexAttribArray(3);
    463 		if (ebo)
    464 		{
    465 			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ebo);
    466 		}
    467 		glBindVertexArray(0);
    468 	}
    469 
    470 	std::string FormatEnumToString(GLenum e)
    471 	{
    472 		switch (e)
    473 		{
    474 		case GL_RGBA32F:
    475 			return "rgba32f";
    476 		case GL_RGBA16F:
    477 			return "rgba16f";
    478 		case GL_R32F:
    479 			return "r32f";
    480 
    481 		case GL_RGBA32UI:
    482 			return "rgba32ui";
    483 		case GL_RGBA16UI:
    484 			return "rgba16ui";
    485 		case GL_RGBA8UI:
    486 			return "rgba8ui";
    487 		case GL_R32UI:
    488 			return "r32ui";
    489 
    490 		case GL_RGBA32I:
    491 			return "rgba32i";
    492 		case GL_RGBA16I:
    493 			return "rgba16i";
    494 		case GL_RGBA8I:
    495 			return "rgba8i";
    496 		case GL_R32I:
    497 			return "r32i";
    498 
    499 		case GL_RGBA8:
    500 			return "rgba8";
    501 
    502 		case GL_RGBA8_SNORM:
    503 			return "rgba8_snorm";
    504 		}
    505 
    506 		assert(0);
    507 		return "";
    508 	}
    509 
    510 	template <typename T>
    511 	GLenum Format();
    512 
    513 	template <typename T>
    514 	GLenum Type();
    515 
    516 	template <typename T>
    517 	std::string TypePrefix();
    518 
    519 	template <typename T>
    520 	GLenum ImageType(GLenum target);
    521 
    522 	void ClearBuffer(GLenum buffer, GLint drawbuffer, const vec4& color)
    523 	{
    524 		glClearBufferfv(buffer, drawbuffer, &color[0]);
    525 	}
    526 
    527 	void ClearBuffer(GLenum buffer, GLint drawbuffer, const ivec4& color)
    528 	{
    529 		glClearBufferiv(buffer, drawbuffer, &color[0]);
    530 	}
    531 
    532 	void ClearBuffer(GLenum buffer, GLint drawbuffer, const uvec4& color)
    533 	{
    534 		glClearBufferuiv(buffer, drawbuffer, &color[0]);
    535 	}
    536 
    537 	bool CheckMax(GLenum pname, GLint min_value)
    538 	{
    539 		GLboolean b;
    540 		GLint	 i;
    541 		GLfloat   f;
    542 		GLint64   i64;
    543 
    544 		glGetIntegerv(pname, &i);
    545 		if (i < min_value)
    546 			return false;
    547 
    548 		glGetBooleanv(pname, &b);
    549 		if (b != (i ? GL_TRUE : GL_FALSE))
    550 			return false;
    551 
    552 		glGetFloatv(pname, &f);
    553 		if (static_cast<GLint>(f) < min_value)
    554 			return false;
    555 
    556 		glGetInteger64v(pname, &i64);
    557 		if (static_cast<GLint>(i64) < min_value)
    558 			return false;
    559 
    560 		return true;
    561 	}
    562 
    563 	bool CheckBinding(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access,
    564 					  GLenum format)
    565 	{
    566 		GLint	 i;
    567 		GLboolean b;
    568 
    569 		glGetIntegeri_v(GL_IMAGE_BINDING_NAME, unit, &i);
    570 		if (static_cast<GLuint>(i) != texture)
    571 		{
    572 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_NAME is " << i
    573 												<< " should be " << texture << "." << tcu::TestLog::EndMessage;
    574 			return false;
    575 		}
    576 
    577 		glGetIntegeri_v(GL_IMAGE_BINDING_LEVEL, unit, &i);
    578 		if (i != level)
    579 		{
    580 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LEVEL is " << i
    581 												<< " should be " << level << "." << tcu::TestLog::EndMessage;
    582 			return false;
    583 		}
    584 
    585 		glGetIntegeri_v(GL_IMAGE_BINDING_LAYERED, unit, &i);
    586 		glGetBooleani_v(GL_IMAGE_BINDING_LAYERED, unit, &b);
    587 		if (i != layered || b != layered)
    588 		{
    589 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYERED is " << i
    590 												<< " should be " << layered << "." << tcu::TestLog::EndMessage;
    591 			return false;
    592 		}
    593 
    594 		glGetIntegeri_v(GL_IMAGE_BINDING_LAYER, unit, &i);
    595 		if (i != layer)
    596 		{
    597 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_LAYER is " << i
    598 												<< " should be " << layer << "." << tcu::TestLog::EndMessage;
    599 			return false;
    600 		}
    601 
    602 		glGetIntegeri_v(GL_IMAGE_BINDING_ACCESS, unit, &i);
    603 		if (static_cast<GLenum>(i) != access)
    604 		{
    605 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_ACCESS is " << i
    606 												<< " should be " << access << "." << tcu::TestLog::EndMessage;
    607 			return false;
    608 		}
    609 
    610 		glGetIntegeri_v(GL_IMAGE_BINDING_FORMAT, unit, &i);
    611 		if (static_cast<GLenum>(i) != format)
    612 		{
    613 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_IMAGE_BINDING_FORMAT is " << i
    614 												<< " should be " << format << "." << tcu::TestLog::EndMessage;
    615 			return false;
    616 		}
    617 
    618 		return true;
    619 	}
    620 	const char* EnumToString(GLenum e)
    621 	{
    622 		switch (e)
    623 		{
    624 		case GL_TEXTURE_2D:
    625 			return "GL_TEXTURE_2D";
    626 		case GL_TEXTURE_3D:
    627 			return "GL_TEXTURE_3D";
    628 		case GL_TEXTURE_CUBE_MAP:
    629 			return "GL_TEXTURE_CUBE_MAP";
    630 		case GL_TEXTURE_2D_ARRAY:
    631 			return "GL_TEXTURE_2D_ARRAY";
    632 
    633 		default:
    634 			assert(0);
    635 			break;
    636 		}
    637 		return NULL;
    638 	}
    639 };
    640 
    641 template <>
    642 GLenum ShaderImageLoadStoreBase::Format<vec4>()
    643 {
    644 	return GL_RGBA;
    645 }
    646 
    647 template <>
    648 GLenum ShaderImageLoadStoreBase::Format<ivec4>()
    649 {
    650 	return GL_RGBA_INTEGER;
    651 }
    652 
    653 template <>
    654 GLenum ShaderImageLoadStoreBase::Format<uvec4>()
    655 {
    656 	return GL_RGBA_INTEGER;
    657 }
    658 
    659 template <>
    660 GLenum ShaderImageLoadStoreBase::Format<GLint>()
    661 {
    662 	return GL_RED_INTEGER;
    663 }
    664 
    665 template <>
    666 GLenum ShaderImageLoadStoreBase::Format<GLuint>()
    667 {
    668 	return GL_RED_INTEGER;
    669 }
    670 
    671 template <>
    672 GLenum ShaderImageLoadStoreBase::Type<vec4>()
    673 {
    674 	return GL_FLOAT;
    675 }
    676 
    677 template <>
    678 GLenum ShaderImageLoadStoreBase::Type<ivec4>()
    679 {
    680 	return GL_INT;
    681 }
    682 
    683 template <>
    684 GLenum ShaderImageLoadStoreBase::Type<uvec4>()
    685 {
    686 	return GL_UNSIGNED_INT;
    687 }
    688 
    689 template <>
    690 GLenum ShaderImageLoadStoreBase::Type<GLint>()
    691 {
    692 	return GL_INT;
    693 }
    694 
    695 template <>
    696 GLenum ShaderImageLoadStoreBase::Type<GLuint>()
    697 {
    698 	return GL_UNSIGNED_INT;
    699 }
    700 
    701 template <>
    702 std::string ShaderImageLoadStoreBase::TypePrefix<vec4>()
    703 {
    704 	return "";
    705 }
    706 
    707 template <>
    708 
    709 std::string ShaderImageLoadStoreBase::TypePrefix<ivec4>()
    710 {
    711 	return "i";
    712 }
    713 
    714 template <>
    715 std::string ShaderImageLoadStoreBase::TypePrefix<uvec4>()
    716 {
    717 	return "u";
    718 }
    719 
    720 template <>
    721 
    722 std::string ShaderImageLoadStoreBase::TypePrefix<GLint>()
    723 {
    724 	return "i";
    725 }
    726 
    727 template <>
    728 std::string ShaderImageLoadStoreBase::TypePrefix<GLuint>()
    729 {
    730 	return "u";
    731 }
    732 
    733 template <>
    734 GLenum ShaderImageLoadStoreBase::ImageType<vec4>(GLenum target)
    735 {
    736 	switch (target)
    737 	{
    738 	case GL_TEXTURE_2D:
    739 		return GL_IMAGE_2D;
    740 	case GL_TEXTURE_3D:
    741 		return GL_IMAGE_3D;
    742 	case GL_TEXTURE_CUBE_MAP:
    743 		return GL_IMAGE_CUBE;
    744 	case GL_TEXTURE_2D_ARRAY:
    745 		return GL_IMAGE_2D_ARRAY;
    746 	}
    747 	assert(0);
    748 	return 0;
    749 }
    750 
    751 template <>
    752 GLenum ShaderImageLoadStoreBase::ImageType<ivec4>(GLenum target)
    753 {
    754 	switch (target)
    755 	{
    756 	case GL_TEXTURE_2D:
    757 		return GL_INT_IMAGE_2D;
    758 	case GL_TEXTURE_3D:
    759 		return GL_INT_IMAGE_3D;
    760 	case GL_TEXTURE_CUBE_MAP:
    761 		return GL_INT_IMAGE_CUBE;
    762 	case GL_TEXTURE_2D_ARRAY:
    763 		return GL_INT_IMAGE_2D_ARRAY;
    764 	}
    765 	assert(0);
    766 	return 0;
    767 }
    768 
    769 template <>
    770 GLenum ShaderImageLoadStoreBase::ImageType<uvec4>(GLenum target)
    771 {
    772 	switch (target)
    773 	{
    774 	case GL_TEXTURE_2D:
    775 		return GL_UNSIGNED_INT_IMAGE_2D;
    776 	case GL_TEXTURE_3D:
    777 		return GL_UNSIGNED_INT_IMAGE_3D;
    778 	case GL_TEXTURE_CUBE_MAP:
    779 		return GL_UNSIGNED_INT_IMAGE_CUBE;
    780 	case GL_TEXTURE_2D_ARRAY:
    781 		return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
    782 	}
    783 	assert(0);
    784 	return 0;
    785 }
    786 
    787 int Components(GLenum e)
    788 {
    789 	return (e == GL_RED || e == GL_RED_INTEGER) ? 1 : 4;
    790 }
    791 
    792 bool Shorts(GLenum e)
    793 {
    794 	return (e == GL_RGBA16I || e == GL_RGBA16UI);
    795 }
    796 
    797 bool Bytes(GLenum e)
    798 {
    799 	return (e == GL_RGBA8I || e == GL_RGBA8UI || e == GL_RGBA8 || e == GL_RGBA8_SNORM);
    800 }
    801 
    802 template <typename T>
    803 class ShortByteData
    804 {
    805 public:
    806 	std::vector<T>		 data;
    807 	std::vector<GLshort> datas;
    808 	std::vector<GLbyte>  datab;
    809 
    810 	ShortByteData(int size, const T& value, GLenum internalformat, GLenum format)
    811 		: data(size * size, value), datas(size * size * 4), datab(size * size * 4)
    812 	{
    813 		if (Components(format) == 1)
    814 			for (unsigned i = 0; i < data.size() / 4; ++i)
    815 			{
    816 				data[i][0] = data[i * 4][0];
    817 				data[i][1] = data[i * 4 + 1][0];
    818 				data[i][2] = data[i * 4 + 2][0];
    819 				data[i][3] = data[i * 4 + 3][0];
    820 			}
    821 		if (Shorts(internalformat))
    822 		{
    823 			for (unsigned i = 0; i < datas.size(); i += 4)
    824 			{
    825 				datas[i]	 = static_cast<GLshort>(data[i / 4][0]);
    826 				datas[i + 1] = static_cast<GLshort>(data[i / 4][1]);
    827 				datas[i + 2] = static_cast<GLshort>(data[i / 4][2]);
    828 				datas[i + 3] = static_cast<GLshort>(data[i / 4][3]);
    829 			}
    830 		}
    831 		if (Bytes(internalformat))
    832 		{
    833 			for (unsigned i = 0; i < datas.size(); i += 4)
    834 			{
    835 				if (internalformat == GL_RGBA8I || internalformat == GL_RGBA8UI)
    836 				{
    837 					datab[i]	 = static_cast<GLbyte>(data[i / 4][0]);
    838 					datab[i + 1] = static_cast<GLbyte>(data[i / 4][1]);
    839 					datab[i + 2] = static_cast<GLbyte>(data[i / 4][2]);
    840 					datab[i + 3] = static_cast<GLbyte>(data[i / 4][3]);
    841 				}
    842 				else if (internalformat == GL_RGBA8)
    843 				{
    844 					datab[i]	 = static_cast<GLbyte>(data[i / 4][0] * 255);
    845 					datab[i + 1] = static_cast<GLbyte>(data[i / 4][1] * 255);
    846 					datab[i + 2] = static_cast<GLbyte>(data[i / 4][2] * 255);
    847 					datab[i + 3] = static_cast<GLbyte>(data[i / 4][3] * 255);
    848 				}
    849 				else
    850 				{ // GL_RGBA8_SNORM
    851 					datab[i]	 = static_cast<GLbyte>(data[i / 4][0] * 127);
    852 					datab[i + 1] = static_cast<GLbyte>(data[i / 4][1] * 127);
    853 					datab[i + 2] = static_cast<GLbyte>(data[i / 4][2] * 127);
    854 					datab[i + 3] = static_cast<GLbyte>(data[i / 4][3] * 127);
    855 				}
    856 			}
    857 		}
    858 	}
    859 };
    860 
    861 //-----------------------------------------------------------------------------
    862 // 1.1.1 BasicAPIGet
    863 //-----------------------------------------------------------------------------
    864 class BasicAPIGet : public ShaderImageLoadStoreBase
    865 {
    866 	virtual long Run()
    867 	{
    868 		if (!CheckMax(GL_MAX_IMAGE_UNITS, 4))
    869 		{
    870 			m_context.getTestContext().getLog()
    871 				<< tcu::TestLog::Message << "GL_MAX_IMAGE_UNITS value is invalid." << tcu::TestLog::EndMessage;
    872 			return ERROR;
    873 		}
    874 		if (!CheckMax(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, 4))
    875 		{
    876 			m_context.getTestContext().getLog()
    877 				<< tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES value is invalid."
    878 				<< tcu::TestLog::EndMessage;
    879 			return ERROR;
    880 		}
    881 		if (!CheckMax(GL_MAX_VERTEX_IMAGE_UNIFORMS, 0))
    882 		{
    883 			m_context.getTestContext().getLog()
    884 				<< tcu::TestLog::Message << "GL_MAX_VERTEX_IMAGE_UNIFORMS value is invalid."
    885 				<< tcu::TestLog::EndMessage;
    886 			return ERROR;
    887 		}
    888 		if (!CheckMax(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, 0))
    889 		{
    890 			m_context.getTestContext().getLog()
    891 				<< tcu::TestLog::Message << "GL_MAX_FRAGMENT_IMAGE_UNIFORMS value is invalid."
    892 				<< tcu::TestLog::EndMessage;
    893 			return ERROR;
    894 		}
    895 		if (!CheckMax(GL_MAX_COMBINED_IMAGE_UNIFORMS, 4))
    896 		{
    897 			m_context.getTestContext().getLog()
    898 				<< tcu::TestLog::Message << "GL_MAX_COMBINED_IMAGE_UNIFORMS value is invalid."
    899 				<< tcu::TestLog::EndMessage;
    900 			return ERROR;
    901 		}
    902 		if (!CheckMax(GL_MAX_COMPUTE_IMAGE_UNIFORMS, 4))
    903 		{
    904 			m_context.getTestContext().getLog()
    905 				<< tcu::TestLog::Message << "GL_MAX_COMPUTE_IMAGE_UNIFORMS value is invalid."
    906 				<< tcu::TestLog::EndMessage;
    907 			return ERROR;
    908 		}
    909 		return NO_ERROR;
    910 	}
    911 };
    912 
    913 //-----------------------------------------------------------------------------
    914 // 1.1.2 BasicAPIBind
    915 //-----------------------------------------------------------------------------
    916 class BasicAPIBind : public ShaderImageLoadStoreBase
    917 {
    918 	GLuint m_texture;
    919 
    920 	virtual long Setup()
    921 	{
    922 		m_texture = 0;
    923 		return NO_ERROR;
    924 	}
    925 
    926 	virtual long Run()
    927 	{
    928 		bool status = true;
    929 		for (GLuint index = 0; index < 4; ++index)
    930 		{
    931 			if (!CheckBinding(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI))
    932 			{
    933 				m_context.getTestContext().getLog() << tcu::TestLog::Message << "Binding point " << index
    934 													<< " has invalid default state." << tcu::TestLog::EndMessage;
    935 				status = false;
    936 			}
    937 		}
    938 
    939 		glGenTextures(1, &m_texture);
    940 		glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
    941 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RG32F, 16, 16, 4);
    942 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
    943 
    944 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
    945 		if (!CheckBinding(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F))
    946 			status = false;
    947 
    948 		glBindImageTexture(3, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8);
    949 		if (!CheckBinding(3, m_texture, 1, GL_TRUE, 1, GL_WRITE_ONLY, GL_RGBA8))
    950 			status = false;
    951 
    952 		glBindImageTexture(1, m_texture, 3, GL_FALSE, 2, GL_READ_WRITE, GL_RGBA8UI);
    953 		if (!CheckBinding(1, m_texture, 3, GL_FALSE, 2, GL_READ_WRITE, GL_RGBA8UI))
    954 			status = false;
    955 
    956 		glBindImageTexture(2, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I);
    957 		if (!CheckBinding(2, m_texture, 4, GL_FALSE, 3, GL_READ_ONLY, GL_R32I))
    958 			status = false;
    959 
    960 		glDeleteTextures(1, &m_texture);
    961 		m_texture = 0;
    962 
    963 		for (GLuint index = 0; index < 4; ++index)
    964 		{
    965 			GLint name;
    966 			glGetIntegeri_v(GL_IMAGE_BINDING_NAME, index, &name);
    967 			if (name != 0)
    968 			{
    969 				m_context.getTestContext().getLog()
    970 					<< tcu::TestLog::Message << "Binding point " << index
    971 					<< " should be set to 0 after texture deletion." << tcu::TestLog::EndMessage;
    972 				status = false;
    973 			}
    974 			if (!CheckBinding(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI))
    975 				status = false;
    976 		}
    977 
    978 		return status ? NO_ERROR : ERROR;
    979 	}
    980 
    981 	virtual long Cleanup()
    982 	{
    983 		glDeleteTextures(1, &m_texture);
    984 		return NO_ERROR;
    985 	}
    986 };
    987 //-----------------------------------------------------------------------------
    988 // 1.1.3 BasicAPIBarrier
    989 //-----------------------------------------------------------------------------
    990 class BasicAPIBarrier : public ShaderImageLoadStoreBase
    991 {
    992 	virtual long Run()
    993 	{
    994 		glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
    995 		glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);
    996 		glMemoryBarrier(GL_UNIFORM_BARRIER_BIT);
    997 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
    998 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
    999 		glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
   1000 		glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
   1001 		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
   1002 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1003 		glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
   1004 		glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);
   1005 		glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
   1006 		glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
   1007 
   1008 		glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
   1009 						GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
   1010 						GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
   1011 						GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT |
   1012 						GL_SHADER_STORAGE_BARRIER_BIT);
   1013 
   1014 		glMemoryBarrier(GL_ALL_BARRIER_BITS);
   1015 
   1016 		return NO_ERROR;
   1017 	}
   1018 };
   1019 
   1020 class BasicAPIBarrierByRegion : public ShaderImageLoadStoreBase
   1021 {
   1022 	virtual long Run()
   1023 	{
   1024 		glMemoryBarrierByRegion(GL_UNIFORM_BARRIER_BIT);
   1025 		glMemoryBarrierByRegion(GL_TEXTURE_FETCH_BARRIER_BIT);
   1026 		glMemoryBarrierByRegion(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   1027 		glMemoryBarrierByRegion(GL_FRAMEBUFFER_BARRIER_BIT);
   1028 		glMemoryBarrierByRegion(GL_ATOMIC_COUNTER_BARRIER_BIT);
   1029 		glMemoryBarrierByRegion(GL_SHADER_STORAGE_BARRIER_BIT);
   1030 
   1031 		glMemoryBarrierByRegion(GL_UNIFORM_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT |
   1032 								GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
   1033 								GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT);
   1034 
   1035 		glMemoryBarrierByRegion(GL_ALL_BARRIER_BITS);
   1036 		return NO_ERROR;
   1037 	}
   1038 };
   1039 //-----------------------------------------------------------------------------
   1040 // 1.1.4 BasicAPITexParam
   1041 //-----------------------------------------------------------------------------
   1042 class BasicAPITexParam : public ShaderImageLoadStoreBase
   1043 {
   1044 	GLuint m_texture;
   1045 
   1046 	virtual long Setup()
   1047 	{
   1048 		m_texture = 0;
   1049 		return NO_ERROR;
   1050 	}
   1051 
   1052 	virtual long Run()
   1053 	{
   1054 		glGenTextures(1, &m_texture);
   1055 		glBindTexture(GL_TEXTURE_2D, m_texture);
   1056 		glTexStorage2D(GL_TEXTURE_2D, 5, GL_RG32F, 16, 16);
   1057 
   1058 		GLint   i;
   1059 		GLfloat f;
   1060 
   1061 		glGetTexParameteriv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &i);
   1062 		if (i != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
   1063 		{
   1064 			m_context.getTestContext().getLog()
   1065 				<< tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
   1066 				<< "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
   1067 				<< tcu::TestLog::EndMessage;
   1068 			return ERROR;
   1069 		}
   1070 		glGetTexParameterfv(GL_TEXTURE_2D, GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, &f);
   1071 		if (static_cast<GLenum>(f) != GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE)
   1072 		{
   1073 			m_context.getTestContext().getLog()
   1074 				<< tcu::TestLog::Message << "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE should equal to "
   1075 				<< "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE for textures allocated by the GL."
   1076 				<< tcu::TestLog::EndMessage;
   1077 			return ERROR;
   1078 		}
   1079 
   1080 		return NO_ERROR;
   1081 	}
   1082 
   1083 	virtual long Cleanup()
   1084 	{
   1085 		glDeleteTextures(1, &m_texture);
   1086 		return NO_ERROR;
   1087 	}
   1088 };
   1089 //-----------------------------------------------------------------------------
   1090 // 1.2.1 BasicAllFormatsStore
   1091 //-----------------------------------------------------------------------------
   1092 class BasicAllFormatsStoreFS : public ShaderImageLoadStoreBase
   1093 {
   1094 	GLuint m_vao, m_vbo;
   1095 
   1096 	virtual long Setup()
   1097 	{
   1098 		m_vao = 0;
   1099 		m_vbo = 0;
   1100 		return NO_ERROR;
   1101 	}
   1102 
   1103 	virtual long Run()
   1104 	{
   1105 		if (!IsVSFSAvailable(0, 1))
   1106 			return NOT_SUPPORTED;
   1107 
   1108 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   1109 
   1110 		if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   1111 			return ERROR;
   1112 		if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
   1113 			return ERROR;
   1114 		if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   1115 			return ERROR;
   1116 
   1117 		if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1118 			return ERROR;
   1119 		if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
   1120 			return ERROR;
   1121 		if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1122 			return ERROR;
   1123 		if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1124 			return ERROR;
   1125 
   1126 		if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1127 			return ERROR;
   1128 		if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
   1129 			return ERROR;
   1130 		if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1131 			return ERROR;
   1132 		if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1133 			return ERROR;
   1134 
   1135 		if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
   1136 			return ERROR;
   1137 
   1138 		if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
   1139 			return ERROR;
   1140 
   1141 		return NO_ERROR;
   1142 	}
   1143 
   1144 	template <typename T>
   1145 	bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
   1146 	{
   1147 		const char* src_vs =
   1148 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   1149 		GLuint		   program = BuildProgram(src_vs, GenFS(internalformat, write_value).c_str());
   1150 		const int	  kSize   = 11;
   1151 		std::vector<T> data(kSize * kSize);
   1152 		GLuint		   texture;
   1153 		glGenTextures(1, &texture);
   1154 		glUseProgram(program);
   1155 
   1156 		GLuint unit = 2;
   1157 		glBindTexture(GL_TEXTURE_2D, texture);
   1158 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1159 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1160 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1161 		glBindTexture(GL_TEXTURE_2D, 0);
   1162 
   1163 		glViewport(0, 0, kSize, kSize);
   1164 		glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
   1165 		glBindVertexArray(m_vao);
   1166 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   1167 
   1168 		glBindTexture(GL_TEXTURE_2D, texture);
   1169 		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
   1170 
   1171 		GLuint		   c_program = CreateComputeProgram(GenC(write_value));
   1172 		std::vector<T> out_data(kSize * kSize);
   1173 		GLuint		   m_buffer;
   1174 		glGenBuffers(1, &m_buffer);
   1175 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   1176 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   1177 
   1178 		glUseProgram(c_program);
   1179 		glDispatchCompute(1, 1, 1);
   1180 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1181 		T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1182 		for (int i = 0; i < kSize * kSize; ++i)
   1183 		{
   1184 			if (!Equal(map_data[i], expected_value, internalformat))
   1185 			{
   1186 				m_context.getTestContext().getLog()
   1187 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
   1188 					<< ". Value should be: " << ToString(expected_value).c_str()
   1189 					<< ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "."
   1190 					<< tcu::TestLog::EndMessage;
   1191 				glDeleteTextures(1, &texture);
   1192 				glUseProgram(0);
   1193 				glDeleteProgram(program);
   1194 				glDeleteProgram(c_program);
   1195 				glDeleteBuffers(1, &m_buffer);
   1196 				return false;
   1197 			}
   1198 		}
   1199 		glDeleteTextures(1, &texture);
   1200 		glUseProgram(0);
   1201 		glDeleteProgram(program);
   1202 		glDeleteProgram(c_program);
   1203 		glDeleteBuffers(1, &m_buffer);
   1204 		return true;
   1205 	}
   1206 
   1207 	virtual long Cleanup()
   1208 	{
   1209 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   1210 		glDeleteVertexArrays(1, &m_vao);
   1211 		glDeleteBuffers(1, &m_vbo);
   1212 		return NO_ERROR;
   1213 	}
   1214 
   1215 	template <typename T>
   1216 	std::string GenFS(GLenum internalformat, const T& value)
   1217 	{
   1218 		std::ostringstream os;
   1219 		os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform "
   1220 		   << TypePrefix<T>() << "image2D g_image;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
   1221 								 "  imageStore(g_image, coord, "
   1222 		   << TypePrefix<T>() << "vec4" << value << ");" NL "  discard;" NL "}";
   1223 		return os.str();
   1224 	}
   1225 
   1226 	template <typename T>
   1227 	std::string GenC(const T& value)
   1228 	{
   1229 		std::ostringstream os;
   1230 		os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform "
   1231 		   << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL "  "
   1232 		   << TypePrefix<T>()
   1233 		   << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL
   1234 			  "  data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL
   1235 			  "  //data[gl_LocalInvocationIndex] = "
   1236 		   << value << ";" NL "}";
   1237 		return os.str();
   1238 	}
   1239 };
   1240 
   1241 class BasicAllFormatsStoreCS : public ShaderImageLoadStoreBase
   1242 {
   1243 	virtual long Setup()
   1244 	{
   1245 		return NO_ERROR;
   1246 	}
   1247 
   1248 	template <typename T>
   1249 	std::string GenCS(GLenum internalformat, const T& value)
   1250 	{
   1251 		std::ostringstream os;
   1252 		os << NL "#define KSIZE 4" NL "layout(" << FormatEnumToString(internalformat) << ") writeonly uniform "
   1253 		   << TypePrefix<T>()
   1254 		   << "image2D g_image;" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "void main() {" NL
   1255 			  "  ivec2 thread_xy = ivec2(gl_LocalInvocationID);" NL "  imageStore(g_image, thread_xy, "
   1256 		   << TypePrefix<T>() << "vec4" << value << ");" NL "}";
   1257 		return os.str();
   1258 	}
   1259 
   1260 	template <typename T>
   1261 	std::string GenC(const T& value)
   1262 	{
   1263 		std::ostringstream os;
   1264 		os << NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform "
   1265 		   << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL "  "
   1266 		   << TypePrefix<T>()
   1267 		   << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL
   1268 			  "  data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL
   1269 			  "  //data[gl_LocalInvocationIndex] = "
   1270 		   << TypePrefix<T>() << "vec4" << value << ";" NL "}";
   1271 		return os.str();
   1272 	}
   1273 
   1274 	template <typename T>
   1275 	bool WriteCS(GLenum internalformat, const T& write_value, const T& expected_value)
   1276 	{
   1277 		const int kSize   = 4;
   1278 		GLuint	program = CreateComputeProgram(GenCS(internalformat, write_value));
   1279 
   1280 		std::vector<T> data(kSize * kSize);
   1281 		GLuint		   texture;
   1282 		glGenTextures(1, &texture);
   1283 
   1284 		GLuint unit = 0;
   1285 		glBindTexture(GL_TEXTURE_2D, texture);
   1286 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1287 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1288 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1289 		glBindTexture(GL_TEXTURE_2D, 0);
   1290 		glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
   1291 		glUseProgram(program);
   1292 		glDispatchCompute(1, 1, 1);
   1293 
   1294 		glBindTexture(GL_TEXTURE_2D, texture);
   1295 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   1296 
   1297 		GLuint		   c_program = CreateComputeProgram(GenC(expected_value));
   1298 		std::vector<T> out_data(kSize * kSize);
   1299 		GLuint		   m_buffer;
   1300 		glGenBuffers(1, &m_buffer);
   1301 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   1302 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   1303 
   1304 		glUseProgram(c_program);
   1305 		glDispatchCompute(1, 1, 1);
   1306 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1307 		T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1308 		for (int i = 0; i < kSize * kSize; ++i)
   1309 		{
   1310 			if (!Equal(map_data[i], expected_value, internalformat))
   1311 			{
   1312 				m_context.getTestContext().getLog()
   1313 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
   1314 					<< ". Value should be: " << ToString(expected_value).c_str()
   1315 					<< ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "."
   1316 					<< tcu::TestLog::EndMessage;
   1317 				glDeleteTextures(1, &texture);
   1318 				glUseProgram(0);
   1319 				glDeleteProgram(program);
   1320 				glDeleteProgram(c_program);
   1321 				glDeleteBuffers(1, &m_buffer);
   1322 				return false;
   1323 			}
   1324 		}
   1325 		glDeleteTextures(1, &texture);
   1326 		glUseProgram(0);
   1327 		glDeleteProgram(program);
   1328 		glDeleteProgram(c_program);
   1329 		glDeleteBuffers(1, &m_buffer);
   1330 
   1331 		return true;
   1332 	}
   1333 
   1334 	virtual long Run()
   1335 	{
   1336 
   1337 		if (!WriteCS(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   1338 			return ERROR;
   1339 		if (!WriteCS(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
   1340 			return ERROR;
   1341 		if (!WriteCS(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   1342 			return ERROR;
   1343 
   1344 		if (!WriteCS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1345 			return ERROR;
   1346 		if (!WriteCS(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
   1347 			return ERROR;
   1348 		if (!WriteCS(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1349 			return ERROR;
   1350 		if (!WriteCS(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1351 			return ERROR;
   1352 
   1353 		if (!WriteCS(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1354 			return ERROR;
   1355 		if (!WriteCS(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
   1356 			return ERROR;
   1357 		if (!WriteCS(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1358 			return ERROR;
   1359 		if (!WriteCS(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   1360 			return ERROR;
   1361 
   1362 		if (!WriteCS(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
   1363 			return ERROR;
   1364 
   1365 		if (!WriteCS(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
   1366 			return ERROR;
   1367 
   1368 		return NO_ERROR;
   1369 	}
   1370 
   1371 	virtual long Cleanup()
   1372 	{
   1373 		return NO_ERROR;
   1374 	}
   1375 };
   1376 //-----------------------------------------------------------------------------
   1377 // 1.2.2 BasicAllFormatsLoad
   1378 //-----------------------------------------------------------------------------
   1379 class BasicAllFormatsLoadFS : public ShaderImageLoadStoreBase
   1380 {
   1381 	GLuint m_vao, m_vbo;
   1382 
   1383 	virtual long Setup()
   1384 	{
   1385 		m_vao = 0;
   1386 		m_vbo = 0;
   1387 		return NO_ERROR;
   1388 	}
   1389 
   1390 	virtual long Run()
   1391 	{
   1392 		if (!IsVSFSAvailable(0, 1) || !IsSSBInVSFSAvailable(1))
   1393 			return NOT_SUPPORTED;
   1394 
   1395 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   1396 
   1397 		if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT))
   1398 			return ERROR;
   1399 		if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT))
   1400 			return ERROR;
   1401 		if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT))
   1402 			return ERROR;
   1403 
   1404 		if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_INT))
   1405 			return ERROR;
   1406 		if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1), GL_RED_INTEGER, GL_INT))
   1407 			return ERROR;
   1408 		if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_SHORT))
   1409 			return ERROR;
   1410 		if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_BYTE))
   1411 			return ERROR;
   1412 
   1413 		if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   1414 			return ERROR;
   1415 		if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT))
   1416 			return ERROR;
   1417 		if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT))
   1418 			return ERROR;
   1419 		if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE))
   1420 			return ERROR;
   1421 
   1422 		if (!Read(GL_RGBA8, vec4(1.0f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE))
   1423 			return ERROR;
   1424 
   1425 		if (!Read(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE))
   1426 			return ERROR;
   1427 
   1428 		return NO_ERROR;
   1429 	}
   1430 
   1431 	template <typename T>
   1432 	bool Read(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type)
   1433 	{
   1434 		const char* src_vs =
   1435 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   1436 		GLuint			 program = BuildProgram(src_vs, GenFS(internalformat, expected_value).c_str());
   1437 		const int		 kSize   = 11;
   1438 		ShortByteData<T> d(kSize, value, internalformat, format);
   1439 		GLuint			 texture;
   1440 		glGenTextures(1, &texture);
   1441 		GLuint unit = 1;
   1442 		glBindTexture(GL_TEXTURE_2D, texture);
   1443 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1444 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1445 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1446 		if (Shorts(internalformat))
   1447 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]);
   1448 		else if (Bytes(internalformat))
   1449 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]);
   1450 		else
   1451 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]);
   1452 		glBindTexture(GL_TEXTURE_2D, 0);
   1453 
   1454 		glViewport(0, 0, kSize, kSize);
   1455 		glClear(GL_COLOR_BUFFER_BIT);
   1456 		glUseProgram(program);
   1457 		glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
   1458 		glBindVertexArray(m_vao);
   1459 
   1460 		std::vector<T> out_data(kSize * kSize);
   1461 		GLuint		   m_buffer;
   1462 		glGenBuffers(1, &m_buffer);
   1463 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   1464 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   1465 
   1466 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   1467 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1468 		T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1469 		for (int i = 0; i < kSize * kSize; ++i)
   1470 		{
   1471 			if (!Equal(map_data[i], expected_value, internalformat))
   1472 			{
   1473 				m_context.getTestContext().getLog()
   1474 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
   1475 					<< ". Value should be: " << ToString(expected_value).c_str()
   1476 					<< ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "."
   1477 					<< tcu::TestLog::EndMessage;
   1478 				glUseProgram(0);
   1479 				glDeleteProgram(program);
   1480 				glDeleteTextures(1, &texture);
   1481 				glDeleteBuffers(1, &m_buffer);
   1482 				return false;
   1483 			}
   1484 		}
   1485 		glUseProgram(0);
   1486 		glDeleteProgram(program);
   1487 		glDeleteTextures(1, &texture);
   1488 		glDeleteBuffers(1, &m_buffer);
   1489 		return true;
   1490 	}
   1491 
   1492 	virtual long Cleanup()
   1493 	{
   1494 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   1495 		glDeleteVertexArrays(1, &m_vao);
   1496 		glDeleteBuffers(1, &m_vbo);
   1497 		return NO_ERROR;
   1498 	}
   1499 
   1500 	template <typename T>
   1501 	std::string GenFS(GLenum internalformat, const T& expected_value)
   1502 	{
   1503 		std::ostringstream os;
   1504 		os << NL "#define KSIZE 11" NL "layout(" << FormatEnumToString(internalformat)
   1505 		   << ", binding = 1) readonly uniform " << TypePrefix<T>()
   1506 		   << "image2D g_image;" NL "layout(std430) buffer OutputBuffer {" NL "  " << TypePrefix<T>()
   1507 		   << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  "
   1508 		   << TypePrefix<T>() << "vec4 v = imageLoad(g_image, coord);" NL "  data[coord.y * KSIZE + coord.x] = v;" NL
   1509 								 "  //data[coord.y * KSIZE + coord.x] = "
   1510 		   << TypePrefix<T>() << "vec4" << expected_value << ";" NL "  discard;" NL "}";
   1511 		return os.str();
   1512 	}
   1513 };
   1514 
   1515 class BasicAllFormatsLoadCS : public ShaderImageLoadStoreBase
   1516 {
   1517 	virtual long Setup()
   1518 	{
   1519 		return NO_ERROR;
   1520 	}
   1521 
   1522 	template <typename T>
   1523 	std::string GenCS(GLenum internalformat, const T& expected_value)
   1524 	{
   1525 		std::ostringstream os;
   1526 		os << NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "layout("
   1527 		   << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " << TypePrefix<T>()
   1528 		   << "image2D g_image;" NL "layout(std430) buffer OutputBuffer {" NL "  " << TypePrefix<T>()
   1529 		   << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   1530 			  "  "
   1531 		   << TypePrefix<T>() << "vec4 v = imageLoad(g_image, coord);" NL "  data[gl_LocalInvocationIndex] = v;" NL
   1532 								 "  //data[gl_LocalInvocationIndex] = "
   1533 		   << TypePrefix<T>() << "vec4" << expected_value << ";" NL "}";
   1534 		return os.str();
   1535 	}
   1536 
   1537 	virtual long Run()
   1538 	{
   1539 		if (!ReadCS(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT))
   1540 			return ERROR;
   1541 		if (!ReadCS(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT))
   1542 			return ERROR;
   1543 		if (!ReadCS(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f), GL_RGBA, GL_FLOAT))
   1544 			return ERROR;
   1545 
   1546 		if (!ReadCS(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_INT))
   1547 			return ERROR;
   1548 		if (!ReadCS(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1), GL_RED_INTEGER, GL_INT))
   1549 			return ERROR;
   1550 		if (!ReadCS(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_SHORT))
   1551 			return ERROR;
   1552 		if (!ReadCS(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4), GL_RGBA_INTEGER, GL_BYTE))
   1553 			return ERROR;
   1554 
   1555 		if (!ReadCS(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   1556 			return ERROR;
   1557 		if (!ReadCS(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT))
   1558 			return ERROR;
   1559 		if (!ReadCS(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT))
   1560 			return ERROR;
   1561 		if (!ReadCS(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE))
   1562 			return ERROR;
   1563 
   1564 		if (!ReadCS(GL_RGBA8, vec4(1.0f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE))
   1565 			return ERROR;
   1566 
   1567 		if (!ReadCS(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE))
   1568 			return ERROR;
   1569 
   1570 		return NO_ERROR;
   1571 	}
   1572 
   1573 	template <typename T>
   1574 	bool ReadCS(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type)
   1575 	{
   1576 		GLuint			 program = CreateComputeProgram(GenCS(internalformat, expected_value));
   1577 		const int		 kSize   = 4;
   1578 		ShortByteData<T> d(kSize, value, internalformat, format);
   1579 		GLuint			 texture;
   1580 		glGenTextures(1, &texture);
   1581 
   1582 		GLuint unit = 1;
   1583 		glBindTexture(GL_TEXTURE_2D, texture);
   1584 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1585 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1586 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1587 		if (Shorts(internalformat))
   1588 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]);
   1589 		else if (Bytes(internalformat))
   1590 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]);
   1591 		else
   1592 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]);
   1593 		glBindTexture(GL_TEXTURE_2D, 0);
   1594 
   1595 		glUseProgram(program);
   1596 		glBindImageTexture(unit, texture, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
   1597 
   1598 		std::vector<T> out_data(kSize * kSize);
   1599 		GLuint		   m_buffer;
   1600 		glGenBuffers(1, &m_buffer);
   1601 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   1602 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   1603 
   1604 		glDispatchCompute(1, 1, 1);
   1605 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1606 		T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1607 		for (int i = 0; i < kSize * kSize; ++i)
   1608 		{
   1609 			if (!Equal(map_data[i], expected_value, internalformat))
   1610 			{
   1611 				m_context.getTestContext().getLog()
   1612 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
   1613 					<< ". Value should be: " << ToString(expected_value).c_str()
   1614 					<< ". Format is: " << FormatEnumToString(internalformat).c_str() << ". Unit is: " << unit << "."
   1615 					<< tcu::TestLog::EndMessage;
   1616 				glUseProgram(0);
   1617 				glDeleteProgram(program);
   1618 				glDeleteTextures(1, &texture);
   1619 				glDeleteBuffers(1, &m_buffer);
   1620 				return false;
   1621 			}
   1622 		}
   1623 		glUseProgram(0);
   1624 		glDeleteProgram(program);
   1625 		glDeleteTextures(1, &texture);
   1626 		glDeleteBuffers(1, &m_buffer);
   1627 		return true;
   1628 	}
   1629 
   1630 	virtual long Cleanup()
   1631 	{
   1632 		return NO_ERROR;
   1633 	}
   1634 };
   1635 
   1636 class BasicAllFormatsLoadStoreComputeStage : public ShaderImageLoadStoreBase
   1637 {
   1638 	virtual long Run()
   1639 	{
   1640 
   1641 		if (!Read(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 4.0f, 6.0f, 8.0f), GL_RGBA, GL_FLOAT))
   1642 			return ERROR;
   1643 		if (!Read(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 0.0f, 0.0f, 1.0f), GL_RED, GL_FLOAT))
   1644 			return ERROR;
   1645 		if (!Read(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(2.0f, 4.0f, 6.0f, 8.0f), GL_RGBA, GL_FLOAT))
   1646 			return ERROR;
   1647 
   1648 		if (!Read(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_INT))
   1649 			return ERROR;
   1650 		if (!Read(GL_R32I, ivec4(1, -2, 3, -4), ivec4(2, 0, 0, 1), GL_RED_INTEGER, GL_INT))
   1651 			return ERROR;
   1652 		if (!Read(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_SHORT))
   1653 			return ERROR;
   1654 		if (!Read(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(2, -4, 6, -8), GL_RGBA_INTEGER, GL_BYTE))
   1655 			return ERROR;
   1656 
   1657 		if (!Read(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   1658 			return ERROR;
   1659 		if (!Read(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(14, 0, 0, 1), GL_RED_INTEGER, GL_UNSIGNED_INT))
   1660 			return ERROR;
   1661 		if (!Read(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_SHORT))
   1662 			return ERROR;
   1663 		if (!Read(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 2, 4, 6), GL_RGBA_INTEGER, GL_UNSIGNED_BYTE))
   1664 			return ERROR;
   1665 
   1666 		if (!Read(GL_RGBA8, vec4(0.5f), vec4(1.0f), GL_RGBA, GL_UNSIGNED_BYTE))
   1667 			return ERROR;
   1668 		if (!Read(GL_RGBA8_SNORM, vec4(0.5f, 0.0f, 0.5f, -0.5f), vec4(1.0f, 0.0f, 1.0f, -1.0f), GL_RGBA, GL_BYTE))
   1669 			return ERROR;
   1670 
   1671 		return NO_ERROR;
   1672 	}
   1673 
   1674 	template <typename T>
   1675 	bool Read(GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type)
   1676 	{
   1677 		GLuint program = CreateComputeProgram(GenCS(internalformat, expected_value));
   1678 
   1679 		const int		 kSize = 8;
   1680 		ShortByteData<T> d(kSize, value, internalformat, format);
   1681 		GLuint			 texture[2];
   1682 		glGenTextures(2, texture);
   1683 
   1684 		/* read texture */
   1685 		{
   1686 			glBindTexture(GL_TEXTURE_2D, texture[0]);
   1687 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1688 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1689 			glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1690 			if (Shorts(internalformat))
   1691 				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datas[0]);
   1692 			else if (Bytes(internalformat))
   1693 				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.datab[0]);
   1694 			else
   1695 				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &d.data[0]);
   1696 		}
   1697 		/* write texture */
   1698 		{
   1699 			glBindTexture(GL_TEXTURE_2D, texture[1]);
   1700 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1701 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1702 			glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1703 		}
   1704 		glBindTexture(GL_TEXTURE_2D, 0);
   1705 
   1706 		glUseProgram(program);
   1707 
   1708 		glBindImageTexture(2, texture[0], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);
   1709 		glBindImageTexture(3, texture[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);
   1710 
   1711 		glDispatchCompute(1, 1, 1);
   1712 
   1713 		glBindTexture(GL_TEXTURE_2D, texture[1]);
   1714 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   1715 
   1716 		GLuint		   c_program = CreateComputeProgram(GenC(expected_value));
   1717 		std::vector<T> out_data(kSize * kSize);
   1718 		GLuint		   m_buffer;
   1719 		glGenBuffers(1, &m_buffer);
   1720 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   1721 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   1722 
   1723 		glUseProgram(c_program);
   1724 		glDispatchCompute(1, 1, 1);
   1725 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1726 		T* map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1727 		for (int i = 0; i < kSize * kSize; ++i)
   1728 		{
   1729 			if (!Equal(map_data[i], expected_value, internalformat))
   1730 			{
   1731 				m_context.getTestContext().getLog()
   1732 					<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[i]).c_str()
   1733 					<< ". Value should be: " << ToString(expected_value).c_str()
   1734 					<< ". Format is: " << FormatEnumToString(internalformat).c_str() << "." << tcu::TestLog::EndMessage;
   1735 				glDeleteTextures(2, texture);
   1736 				glUseProgram(0);
   1737 				glDeleteProgram(program);
   1738 				glDeleteProgram(c_program);
   1739 				glDeleteBuffers(1, &m_buffer);
   1740 				return false;
   1741 			}
   1742 		}
   1743 		glDeleteTextures(2, texture);
   1744 		glUseProgram(0);
   1745 		glDeleteProgram(program);
   1746 		glDeleteProgram(c_program);
   1747 		glDeleteBuffers(1, &m_buffer);
   1748 
   1749 		return true;
   1750 	}
   1751 
   1752 	template <typename T>
   1753 	std::string GenCS(GLenum internalformat, const T& expected_value)
   1754 	{
   1755 		std::ostringstream os;
   1756 		os << NL "#define KSIZE 8" NL "layout(local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "layout("
   1757 		   << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform " << TypePrefix<T>()
   1758 		   << "image2D g_image_read;" NL "layout(" << FormatEnumToString(internalformat)
   1759 		   << ", binding = 3) writeonly uniform " << TypePrefix<T>()
   1760 		   << "image2D g_image_write;" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL "  "
   1761 		   << TypePrefix<T>() << "vec4 v = imageLoad(g_image_read, coord);" NL
   1762 								 "  imageStore(g_image_write, coord, v+v);" NL "  //imageStore(g_image_write, coord, "
   1763 		   << TypePrefix<T>() << "vec4" << expected_value << ");" NL "}";
   1764 		return os.str();
   1765 	}
   1766 
   1767 	template <typename T>
   1768 	std::string GenC(const T& value)
   1769 	{
   1770 		std::ostringstream os;
   1771 		os << NL "#define KSIZE 8" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform "
   1772 		   << TypePrefix<T>() << "sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL "  "
   1773 		   << TypePrefix<T>()
   1774 		   << "vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL
   1775 			  "  data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL
   1776 			  "  //data[gl_LocalInvocationIndex] = "
   1777 		   << TypePrefix<T>() << "vec4" << value << ";" NL "}";
   1778 		return os.str();
   1779 	}
   1780 };
   1781 //-----------------------------------------------------------------------------
   1782 // 1.3.1 BasicAllTargetsStore
   1783 //-----------------------------------------------------------------------------
   1784 class BasicAllTargetsStoreFS : public ShaderImageLoadStoreBase
   1785 {
   1786 	GLuint m_vao;
   1787 	GLuint m_vbo;
   1788 
   1789 	virtual long Setup()
   1790 	{
   1791 		m_vao = 0;
   1792 		m_vbo = 0;
   1793 		return NO_ERROR;
   1794 	}
   1795 
   1796 	virtual long Run()
   1797 	{
   1798 		if (!IsVSFSAvailable(0, 4))
   1799 			return NOT_SUPPORTED;
   1800 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   1801 
   1802 		if (!Write(T2D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   1803 			return ERROR;
   1804 		if (!Write(T2D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1805 			return ERROR;
   1806 		if (!Write(T2D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   1807 			return ERROR;
   1808 		if (!Write(T3D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   1809 			return ERROR;
   1810 		if (!Write(T3D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1811 			return ERROR;
   1812 		if (!Write(T3D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   1813 			return ERROR;
   1814 		if (!Write(TCM, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   1815 			return ERROR;
   1816 		if (!Write(TCM, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1817 			return ERROR;
   1818 		if (!Write(TCM, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   1819 			return ERROR;
   1820 		if (!Write(T2DA, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   1821 			return ERROR;
   1822 		if (!Write(T2DA, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   1823 			return ERROR;
   1824 		if (!Write(T2DA, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   1825 			return ERROR;
   1826 
   1827 		return NO_ERROR;
   1828 	}
   1829 
   1830 	virtual long Cleanup()
   1831 	{
   1832 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   1833 		glDeleteVertexArrays(1, &m_vao);
   1834 		glDeleteBuffers(1, &m_vbo);
   1835 		glActiveTexture(GL_TEXTURE0);
   1836 		return NO_ERROR;
   1837 	}
   1838 
   1839 	template <typename T>
   1840 	bool Write(int target, GLenum internalformat, const T& write_value, const T& expected_value)
   1841 	{
   1842 		const char* src_vs =
   1843 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   1844 		const GLuint program = BuildProgram(src_vs, GenFS(target, internalformat, write_value).c_str());
   1845 		GLuint		 textures[8];
   1846 		glGenTextures(8, textures);
   1847 
   1848 		const int	  kSize = 11;
   1849 		std::vector<T> data(kSize * kSize * 2);
   1850 
   1851 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   1852 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1853 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1854 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   1855 		glBindTexture(GL_TEXTURE_2D, 0);
   1856 
   1857 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   1858 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1859 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1860 		glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2);
   1861 		glBindTexture(GL_TEXTURE_3D, 0);
   1862 
   1863 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   1864 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1865 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1866 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize);
   1867 		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   1868 
   1869 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   1870 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1871 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1872 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2);
   1873 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   1874 
   1875 		glBindImageTexture(0, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D
   1876 		glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 3D
   1877 		glBindImageTexture(2, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // Cube
   1878 		glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 2DArray
   1879 
   1880 		glUseProgram(program);
   1881 		glBindVertexArray(m_vao);
   1882 		glViewport(0, 0, kSize, kSize);
   1883 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   1884 
   1885 		glActiveTexture(GL_TEXTURE1);
   1886 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   1887 		glActiveTexture(GL_TEXTURE2);
   1888 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   1889 		glActiveTexture(GL_TEXTURE3);
   1890 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   1891 		glActiveTexture(GL_TEXTURE4);
   1892 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   1893 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   1894 
   1895 		GLuint		   c_program = CreateComputeProgram(GenC(write_value));
   1896 		std::vector<T> out_data2D(kSize * kSize * 6);
   1897 		std::vector<T> out_data3D(kSize * kSize * 6);
   1898 		std::vector<T> out_dataCube(kSize * kSize * 6);
   1899 		std::vector<T> out_data2DArray(kSize * kSize * 6);
   1900 		GLuint		   m_buffer[4];
   1901 		glGenBuffers(4, m_buffer);
   1902 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[0]);
   1903 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   1904 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
   1905 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   1906 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[2]);
   1907 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   1908 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
   1909 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   1910 
   1911 		glUseProgram(c_program);
   1912 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_2d"), 1);
   1913 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_3d"), 2);
   1914 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_cube"), 3);
   1915 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_2darray"), 4);
   1916 		glDispatchCompute(1, 1, 1);
   1917 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   1918 
   1919 		bool status = true;
   1920 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]);
   1921 		T*  map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   1922 		int layers   = 2;
   1923 		if (target == T2D)
   1924 			layers = 1;
   1925 		if (target == TCM)
   1926 			layers = 6;
   1927 		status	 = CompareValues(map_data, kSize, expected_value, internalformat, layers);
   1928 		if (!status)
   1929 			m_context.getTestContext().getLog()
   1930 				<< tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str()
   1931 				<< " format failed." << tcu::TestLog::EndMessage;
   1932 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   1933 
   1934 		glDeleteTextures(8, textures);
   1935 		glUseProgram(0);
   1936 		glDeleteProgram(program);
   1937 		glDeleteProgram(c_program);
   1938 		glDeleteBuffers(4, m_buffer);
   1939 
   1940 		return status;
   1941 	}
   1942 
   1943 	template <typename T>
   1944 	std::string GenFS(int target, GLenum internalformat, const T& write_value)
   1945 	{
   1946 		std::ostringstream os;
   1947 		switch (target)
   1948 		{
   1949 		case T2D:
   1950 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform "
   1951 			   << TypePrefix<T>() << "image2D g_image_2d;";
   1952 			break;
   1953 		case T3D:
   1954 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform "
   1955 			   << TypePrefix<T>() << "image3D g_image_3d;";
   1956 			break;
   1957 		case TCM:
   1958 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform "
   1959 			   << TypePrefix<T>() << "imageCube g_image_cube;";
   1960 			break;
   1961 		case T2DA:
   1962 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) writeonly uniform "
   1963 			   << TypePrefix<T>() << "image2DArray g_image_2darray;";
   1964 			break;
   1965 		}
   1966 		os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);";
   1967 
   1968 		switch (target)
   1969 		{
   1970 		case T2D:
   1971 			os << NL "  imageStore(g_image_2d, coord, " << TypePrefix<T>() << "vec4" << write_value << ");";
   1972 			break;
   1973 		case T3D:
   1974 			os << NL "  imageStore(g_image_3d, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   1975 			   << ");" NL "  imageStore(g_image_3d, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   1976 			   << ");";
   1977 			break;
   1978 		case TCM:
   1979 			os << NL "  imageStore(g_image_cube, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   1980 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   1981 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 2), " << TypePrefix<T>() << "vec4" << write_value
   1982 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 3), " << TypePrefix<T>() << "vec4" << write_value
   1983 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 4), " << TypePrefix<T>() << "vec4" << write_value
   1984 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 5), " << TypePrefix<T>() << "vec4" << write_value
   1985 			   << ");";
   1986 			break;
   1987 		case T2DA:
   1988 			os << NL "  imageStore(g_image_2darray, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   1989 			   << ");" NL "  imageStore(g_image_2darray, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   1990 			   << ");";
   1991 			break;
   1992 		}
   1993 		os << NL "  discard;" NL "}";
   1994 		return os.str();
   1995 	}
   1996 
   1997 	template <typename T>
   1998 	std::string GenC(const T& write_value)
   1999 	{
   2000 		std::ostringstream os;
   2001 		os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform "
   2002 		   << TypePrefix<T>() << "sampler2D g_sampler_2d;" NL "uniform " << TypePrefix<T>()
   2003 		   << "sampler3D g_sampler_3d;" NL "uniform " << TypePrefix<T>() << "samplerCube g_sampler_cube;" NL "uniform "
   2004 		   << TypePrefix<T>()
   2005 		   << "sampler2DArray g_sampler_2darray;" NL "layout(std430, binding = 1) buffer OutputBuffer2D {" NL "  "
   2006 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;" NL
   2007 								 "layout(std430, binding = 0) buffer OutputBuffer3D {" NL "  "
   2008 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;" NL
   2009 								 "layout(std430, binding = 3) buffer OutputBufferCube {" NL "  "
   2010 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;" NL
   2011 								 "layout(std430, binding = 2) buffer OutputBuffer2DArray {" NL "  "
   2012 		   << TypePrefix<T>()
   2013 		   << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;" NL "void main() {" NL
   2014 			  "  int cubemap_i = 2 * int(gl_LocalInvocationID.x) - KSIZE + 1;" NL
   2015 			  "  int cubemap_j = 2 * int(gl_LocalInvocationID.y) - KSIZE + 1;" NL
   2016 			  "  uint layer = uint(KSIZE * KSIZE);" NL
   2017 			  "  g_buff_2d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_2d, ivec2(gl_LocalInvocationID), 0);" NL
   2018 			  "  g_buff_3d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_3d, ivec3(gl_LocalInvocationID.xy, 0), "
   2019 			  "0);" NL "  g_buff_3d.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_3d, "
   2020 			  "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL "  g_buff_2darray.data[gl_LocalInvocationIndex] = "
   2021 			  "texelFetch(g_sampler_2darray, "
   2022 			  "ivec3(gl_LocalInvocationID.xy, 0), 0);" NL
   2023 			  "  g_buff_2darray.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_2darray, "
   2024 			  "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL "  g_buff_cube.data[gl_LocalInvocationIndex] = "
   2025 			  "texture(g_sampler_cube, vec3(KSIZE,cubemap_i,cubemap_j));" NL
   2026 			  "  g_buff_cube.data[gl_LocalInvocationIndex + layer] = texture(g_sampler_cube, "
   2027 			  "vec3(KSIZE,cubemap_i,cubemap_j));" NL "  g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = "
   2028 			  "texture(g_sampler_cube, vec3(cubemap_i,KSIZE,cubemap_j));" NL
   2029 			  "  g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = texture(g_sampler_cube, "
   2030 			  "vec3(cubemap_i,KSIZE,cubemap_j));" NL "  g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = "
   2031 			  "texture(g_sampler_cube, vec3(cubemap_i,cubemap_j,KSIZE));" NL
   2032 			  "  g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = texture(g_sampler_cube, "
   2033 			  "vec3(cubemap_i,cubemap_j,KSIZE));" NL "  //g_buff_2d.data[gl_LocalInvocationIndex] = "
   2034 		   << write_value << ";" NL "}";
   2035 		return os.str();
   2036 	}
   2037 };
   2038 
   2039 class BasicAllTargetsStoreCS : public ShaderImageLoadStoreBase
   2040 {
   2041 	virtual long Setup()
   2042 	{
   2043 		return NO_ERROR;
   2044 	}
   2045 
   2046 	virtual long Run()
   2047 	{
   2048 
   2049 		if (!Write(T2D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   2050 			return ERROR;
   2051 		if (!Write(T2D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   2052 			return ERROR;
   2053 		if (!Write(T2D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   2054 			return ERROR;
   2055 		if (!Write(T3D, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   2056 			return ERROR;
   2057 		if (!Write(T3D, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   2058 			return ERROR;
   2059 		if (!Write(T3D, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   2060 			return ERROR;
   2061 		if (!Write(TCM, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   2062 			return ERROR;
   2063 		if (!Write(TCM, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   2064 			return ERROR;
   2065 		if (!Write(TCM, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   2066 			return ERROR;
   2067 		if (!Write(T2DA, GL_RGBA32F, vec4(-1.0f, 2.0f, 3.0f, -4.0f), vec4(-1.0f, 2.0f, 3.0f, -4.0f)))
   2068 			return ERROR;
   2069 		if (!Write(T2DA, GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   2070 			return ERROR;
   2071 		if (!Write(T2DA, GL_RGBA32UI, uvec4(1, 2, 3, 4), uvec4(1, 2, 3, 4)))
   2072 			return ERROR;
   2073 
   2074 		return NO_ERROR;
   2075 	}
   2076 
   2077 	virtual long Cleanup()
   2078 	{
   2079 		glActiveTexture(GL_TEXTURE0);
   2080 		return NO_ERROR;
   2081 	}
   2082 
   2083 	template <typename T>
   2084 	bool Write(int target, GLenum internalformat, const T& write_value, const T& expected_value)
   2085 	{
   2086 		const GLuint program = CreateComputeProgram(GenCS(target, internalformat, write_value));
   2087 		GLuint		 textures[8];
   2088 		glGenTextures(8, textures);
   2089 
   2090 		const int	  kSize = 11;
   2091 		std::vector<T> data(kSize * kSize * 2);
   2092 
   2093 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   2094 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2095 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2096 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   2097 		glBindTexture(GL_TEXTURE_2D, 0);
   2098 
   2099 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   2100 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2101 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2102 		glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2);
   2103 		glBindTexture(GL_TEXTURE_3D, 0);
   2104 
   2105 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   2106 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2107 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2108 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize);
   2109 		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   2110 
   2111 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   2112 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2113 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2114 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2);
   2115 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   2116 
   2117 		glBindImageTexture(0, textures[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D
   2118 		glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 3D
   2119 		glBindImageTexture(2, textures[4], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // Cube
   2120 		glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 2DArray
   2121 
   2122 		glUseProgram(program);
   2123 		glDispatchCompute(1, 1, 1);
   2124 
   2125 		glActiveTexture(GL_TEXTURE1);
   2126 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   2127 		glActiveTexture(GL_TEXTURE2);
   2128 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   2129 		glActiveTexture(GL_TEXTURE3);
   2130 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   2131 		glActiveTexture(GL_TEXTURE4);
   2132 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   2133 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   2134 
   2135 		GLuint		   c_program = CreateComputeProgram(GenC(write_value));
   2136 		std::vector<T> out_data2D(kSize * kSize * 6);
   2137 		std::vector<T> out_data3D(kSize * kSize * 6);
   2138 		std::vector<T> out_dataCube(kSize * kSize * 6);
   2139 		std::vector<T> out_data2DArray(kSize * kSize * 6);
   2140 		GLuint		   m_buffer[4];
   2141 		glGenBuffers(4, m_buffer);
   2142 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
   2143 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2144 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
   2145 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2146 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[2]);
   2147 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2148 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[3]);
   2149 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2150 
   2151 		glUseProgram(c_program);
   2152 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_2d"), 1);
   2153 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_3d"), 2);
   2154 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_cube"), 3);
   2155 		glUniform1i(glGetUniformLocation(c_program, "g_sampler_2darray"), 4);
   2156 
   2157 		glDispatchCompute(1, 1, 1);
   2158 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   2159 
   2160 		bool status = true;
   2161 
   2162 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]);
   2163 		T*  map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   2164 		int layers   = 2;
   2165 		if (target == T2D)
   2166 			layers = 1;
   2167 		if (target == TCM)
   2168 			layers = 6;
   2169 		status	 = CompareValues(map_data, kSize, expected_value, internalformat, layers);
   2170 		if (!status)
   2171 			m_context.getTestContext().getLog()
   2172 				<< tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str()
   2173 				<< " format failed." << tcu::TestLog::EndMessage;
   2174 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   2175 
   2176 		glDeleteTextures(8, textures);
   2177 		glUseProgram(0);
   2178 		glDeleteProgram(program);
   2179 		glDeleteProgram(c_program);
   2180 		glDeleteBuffers(4, m_buffer);
   2181 
   2182 		return status;
   2183 	}
   2184 
   2185 	template <typename T>
   2186 	std::string GenCS(int target, GLenum internalformat, const T& write_value)
   2187 	{
   2188 		std::ostringstream os;
   2189 		os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;";
   2190 		switch (target)
   2191 		{
   2192 		case T2D:
   2193 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform "
   2194 			   << TypePrefix<T>() << "image2D g_image_2d;";
   2195 			break;
   2196 		case T3D:
   2197 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform "
   2198 			   << TypePrefix<T>() << "image3D g_image_3d;";
   2199 			break;
   2200 		case TCM:
   2201 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) writeonly uniform "
   2202 			   << TypePrefix<T>() << "imageCube g_image_cube;";
   2203 			break;
   2204 		case T2DA:
   2205 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) writeonly uniform "
   2206 			   << TypePrefix<T>() << "image2DArray g_image_2darray;";
   2207 			break;
   2208 		}
   2209 		os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);";
   2210 		switch (target)
   2211 		{
   2212 		case T2D:
   2213 			os << NL "  imageStore(g_image_2d, coord, " << TypePrefix<T>() << "vec4" << write_value << ");";
   2214 			break;
   2215 		case T3D:
   2216 			os << NL "  imageStore(g_image_3d, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   2217 			   << ");" NL "  imageStore(g_image_3d, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   2218 			   << ");";
   2219 			break;
   2220 		case TCM:
   2221 			os << NL "  imageStore(g_image_cube, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   2222 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   2223 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 2), " << TypePrefix<T>() << "vec4" << write_value
   2224 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 3), " << TypePrefix<T>() << "vec4" << write_value
   2225 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 4), " << TypePrefix<T>() << "vec4" << write_value
   2226 			   << ");" NL "  imageStore(g_image_cube, ivec3(coord, 5), " << TypePrefix<T>() << "vec4" << write_value
   2227 			   << ");";
   2228 			break;
   2229 		case T2DA:
   2230 			os << NL "  imageStore(g_image_2darray, ivec3(coord, 0), " << TypePrefix<T>() << "vec4" << write_value
   2231 			   << ");" NL "  imageStore(g_image_2darray, ivec3(coord, 1), " << TypePrefix<T>() << "vec4" << write_value
   2232 			   << ");";
   2233 			break;
   2234 		}
   2235 		os << NL "}";
   2236 		return os.str();
   2237 	}
   2238 
   2239 	template <typename T>
   2240 	std::string GenC(const T& write_value)
   2241 	{
   2242 		std::ostringstream os;
   2243 		os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL "uniform "
   2244 		   << TypePrefix<T>() << "sampler2D g_sampler_2d;" NL "uniform " << TypePrefix<T>()
   2245 		   << "sampler3D g_sampler_3d;" NL "uniform " << TypePrefix<T>() << "samplerCube g_sampler_cube;" NL "uniform "
   2246 		   << TypePrefix<T>()
   2247 		   << "sampler2DArray g_sampler_2darray;" NL "layout(std430, binding = 0) buffer OutputBuffer2D {" NL "  "
   2248 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;" NL
   2249 								 "layout(std430, binding = 1) buffer OutputBuffer3D {" NL "  "
   2250 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;" NL
   2251 								 "layout(std430, binding = 2) buffer OutputBufferCube {" NL "  "
   2252 		   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;" NL
   2253 								 "layout(std430, binding = 3) buffer OutputBuffer2DArray {" NL "  "
   2254 		   << TypePrefix<T>()
   2255 		   << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;" NL "void main() {" NL
   2256 			  "  int cubemap_i = 2 * int(gl_LocalInvocationID.x) - KSIZE + 1;" NL
   2257 			  "  int cubemap_j = 2 * int(gl_LocalInvocationID.y) - KSIZE + 1;" NL
   2258 			  "  uint layer = uint(KSIZE * KSIZE);" NL
   2259 			  "  g_buff_2d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_2d, ivec2(gl_LocalInvocationID), 0);" NL
   2260 			  "  g_buff_3d.data[gl_LocalInvocationIndex] = texelFetch(g_sampler_3d, ivec3(gl_LocalInvocationID.xy, 0), "
   2261 			  "0);" NL "  g_buff_3d.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_3d, "
   2262 			  "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL "  g_buff_2darray.data[gl_LocalInvocationIndex] = "
   2263 			  "texelFetch(g_sampler_2darray, "
   2264 			  "ivec3(gl_LocalInvocationID.xy, 0), 0);" NL
   2265 			  "  g_buff_2darray.data[gl_LocalInvocationIndex + layer] = texelFetch(g_sampler_2darray, "
   2266 			  "ivec3(gl_LocalInvocationID.xy, 1), 0);" NL "  g_buff_cube.data[gl_LocalInvocationIndex] = "
   2267 			  "texture(g_sampler_cube, vec3(KSIZE,cubemap_i,cubemap_j));" NL
   2268 			  "  g_buff_cube.data[gl_LocalInvocationIndex + layer] = texture(g_sampler_cube, "
   2269 			  "vec3(KSIZE,cubemap_i,cubemap_j));" NL "  g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = "
   2270 			  "texture(g_sampler_cube, vec3(cubemap_i,KSIZE,cubemap_j));" NL
   2271 			  "  g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = texture(g_sampler_cube, "
   2272 			  "vec3(cubemap_i,KSIZE,cubemap_j));" NL "  g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = "
   2273 			  "texture(g_sampler_cube, vec3(cubemap_i,cubemap_j,KSIZE));" NL
   2274 			  "  g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = texture(g_sampler_cube, "
   2275 			  "vec3(cubemap_i,cubemap_j,KSIZE));" NL "  //g_buff_2d.data[gl_LocalInvocationIndex] = "
   2276 		   << write_value << ";" NL "}";
   2277 		return os.str();
   2278 	}
   2279 };
   2280 //-----------------------------------------------------------------------------
   2281 // 1.3.2.1 BasicAllTargetsLoad
   2282 //-----------------------------------------------------------------------------
   2283 class BasicAllTargetsLoadFS : public ShaderImageLoadStoreBase
   2284 {
   2285 	GLuint m_vao;
   2286 	GLuint m_vbo;
   2287 
   2288 	virtual long Setup()
   2289 	{
   2290 		m_vao = 0;
   2291 		m_vbo = 0;
   2292 		return NO_ERROR;
   2293 	}
   2294 
   2295 	virtual long Run()
   2296 	{
   2297 		if (!IsVSFSAvailable(0, 4) || !IsSSBInVSFSAvailable(4))
   2298 			return NOT_SUPPORTED;
   2299 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   2300 
   2301 		if (!Read(T2D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2302 				  GL_FLOAT))
   2303 			return ERROR;
   2304 		if (!Read(T2D, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2305 			return ERROR;
   2306 		if (!Read(T2D, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2307 			return ERROR;
   2308 		if (!Read(T3D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2309 				  GL_FLOAT))
   2310 			return ERROR;
   2311 		if (!Read(T3D, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2312 			return ERROR;
   2313 		if (!Read(T3D, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2314 			return ERROR;
   2315 		if (!Read(TCM, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2316 				  GL_FLOAT))
   2317 			return ERROR;
   2318 		if (!Read(TCM, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2319 			return ERROR;
   2320 		if (!Read(TCM, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2321 			return ERROR;
   2322 		if (!Read(T2DA, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2323 				  GL_FLOAT))
   2324 			return ERROR;
   2325 		if (!Read(T2DA, GL_RGBA32I, ivec4(-1, 10, -200, 3000), ivec4(-1, 10, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2326 			return ERROR;
   2327 		if (!Read(T2DA, GL_RGBA32UI, uvec4(1, 10, 200, 3000), uvec4(1, 10, 200, 3000), GL_RGBA_INTEGER,
   2328 				  GL_UNSIGNED_INT))
   2329 			return ERROR;
   2330 
   2331 		return NO_ERROR;
   2332 	}
   2333 
   2334 	virtual long Cleanup()
   2335 	{
   2336 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   2337 		glDeleteVertexArrays(1, &m_vao);
   2338 		glDeleteBuffers(1, &m_vbo);
   2339 		return NO_ERROR;
   2340 	}
   2341 
   2342 	template <typename T>
   2343 	bool Read(int target, GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type)
   2344 	{
   2345 		const char* src_vs =
   2346 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   2347 		const GLuint program = BuildProgram(src_vs, GenFS(target, internalformat, expected_value).c_str());
   2348 		GLuint		 textures[8];
   2349 		glGenTextures(8, textures);
   2350 
   2351 		const int	  kSize = 11;
   2352 		std::vector<T> data(kSize * kSize * 2, value);
   2353 
   2354 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   2355 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2356 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2357 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   2358 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2359 		glBindTexture(GL_TEXTURE_2D, 0);
   2360 
   2361 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   2362 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2363 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2364 		glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2);
   2365 		glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]);
   2366 		glBindTexture(GL_TEXTURE_3D, 0);
   2367 
   2368 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   2369 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2370 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2371 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize);
   2372 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2373 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2374 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2375 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2376 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2377 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2378 		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   2379 
   2380 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   2381 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2382 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2383 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2);
   2384 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]);
   2385 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   2386 
   2387 		glBindImageTexture(2, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D
   2388 		glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 3D
   2389 		glBindImageTexture(3, textures[4], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // Cube
   2390 		glBindImageTexture(1, textures[7], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 2DArray
   2391 
   2392 		std::vector<T> out_data2D(kSize * kSize * 6);
   2393 		std::vector<T> out_data3D(kSize * kSize * 6);
   2394 		std::vector<T> out_dataCube(kSize * kSize * 6);
   2395 		std::vector<T> out_data2DArray(kSize * kSize * 6);
   2396 		GLuint		   m_buffer[4];
   2397 		glGenBuffers(4, m_buffer);
   2398 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[0]);
   2399 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2400 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[1]);
   2401 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2402 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[2]);
   2403 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2404 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[3]);
   2405 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2406 
   2407 		glUseProgram(program);
   2408 		glClear(GL_COLOR_BUFFER_BIT);
   2409 		glBindVertexArray(m_vao);
   2410 		glViewport(0, 0, kSize, kSize);
   2411 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   2412 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   2413 
   2414 		bool status = true;
   2415 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]);
   2416 		T*  map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   2417 		int layers   = 2;
   2418 		if (target == T2D)
   2419 			layers = 1;
   2420 		if (target == TCM)
   2421 			layers = 6;
   2422 		status	 = CompareValues(map_data, kSize, expected_value, internalformat, layers);
   2423 		if (!status)
   2424 			m_context.getTestContext().getLog()
   2425 				<< tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str()
   2426 				<< " format failed." << tcu::TestLog::EndMessage;
   2427 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   2428 
   2429 		glUseProgram(0);
   2430 		glDeleteProgram(program);
   2431 		glDeleteTextures(8, textures);
   2432 		glDeleteBuffers(4, m_buffer);
   2433 
   2434 		return status;
   2435 	}
   2436 
   2437 	template <typename T>
   2438 	std::string GenFS(int target, GLenum internalformat, const T& expected_value)
   2439 	{
   2440 		std::ostringstream os;
   2441 		os << NL "#define KSIZE 11";
   2442 		switch (target)
   2443 		{
   2444 		case T2D:
   2445 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform "
   2446 			   << TypePrefix<T>()
   2447 			   << "image2D g_image_2d;" NL "layout(std430, binding = 1) buffer OutputBuffer2D {" NL "  "
   2448 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;";
   2449 			break;
   2450 		case T3D:
   2451 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) readonly uniform "
   2452 			   << TypePrefix<T>()
   2453 			   << "image3D g_image_3d;" NL "layout(std430, binding = 0) buffer OutputBuffer3D {" NL "  "
   2454 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;";
   2455 			break;
   2456 		case TCM:
   2457 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform "
   2458 			   << TypePrefix<T>()
   2459 			   << "imageCube g_image_cube;" NL "layout(std430, binding = 3) buffer OutputBufferCube {" NL "  "
   2460 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;";
   2461 			break;
   2462 		case T2DA:
   2463 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform "
   2464 			   << TypePrefix<T>()
   2465 			   << "image2DArray g_image_2darray;" NL "layout(std430, binding = 2) buffer OutputBuffer2DArray {" NL "  "
   2466 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;";
   2467 			break;
   2468 		}
   2469 		os << NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
   2470 				 "  int coordIndex = coord.x + KSIZE * coord.y;" NL "  int layer = int(KSIZE * KSIZE);" NL "  "
   2471 		   << TypePrefix<T>() << "vec4 v;";
   2472 
   2473 		switch (target)
   2474 		{
   2475 		case T2D:
   2476 			os << NL "  v = imageLoad(g_image_2d, coord);" NL "  g_buff_2d.data[coordIndex] = v;";
   2477 			break;
   2478 		case T3D:
   2479 			os << NL "  v = imageLoad(g_image_3d, ivec3(coord.xy, 0));" NL "  g_buff_3d.data[coordIndex] = v;" NL
   2480 					 "  v = imageLoad(g_image_3d, ivec3(coord.xy, 1));" NL "  g_buff_3d.data[coordIndex + layer] = v;";
   2481 			break;
   2482 		case TCM:
   2483 			os << NL
   2484 				"  v = imageLoad(g_image_cube, ivec3(coord, 0));" NL "  g_buff_cube.data[coordIndex] = v;" NL
   2485 				"  v = imageLoad(g_image_cube, ivec3(coord, 1));" NL "  g_buff_cube.data[coordIndex + layer] = v;" NL
   2486 				"  v = imageLoad(g_image_cube, ivec3(coord, 2));" NL
   2487 				"  g_buff_cube.data[coordIndex + 2 * layer] = v;" NL
   2488 				"  v = imageLoad(g_image_cube, ivec3(coord, 3));" NL
   2489 				"  g_buff_cube.data[coordIndex + 3 * layer] = v;" NL
   2490 				"  v = imageLoad(g_image_cube, ivec3(coord, 4));" NL
   2491 				"  g_buff_cube.data[coordIndex + 4 * layer] = v;" NL
   2492 				"  v = imageLoad(g_image_cube, ivec3(coord, 5));" NL "  g_buff_cube.data[coordIndex + 5 * layer] = v;";
   2493 			break;
   2494 		case T2DA:
   2495 			os << NL "  v = imageLoad(g_image_2darray, ivec3(coord, 0));" NL "  g_buff_2darray.data[coordIndex] = v;" NL
   2496 					 "  v = imageLoad(g_image_2darray, ivec3(coord, 1));" NL
   2497 					 "  g_buff_2darray.data[coordIndex + layer] = v;";
   2498 			break;
   2499 		}
   2500 		os << NL "  //g_buff_2d.data[coordIndex] = " << expected_value << ";" NL "}";
   2501 		return os.str();
   2502 	}
   2503 };
   2504 
   2505 class BasicAllTargetsLoadCS : public ShaderImageLoadStoreBase
   2506 {
   2507 	virtual long Setup()
   2508 	{
   2509 		return NO_ERROR;
   2510 	}
   2511 
   2512 	virtual long Run()
   2513 	{
   2514 		if (!Read(T2D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2515 				  GL_FLOAT))
   2516 			return ERROR;
   2517 		if (!Read(T2D, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000),
   2518 				  ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2519 			return ERROR;
   2520 		if (!Read(T2D, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000),
   2521 				  uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2522 			return ERROR;
   2523 		if (!Read(T3D, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2524 				  GL_FLOAT))
   2525 			return ERROR;
   2526 		if (!Read(T3D, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000),
   2527 				  ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2528 			return ERROR;
   2529 		if (!Read(T3D, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000),
   2530 				  uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2531 			return ERROR;
   2532 		if (!Read(TCM, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2533 				  GL_FLOAT))
   2534 			return ERROR;
   2535 		if (!Read(TCM, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000),
   2536 				  ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2537 			return ERROR;
   2538 		if (!Read(TCM, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000),
   2539 				  uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2540 			return ERROR;
   2541 		if (!Read(T2DA, GL_RGBA32F, vec4(-1.0f, 10.0f, -200.0f, 3000.0f), vec4(-1.0f, 10.0f, -200.0f, 3000.0f), GL_RGBA,
   2542 				  GL_FLOAT))
   2543 			return ERROR;
   2544 		if (!Read(T2DA, GL_RGBA32I, ivec4(-0x7fffffff, 0x7fffffff, -200, 3000),
   2545 				  ivec4(-0x7fffffff, 0x7fffffff, -200, 3000), GL_RGBA_INTEGER, GL_INT))
   2546 			return ERROR;
   2547 		if (!Read(T2DA, GL_RGBA32UI, uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000),
   2548 				  uvec4(0xffffffffu, 0x7fffffff, 0x80000000, 3000), GL_RGBA_INTEGER, GL_UNSIGNED_INT))
   2549 			return ERROR;
   2550 
   2551 		return NO_ERROR;
   2552 	}
   2553 
   2554 	virtual long Cleanup()
   2555 	{
   2556 		return NO_ERROR;
   2557 	}
   2558 
   2559 	template <typename T>
   2560 	bool Read(int target, GLenum internalformat, const T& value, const T& expected_value, GLenum format, GLenum type)
   2561 	{
   2562 		const GLuint program = CreateComputeProgram(GenCS(target, internalformat, expected_value));
   2563 		GLuint		 textures[8];
   2564 		glGenTextures(8, textures);
   2565 
   2566 		const int	  kSize = 11;
   2567 		std::vector<T> data(kSize * kSize * 2, value);
   2568 
   2569 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   2570 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2571 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2572 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   2573 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2574 		glBindTexture(GL_TEXTURE_2D, 0);
   2575 
   2576 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   2577 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2578 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2579 		glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 2);
   2580 		glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]);
   2581 		glBindTexture(GL_TEXTURE_3D, 0);
   2582 
   2583 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   2584 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2585 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2586 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize);
   2587 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2588 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2589 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2590 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2591 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2592 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, format, type, &data[0]);
   2593 		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   2594 
   2595 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   2596 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2597 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2598 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 2);
   2599 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 2, format, type, &data[0]);
   2600 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   2601 
   2602 		glBindImageTexture(2, textures[1], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D
   2603 		glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 3D
   2604 		glBindImageTexture(3, textures[4], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // Cube
   2605 		glBindImageTexture(1, textures[7], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 2DArray
   2606 
   2607 		std::vector<T> out_data2D(kSize * kSize * 6);
   2608 		std::vector<T> out_data3D(kSize * kSize * 6);
   2609 		std::vector<T> out_dataCube(kSize * kSize * 6);
   2610 		std::vector<T> out_data2DArray(kSize * kSize * 6);
   2611 		GLuint		   m_buffer[4];
   2612 		glGenBuffers(4, m_buffer);
   2613 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer[0]);
   2614 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2615 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_buffer[1]);
   2616 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2617 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_buffer[2]);
   2618 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2619 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_buffer[3]);
   2620 		glBufferData(GL_SHADER_STORAGE_BUFFER, 6 * kSize * kSize * 4 * 4, &out_dataCube[0], GL_STATIC_DRAW);
   2621 
   2622 		glUseProgram(program);
   2623 		glDispatchCompute(1, 1, 1);
   2624 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   2625 
   2626 		bool status = true;
   2627 
   2628 		glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer[target]);
   2629 		T*  map_data = (T*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 6 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   2630 		int layers   = 2;
   2631 		if (target == T2D)
   2632 			layers = 1;
   2633 		if (target == TCM)
   2634 			layers = 6;
   2635 		status	 = CompareValues(map_data, kSize, expected_value, internalformat, layers);
   2636 		if (!status)
   2637 			m_context.getTestContext().getLog()
   2638 				<< tcu::TestLog::Message << target << " target, " << FormatEnumToString(internalformat).c_str()
   2639 				<< " format failed." << tcu::TestLog::EndMessage;
   2640 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   2641 
   2642 		glUseProgram(0);
   2643 		glDeleteProgram(program);
   2644 		glDeleteTextures(8, textures);
   2645 		glDeleteBuffers(4, m_buffer);
   2646 
   2647 		return status;
   2648 	}
   2649 
   2650 	template <typename T>
   2651 	std::string GenCS(int target, GLenum internalformat, const T& expected_value)
   2652 	{
   2653 		std::ostringstream os;
   2654 		os << NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;";
   2655 		switch (target)
   2656 		{
   2657 		case T2D:
   2658 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) readonly uniform "
   2659 			   << TypePrefix<T>()
   2660 			   << "image2D g_image_2d;" NL "layout(std430, binding = 0) buffer OutputBuffer2D {" NL "  "
   2661 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE];" NL "} g_buff_2d;";
   2662 			break;
   2663 		case T3D:
   2664 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) readonly uniform "
   2665 			   << TypePrefix<T>()
   2666 			   << "image3D g_image_3d;" NL "layout(std430, binding = 1) buffer OutputBuffer3D {" NL "  "
   2667 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_3d;";
   2668 			break;
   2669 		case TCM:
   2670 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform "
   2671 			   << TypePrefix<T>()
   2672 			   << "imageCube g_image_cube;" NL "layout(std430, binding = 2) buffer OutputBufferCube {" NL "  "
   2673 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*6];" NL "} g_buff_cube;";
   2674 			break;
   2675 		case T2DA:
   2676 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform "
   2677 			   << TypePrefix<T>()
   2678 			   << "image2DArray g_image_2darray;" NL "layout(std430, binding = 3) buffer OutputBuffer2DArray {" NL "  "
   2679 			   << TypePrefix<T>() << "vec4 data[KSIZE*KSIZE*2];" NL "} g_buff_2darray;";
   2680 			break;
   2681 		}
   2682 		os << NL "void main() {" NL "  ivec3 coord = ivec3(gl_LocalInvocationID.xy, 0);" NL
   2683 				 "  uint layer = uint(KSIZE * KSIZE);" NL "  "
   2684 		   << TypePrefix<T>() << "vec4 v;";
   2685 		switch (target)
   2686 		{
   2687 		case T2D:
   2688 			os << NL "  v = imageLoad(g_image_2d, coord.xy);" NL "  g_buff_2d.data[gl_LocalInvocationIndex] = v;";
   2689 			break;
   2690 		case T3D:
   2691 			os << NL "  v = imageLoad(g_image_3d, coord);" NL "  g_buff_3d.data[gl_LocalInvocationIndex] = v;" NL
   2692 					 "  v = imageLoad(g_image_3d, ivec3(coord.xy, 1));" NL
   2693 					 "  g_buff_3d.data[gl_LocalInvocationIndex + layer] = v;";
   2694 			break;
   2695 		case TCM:
   2696 			os << NL "  v = imageLoad(g_image_cube, coord);" NL "  g_buff_cube.data[gl_LocalInvocationIndex] = v;" NL
   2697 					 "  v = imageLoad(g_image_cube, ivec3(coord.xy, 1));" NL
   2698 					 "  g_buff_cube.data[gl_LocalInvocationIndex + layer] = v;" NL
   2699 					 "  v = imageLoad(g_image_cube, ivec3(coord.xy, 2));" NL
   2700 					 "  g_buff_cube.data[gl_LocalInvocationIndex + 2u * layer] = v;" NL
   2701 					 "  v = imageLoad(g_image_cube, ivec3(coord.xy, 3));" NL
   2702 					 "  g_buff_cube.data[gl_LocalInvocationIndex + 3u * layer] = v;" NL
   2703 					 "  v = imageLoad(g_image_cube, ivec3(coord.xy, 4));" NL
   2704 					 "  g_buff_cube.data[gl_LocalInvocationIndex + 4u * layer] = v;" NL
   2705 					 "  v = imageLoad(g_image_cube, ivec3(coord.xy, 5));" NL
   2706 					 "  g_buff_cube.data[gl_LocalInvocationIndex + 5u * layer] = v;";
   2707 			break;
   2708 		case T2DA:
   2709 			os << NL "  v = imageLoad(g_image_2darray, coord);" NL
   2710 					 "  g_buff_2darray.data[gl_LocalInvocationIndex] = v;" NL
   2711 					 "  v = imageLoad(g_image_2darray, ivec3(coord.xy, 1));" NL
   2712 					 "  g_buff_2darray.data[gl_LocalInvocationIndex + layer] = v;";
   2713 			break;
   2714 		}
   2715 		os << NL "  //g_buff_2d.data[gl_LocalInvocationIndex] = " << expected_value << ";" NL "}";
   2716 		return os.str();
   2717 	}
   2718 };
   2719 //-----------------------------------------------------------------------------
   2720 // 1.3.3 BasicAllTargetsAtomic
   2721 //-----------------------------------------------------------------------------
   2722 class BasicAllTargetsAtomicFS : public ShaderImageLoadStoreBase
   2723 {
   2724 	GLuint m_vao;
   2725 	GLuint m_vbo;
   2726 
   2727 	virtual long Setup()
   2728 	{
   2729 		m_vao = 0;
   2730 		m_vbo = 0;
   2731 		return NO_ERROR;
   2732 	}
   2733 
   2734 	virtual long Run()
   2735 	{
   2736 		if (!IsImageAtomicSupported())
   2737 			return NOT_SUPPORTED;
   2738 		if (!IsVSFSAvailable(0, 4))
   2739 			return NOT_SUPPORTED;
   2740 		if (!AreOutputsAvailable(5))
   2741 			return NOT_SUPPORTED;
   2742 		if (!IsSSBInVSFSAvailable(1))
   2743 			return NOT_SUPPORTED;
   2744 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   2745 
   2746 		if (!Atomic<GLint>(GL_R32I))
   2747 			return ERROR;
   2748 		if (!Atomic<GLuint>(GL_R32UI))
   2749 			return ERROR;
   2750 
   2751 		return NO_ERROR;
   2752 	}
   2753 
   2754 	virtual long Cleanup()
   2755 	{
   2756 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   2757 		glDeleteVertexArrays(1, &m_vao);
   2758 		glDeleteBuffers(1, &m_vbo);
   2759 		return NO_ERROR;
   2760 	}
   2761 
   2762 	template <typename T>
   2763 	bool Atomic(GLenum internalformat)
   2764 	{
   2765 		const char* src_vs =
   2766 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   2767 		const GLuint program = BuildProgram(src_vs, GenFS<T>(internalformat).c_str(), false, true);
   2768 		GLuint		 textures[8];
   2769 		GLuint		 buffer;
   2770 		glGenTextures(8, textures);
   2771 		glGenBuffers(1, &buffer);
   2772 
   2773 		const int	  kSize = 11;
   2774 		std::vector<T> data(kSize * kSize * 3);
   2775 
   2776 		glBindTexture(GL_TEXTURE_2D, textures[1]);
   2777 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2778 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2779 		glTexStorage2D(GL_TEXTURE_2D, 1, internalformat, kSize, kSize);
   2780 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2781 		glBindTexture(GL_TEXTURE_2D, 0);
   2782 
   2783 		glBindTexture(GL_TEXTURE_3D, textures[2]);
   2784 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2785 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2786 		glTexStorage3D(GL_TEXTURE_3D, 1, internalformat, kSize, kSize, 3);
   2787 		glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, kSize, kSize, 3, Format<T>(), Type<T>(), &data[0]);
   2788 		glBindTexture(GL_TEXTURE_3D, 0);
   2789 
   2790 		glBindTexture(GL_TEXTURE_CUBE_MAP, textures[4]);
   2791 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2792 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2793 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalformat, kSize, kSize);
   2794 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2795 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2796 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2797 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2798 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2799 		glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, kSize, kSize, Format<T>(), Type<T>(), &data[0]);
   2800 		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
   2801 
   2802 		glBindTexture(GL_TEXTURE_2D_ARRAY, textures[7]);
   2803 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2804 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2805 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, internalformat, kSize, kSize, 3);
   2806 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 3, Format<T>(), Type<T>(), &data[0]);
   2807 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   2808 
   2809 		glBindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat); // 2D
   2810 		glBindImageTexture(2, textures[2], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // 3D
   2811 		glBindImageTexture(0, textures[4], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // Cube
   2812 		glBindImageTexture(3, textures[7], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // 2DArray
   2813 
   2814 		std::vector<ivec4> o_data(kSize * kSize);
   2815 		GLuint			   m_buffer;
   2816 		glGenBuffers(1, &m_buffer);
   2817 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   2818 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW);
   2819 
   2820 		glUseProgram(program);
   2821 		glClear(GL_COLOR_BUFFER_BIT);
   2822 		glBindVertexArray(m_vao);
   2823 		glViewport(0, 0, kSize, kSize);
   2824 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   2825 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   2826 
   2827 		bool status = true;
   2828 
   2829 		ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   2830 		for (int i = 0; i < kSize * kSize; ++i)
   2831 		{
   2832 			if (!Equal(out_data[i], ivec4(10, 10, 10, 10), 0))
   2833 			{
   2834 				status = false;
   2835 				m_context.getTestContext().getLog()
   2836 					<< tcu::TestLog::Message << "[" << i
   2837 					<< "] Atomic operation check failed. (operation/target coded: " << ToString(out_data[i]).c_str()
   2838 					<< ")" << tcu::TestLog::EndMessage;
   2839 			}
   2840 		}
   2841 
   2842 		glUseProgram(0);
   2843 		glDeleteProgram(program);
   2844 		glDeleteTextures(8, textures);
   2845 		glDeleteBuffers(1, &buffer);
   2846 		glDeleteBuffers(1, &m_buffer);
   2847 
   2848 		return status;
   2849 	}
   2850 
   2851 	template <typename T>
   2852 	std::string GenFS(GLenum internalformat)
   2853 	{
   2854 		std::ostringstream os;
   2855 		os << NL "#define KSIZE 11" NL "layout(" << FormatEnumToString(internalformat)
   2856 		   << ", binding = 1) coherent uniform " << TypePrefix<T>() << "image2D g_image_2d;" NL "layout("
   2857 		   << FormatEnumToString(internalformat) << ", binding = 2) coherent uniform " << TypePrefix<T>()
   2858 		   << "image3D g_image_3d;" NL "layout(" << FormatEnumToString(internalformat)
   2859 		   << ", binding = 0) coherent uniform " << TypePrefix<T>() << "imageCube g_image_cube;" NL "layout("
   2860 		   << FormatEnumToString(internalformat) << ", binding = 3) coherent uniform " << TypePrefix<T>()
   2861 		   << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL
   2862 			  "  ivec4 o_color[KSIZE*KSIZE];" NL "};" NL
   2863 		   << TypePrefix<T>() << "vec2 t(int i) {" NL "  return " << TypePrefix<T>()
   2864 		   << "vec2(i);" NL "}" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
   2865 			  "  int coordIndex = coord.x + KSIZE * coord.y;" NL "  o_color[coordIndex] = ivec4(coordIndex);" NL
   2866 			  "  if (imageAtomicAdd(g_image_2d, coord, t(2).x) != t(0).x) o_color[coordIndex].x = 1;" NL
   2867 			  "  else if (imageAtomicMin(g_image_2d, coord, t(3).x) != t(2).x) o_color[coordIndex].x = 2;" NL
   2868 			  "  else if (imageAtomicMax(g_image_2d, coord, t(4).x) != t(2).x) o_color[coordIndex].x = 3;" NL
   2869 			  "  else if (imageAtomicAnd(g_image_2d, coord, t(0).x) != t(4).x) o_color[coordIndex].x = 4;" NL
   2870 			  "  else if (imageAtomicOr(g_image_2d, coord, t(7).x) != t(0).x) o_color[coordIndex].x = 5;" NL
   2871 			  "  else if (imageAtomicXor(g_image_2d, coord, t(4).x) != t(7).x) o_color[coordIndex].x = 6;" NL
   2872 			  "  else if (imageAtomicExchange(g_image_2d, coord, t(1).x) != t(3).x) o_color[coordIndex].x = 7;" NL
   2873 			  "  else if (imageAtomicCompSwap(g_image_2d, coord, t(1).x, t(6).x) != t(1).x) o_color[coordIndex].x = "
   2874 			  "8;" NL "  else o_color[coordIndex].x = 10;" NL
   2875 			  "  if (imageAtomicAdd(g_image_3d, ivec3(coord, 2), t(2).x) != t(0).x) o_color[coordIndex].y = 1;" NL
   2876 			  "  else if (imageAtomicMin(g_image_3d, ivec3(coord, 2), t(3).x) != t(2).x) o_color[coordIndex].y = 2;" NL
   2877 			  "  else if (imageAtomicMax(g_image_3d, ivec3(coord, 2), t(4).x) != t(2).x) o_color[coordIndex].y = 3;" NL
   2878 			  "  else if (imageAtomicAnd(g_image_3d, ivec3(coord, 2), t(0).x) != t(4).x) o_color[coordIndex].y = 4;" NL
   2879 			  "  else if (imageAtomicOr(g_image_3d, ivec3(coord, 2), t(7).x) != t(0).x) o_color[coordIndex].y = 5;" NL
   2880 			  "  else if (imageAtomicXor(g_image_3d, ivec3(coord, 2), t(4).x) != t(7).x) o_color[coordIndex].y = 6;" NL
   2881 			  "  else if (imageAtomicExchange(g_image_3d, ivec3(coord, 2), t(1).x) != t(3).x) o_color[coordIndex].y = "
   2882 			  "7;" NL "  else if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 2), t(1).x, t(6).x) != t(1).x) "
   2883 			  "o_color[coordIndex].y = 8;" NL "  else o_color[coordIndex].y = 10;" NL
   2884 			  "  if (imageAtomicAdd(g_image_cube, ivec3(coord, 3), t(2).x) != t(0).x) o_color[coordIndex].z = 1;" NL
   2885 			  "  else if (imageAtomicMin(g_image_cube, ivec3(coord, 3), t(3).x) != t(2).x) o_color[coordIndex].z = "
   2886 			  "2;" NL "  else if (imageAtomicMax(g_image_cube, ivec3(coord, 3), t(4).x) != t(2).x) "
   2887 			  "o_color[coordIndex].z = 3;" NL "  else if (imageAtomicAnd(g_image_cube, ivec3(coord, 3), "
   2888 			  "t(0).x) != t(4).x) o_color[coordIndex].z = 4;" NL
   2889 			  "  else if (imageAtomicOr(g_image_cube, ivec3(coord, 3), t(7).x) != t(0).x) o_color[coordIndex].z = 5;" NL
   2890 			  "  else if (imageAtomicXor(g_image_cube, ivec3(coord, 3), t(4).x) != t(7).x) o_color[coordIndex].z = "
   2891 			  "6;" NL "  else if (imageAtomicExchange(g_image_cube, ivec3(coord, 3), t(1).x) != t(3).x) "
   2892 			  "o_color[coordIndex].z = 7;" NL "  else if (imageAtomicCompSwap(g_image_cube, ivec3(coord, 3), "
   2893 			  "t(1).x, t(6).x) != t(1).x) o_color[coordIndex].z = 8;" NL "  else o_color[coordIndex].z = 10;" NL
   2894 			  "  if (imageAtomicAdd(g_image_2darray, ivec3(coord, 2), t(2).x) != t(0).x) o_color[coordIndex].w = 1;" NL
   2895 			  "  else if (imageAtomicMin(g_image_2darray, ivec3(coord, 2), t(3).x) != t(2).x) o_color[coordIndex].w = "
   2896 			  "2;" NL "  else if (imageAtomicMax(g_image_2darray, ivec3(coord, 2), t(4).x) != t(2).x) "
   2897 			  "o_color[coordIndex].w = 3;" NL "  else if (imageAtomicAnd(g_image_2darray, ivec3(coord, 2), "
   2898 			  "t(0).x) != t(4).x) o_color[coordIndex].w = 4;" NL
   2899 			  "  else if (imageAtomicOr(g_image_2darray, ivec3(coord, 2), t(7).x) != t(0).x) o_color[coordIndex].w = "
   2900 			  "5;" NL "  else if (imageAtomicXor(g_image_2darray, ivec3(coord, 2), t(4).x) != t(7).x) "
   2901 			  "o_color[coordIndex].w = 6;" NL "  else if (imageAtomicExchange(g_image_2darray, ivec3(coord, "
   2902 			  "2), t(1).x) != t(3).x) o_color[coordIndex].w = 7;" NL
   2903 			  "  else if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 2), t(1).x, t(6).x) != t(1).x) "
   2904 			  "o_color[coordIndex].w = 8;" NL "  else o_color[coordIndex].w = 10;" NL "  discard;" NL "}";
   2905 		return os.str();
   2906 	}
   2907 };
   2908 //-----------------------------------------------------------------------------
   2909 // LoadStoreMachine
   2910 //-----------------------------------------------------------------------------
   2911 class LoadStoreMachine : public ShaderImageLoadStoreBase
   2912 {
   2913 	GLuint m_vao;
   2914 	GLuint m_buffer;
   2915 	int	m_stage;
   2916 
   2917 	virtual long Setup()
   2918 	{
   2919 		glEnable(GL_RASTERIZER_DISCARD);
   2920 		glGenVertexArrays(1, &m_vao);
   2921 		glGenBuffers(1, &m_buffer);
   2922 		return NO_ERROR;
   2923 	}
   2924 
   2925 	virtual long Cleanup()
   2926 	{
   2927 		glDisable(GL_RASTERIZER_DISCARD);
   2928 		glDeleteVertexArrays(1, &m_vao);
   2929 		glDeleteBuffers(1, &m_buffer);
   2930 		return NO_ERROR;
   2931 	}
   2932 
   2933 	template <typename T>
   2934 	bool Write(GLenum internalformat, const T& write_value, const T& expected_value)
   2935 	{
   2936 		const GLenum targets[]	 = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY };
   2937 		const int	kTargets	  = sizeof(targets) / sizeof(targets[0]);
   2938 		const int	kSize		   = 100;
   2939 		GLuint		 program_store = 0;
   2940 		GLuint		 program_load  = 0;
   2941 		if (m_stage == 0)
   2942 		{ // VS
   2943 			const char* src_fs = NL "void main() {" NL "  discard;" NL "}";
   2944 			program_store	  = BuildProgram(GenStoreShader(m_stage, internalformat, write_value).c_str(), src_fs);
   2945 			program_load	   = BuildProgram(GenLoadShader(m_stage, internalformat, expected_value).c_str(), src_fs);
   2946 		}
   2947 		else if (m_stage == 4)
   2948 		{ // CS
   2949 			program_store = CreateComputeProgram(GenStoreShader(m_stage, internalformat, write_value));
   2950 			program_load  = CreateComputeProgram(GenLoadShader(m_stage, internalformat, expected_value));
   2951 		}
   2952 		GLuint textures[kTargets];
   2953 		glGenTextures(kTargets, textures);
   2954 
   2955 		for (int i = 0; i < kTargets; ++i)
   2956 		{
   2957 			glBindTexture(targets[i], textures[i]);
   2958 			glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   2959 			glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   2960 
   2961 			if (targets[i] == GL_TEXTURE_2D)
   2962 			{
   2963 				glTexStorage2D(targets[i], 1, internalformat, kSize, 1);
   2964 			}
   2965 			else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY)
   2966 			{
   2967 				glTexStorage3D(targets[i], 1, internalformat, kSize, 1, 2);
   2968 			}
   2969 			else if (targets[i] == GL_TEXTURE_CUBE_MAP)
   2970 			{
   2971 				glTexStorage2D(targets[i], 1, internalformat, kSize, kSize);
   2972 			}
   2973 		}
   2974 		glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat); // 2D
   2975 		glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 3D
   2976 		glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // Cube
   2977 		glBindImageTexture(3, textures[3], 0, GL_TRUE, 0, GL_WRITE_ONLY, internalformat);  // 2DArray
   2978 
   2979 		std::vector<ivec4> b_data(kSize);
   2980 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   2981 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * 4 * 4, &b_data[0], GL_STATIC_DRAW);
   2982 
   2983 		glUseProgram(program_store);
   2984 		glBindVertexArray(m_vao);
   2985 		if (m_stage == 4)
   2986 		{ // CS
   2987 			glDispatchCompute(1, 1, 1);
   2988 		}
   2989 		else if (m_stage == 0)
   2990 		{ // VS
   2991 			glDrawArrays(GL_POINTS, 0, kSize);
   2992 		}
   2993 		bool status = true;
   2994 		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
   2995 
   2996 		glBindImageTexture(3, textures[0], 0, GL_FALSE, 0, GL_READ_ONLY, internalformat); // 2D
   2997 		glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 3D
   2998 		glBindImageTexture(1, textures[2], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // Cube
   2999 		glBindImageTexture(0, textures[3], 0, GL_TRUE, 0, GL_READ_ONLY, internalformat);  // 2DArray
   3000 
   3001 		glUseProgram(program_load);
   3002 		if (m_stage == 0)
   3003 		{ // VS
   3004 			glDrawArrays(GL_POINTS, 0, kSize);
   3005 		}
   3006 		else if (m_stage == 4)
   3007 		{ // CS
   3008 			glDispatchCompute(1, 1, 1);
   3009 		}
   3010 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3011 
   3012 		ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * 4 * 4, GL_MAP_READ_BIT);
   3013 		for (int i = 0; i < kSize; ++i)
   3014 		{
   3015 			if (!Equal(out_data[i], ivec4(0, 1, 0, 1), 0))
   3016 			{
   3017 				status = false;
   3018 				m_context.getTestContext().getLog()
   3019 					<< tcu::TestLog::Message << "[" << i << "] load/store operation check failed. ("
   3020 					<< ToString(out_data[i]).c_str() << ")" << tcu::TestLog::EndMessage;
   3021 			}
   3022 		}
   3023 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   3024 		glUseProgram(0);
   3025 		glDeleteProgram(program_store);
   3026 		glDeleteProgram(program_load);
   3027 		glDeleteTextures(kTargets, textures);
   3028 		return status;
   3029 	}
   3030 
   3031 	template <typename T>
   3032 	std::string GenStoreShader(int stage, GLenum internalformat, const T& write_value)
   3033 	{
   3034 		std::ostringstream os;
   3035 		if (stage == 4)
   3036 		{ // CS
   3037 			os << NL "#define KSIZE 100" NL "layout(local_size_x = KSIZE) in;";
   3038 		}
   3039 		os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) writeonly uniform "
   3040 		   << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat)
   3041 		   << ", binding = 2) writeonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout("
   3042 		   << FormatEnumToString(internalformat) << ", binding = 0) writeonly uniform " << TypePrefix<T>()
   3043 		   << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat)
   3044 		   << ", binding = 3) writeonly uniform " << TypePrefix<T>()
   3045 		   << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL "  ivec4 o_color;" NL "};" NL
   3046 			  "void main() {" NL "  "
   3047 		   << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4(o_color) + " << TypePrefix<T>() << "vec4"
   3048 		   << write_value
   3049 		   << ";" NL "  int g_index[6] = int[](o_color.x, o_color.y, o_color.z, o_color.w, o_color.r, o_color.g);";
   3050 		if (stage == 0)
   3051 		{ // VS
   3052 			os << NL "  ivec2 coord = ivec2(gl_VertexID, g_index[0]);";
   3053 		}
   3054 		else if (stage == 4)
   3055 		{ // CS
   3056 			os << NL "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);";
   3057 		}
   3058 		os << NL "  imageStore(g_image_2d, coord, g_value);" NL
   3059 				 "  imageStore(g_image_3d, ivec3(coord.xy, g_index[0]), g_value);" NL
   3060 				 "  imageStore(g_image_3d, ivec3(coord.xy, g_index[1]), g_value);" NL
   3061 				 "  for (int i = 0; i < 6; ++i) {" NL
   3062 				 "    imageStore(g_image_cube, ivec3(coord, g_index[i]), g_value);" NL "  }" NL
   3063 				 "  imageStore(g_image_2darray, ivec3(coord, g_index[0]), g_value);" NL
   3064 				 "  imageStore(g_image_2darray, ivec3(coord, g_index[1]), g_value);" NL "}";
   3065 		return os.str();
   3066 	}
   3067 
   3068 	template <typename T>
   3069 	std::string GenLoadShader(int stage, GLenum internalformat, const T& expected_value)
   3070 	{
   3071 		std::ostringstream os;
   3072 		os << NL "#define KSIZE 100";
   3073 		if (stage == 4)
   3074 		{ // CS
   3075 			os << NL "layout(local_size_x = KSIZE) in;";
   3076 		}
   3077 		os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) readonly uniform "
   3078 		   << TypePrefix<T>() << "image2D g_image_2d;" NL "layout(" << FormatEnumToString(internalformat)
   3079 		   << ", binding = 2) readonly uniform " << TypePrefix<T>() << "image3D g_image_3d;" NL "layout("
   3080 		   << FormatEnumToString(internalformat) << ", binding = 1) readonly uniform " << TypePrefix<T>()
   3081 		   << "imageCube g_image_cube;" NL "layout(" << FormatEnumToString(internalformat)
   3082 		   << ", binding = 0) readonly uniform " << TypePrefix<T>()
   3083 		   << "image2DArray g_image_2darray;" NL "layout(std430) buffer out_data {" NL "  ivec4 o_color[KSIZE];" NL
   3084 			  "};" NL "void main() {";
   3085 
   3086 		if (stage == 0)
   3087 		{ // VS
   3088 			os << NL "  " << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>() << "vec4(o_color[gl_VertexID]) + "
   3089 			   << TypePrefix<T>() << "vec4" << expected_value << ";";
   3090 		}
   3091 		else if (stage == 4)
   3092 		{ // CS
   3093 			os << NL "  " << TypePrefix<T>() << "vec4 g_value = " << TypePrefix<T>()
   3094 			   << "vec4(o_color[gl_GlobalInvocationID.x]) + " << TypePrefix<T>() << "vec4" << expected_value << ";";
   3095 		}
   3096 
   3097 		os << NL "  int g_index[6] = int[](o_color[0].x, o_color[0].y, o_color[0].z, o_color[0].w, o_color[1].r, "
   3098 				 "o_color[1].g);";
   3099 		if (stage == 0)
   3100 		{ // VS
   3101 			os << NL "  ivec2 coord = ivec2(gl_VertexID, g_index[0]);";
   3102 		}
   3103 		else if (stage == 4)
   3104 		{ // CS
   3105 			os << NL "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_index[0]);";
   3106 		}
   3107 		os << NL "  vec4 r = vec4(0.0, 1.0, 0.0, 1.0);" NL "  " << TypePrefix<T>()
   3108 		   << "vec4 v;" NL "  v = imageLoad(g_image_2d, coord);" NL
   3109 			  "  if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 2.0);" NL
   3110 			  "  v = imageLoad(g_image_3d, ivec3(coord, g_index[0]));" NL
   3111 			  "  if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 3.0);" NL
   3112 			  "  v = imageLoad(g_image_cube, ivec3(coord, g_index[0]));" NL
   3113 			  "  if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 6.0);" NL
   3114 			  "  v = imageLoad(g_image_2darray, ivec3(coord, g_index[0]));" NL
   3115 			  "  if (v != g_value) r = vec4(1.0, 0.0, float(coord.x), 23.0);" NL "  o_color[coord.x] = ivec4(r);" NL
   3116 			  "}";
   3117 		return os.str();
   3118 	}
   3119 
   3120 protected:
   3121 	long RunStage(int stage)
   3122 	{
   3123 		m_stage = stage;
   3124 		if (!AreOutputsAvailable(5))
   3125 			return NOT_SUPPORTED;
   3126 
   3127 		if (!Write(GL_RGBA32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   3128 			return ERROR;
   3129 		if (!Write(GL_R32F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 0.0f, 0.0f, 1.0f)))
   3130 			return ERROR;
   3131 		if (!Write(GL_RGBA16F, vec4(1.0f, 2.0f, 3.0f, 4.0f), vec4(1.0f, 2.0f, 3.0f, 4.0f)))
   3132 			return ERROR;
   3133 
   3134 		if (!Write(GL_RGBA32I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   3135 			return ERROR;
   3136 		if (!Write(GL_R32I, ivec4(1, -2, 3, -4), ivec4(1, 0, 0, 1)))
   3137 			return ERROR;
   3138 		if (!Write(GL_RGBA16I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   3139 			return ERROR;
   3140 		if (!Write(GL_RGBA8I, ivec4(1, -2, 3, -4), ivec4(1, -2, 3, -4)))
   3141 			return ERROR;
   3142 
   3143 		if (!Write(GL_RGBA32UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   3144 			return ERROR;
   3145 		if (!Write(GL_R32UI, uvec4(7, 2, 3, 4), uvec4(7, 0, 0, 1)))
   3146 			return ERROR;
   3147 		if (!Write(GL_RGBA16UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   3148 			return ERROR;
   3149 		if (!Write(GL_RGBA8UI, uvec4(0, 1, 2, 3), uvec4(0, 1, 2, 3)))
   3150 			return ERROR;
   3151 
   3152 		if (!Write(GL_RGBA8, vec4(1.0f), vec4(1.0f)))
   3153 			return ERROR;
   3154 
   3155 		if (!Write(GL_RGBA8_SNORM, vec4(1.0f, -1.0f, 1.0f, -1.0f), vec4(1.0f, -1.0f, 1.0f, -1.0f)))
   3156 			return ERROR;
   3157 
   3158 		return NO_ERROR;
   3159 	}
   3160 };
   3161 
   3162 //-----------------------------------------------------------------------------
   3163 // AtomicMachine
   3164 //-----------------------------------------------------------------------------
   3165 class AtomicMachine : public ShaderImageLoadStoreBase
   3166 {
   3167 	GLuint m_vao;
   3168 	GLuint m_buffer;
   3169 
   3170 	virtual long Setup()
   3171 	{
   3172 		glEnable(GL_RASTERIZER_DISCARD);
   3173 		glGenVertexArrays(1, &m_vao);
   3174 		glGenBuffers(1, &m_buffer);
   3175 		return NO_ERROR;
   3176 	}
   3177 
   3178 	virtual long Cleanup()
   3179 	{
   3180 		glDisable(GL_RASTERIZER_DISCARD);
   3181 		glDeleteVertexArrays(1, &m_vao);
   3182 		glDeleteBuffers(1, &m_buffer);
   3183 		return NO_ERROR;
   3184 	}
   3185 
   3186 	template <typename T>
   3187 	bool Atomic(int target, int stage, GLenum internalformat)
   3188 	{
   3189 		GLuint program = 0;
   3190 		if (stage == 0)
   3191 		{ // VS
   3192 			const char* src_fs = NL "void main() {" NL "  discard;" NL "}";
   3193 			program			   = BuildProgram(GenShader<T>(target, stage, internalformat).c_str(), src_fs, true, false);
   3194 		}
   3195 		else if (stage == 4)
   3196 		{ // CS
   3197 			program = CreateComputeProgram(GenShader<T>(target, stage, internalformat), true);
   3198 		}
   3199 
   3200 		const GLenum targets[] = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY };
   3201 		const int	kTargets  = sizeof(targets) / sizeof(targets[0]);
   3202 		const int	kSize	 = 100;
   3203 
   3204 		GLuint textures[kTargets];
   3205 		glGenTextures(kTargets, textures);
   3206 
   3207 		for (int i = 0; i < kTargets; ++i)
   3208 		{
   3209 			glBindTexture(targets[i], textures[i]);
   3210 			glTexParameteri(targets[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3211 			glTexParameteri(targets[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3212 			if (targets[i] == GL_TEXTURE_2D)
   3213 			{
   3214 				glTexStorage2D(targets[i], 1, internalformat, kSize, 1);
   3215 			}
   3216 			else if (targets[i] == GL_TEXTURE_3D || targets[i] == GL_TEXTURE_2D_ARRAY)
   3217 			{
   3218 				glTexStorage3D(targets[i], 1, internalformat, kSize, 1, 2);
   3219 			}
   3220 			else if (targets[i] == GL_TEXTURE_CUBE_MAP)
   3221 			{
   3222 				glTexStorage2D(targets[i], 1, internalformat, kSize, kSize);
   3223 			}
   3224 		}
   3225 		glBindImageTexture(1, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, internalformat); // 2D
   3226 		glBindImageTexture(2, textures[1], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // 3D
   3227 		glBindImageTexture(0, textures[2], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // Cube
   3228 		glBindImageTexture(3, textures[3], 0, GL_TRUE, 0, GL_READ_WRITE, internalformat);  // 2DArray
   3229 
   3230 		std::vector<ivec4> b_data(kSize);
   3231 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3232 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * 4 * 4, &b_data[0], GL_STATIC_DRAW);
   3233 
   3234 		glUseProgram(program);
   3235 		glBindVertexArray(m_vao);
   3236 		if (stage == 0)
   3237 		{ // VS
   3238 			glDrawArrays(GL_POINTS, 0, kSize);
   3239 		}
   3240 		else if (stage == 4)
   3241 		{ // CS
   3242 			glDispatchCompute(1, 1, 1);
   3243 		}
   3244 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3245 
   3246 		bool   status   = true;
   3247 		ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * 4 * 4, GL_MAP_READ_BIT);
   3248 		for (int i = 0; i < kSize; ++i)
   3249 		{
   3250 			if (!Equal(out_data[i], ivec4(0, 1, 0, 1), 0))
   3251 			{
   3252 				status = false;
   3253 				m_context.getTestContext().getLog()
   3254 					<< tcu::TestLog::Message << "[" << i << "] Atomic operation check failed. ("
   3255 					<< ToString(out_data[i]).c_str() << ")" << tcu::TestLog::EndMessage;
   3256 			}
   3257 		}
   3258 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   3259 		glUseProgram(0);
   3260 		glDeleteProgram(program);
   3261 		glDeleteTextures(kTargets, textures);
   3262 		return status;
   3263 	}
   3264 
   3265 	template <typename T>
   3266 	std::string GenShader(int target, int stage, GLenum internalformat)
   3267 	{
   3268 		std::ostringstream os;
   3269 		os << NL "#define KSIZE 100";
   3270 		if (stage == 4)
   3271 		{ // CS
   3272 			os << NL "layout(local_size_x = KSIZE) in;";
   3273 		}
   3274 		switch (target)
   3275 		{
   3276 		case T2D:
   3277 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 1) coherent uniform "
   3278 			   << TypePrefix<T>() << "image2D g_image_2d;";
   3279 			break;
   3280 		case T3D:
   3281 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 2) coherent uniform "
   3282 			   << TypePrefix<T>() << "image3D g_image_3d;";
   3283 			break;
   3284 		case TCM:
   3285 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 0) coherent uniform "
   3286 			   << TypePrefix<T>() << "imageCube g_image_cube;";
   3287 			break;
   3288 		case T2DA:
   3289 			os << NL "layout(" << FormatEnumToString(internalformat) << ", binding = 3) coherent uniform "
   3290 			   << TypePrefix<T>() << "image2DArray g_image_2darray;";
   3291 			break;
   3292 		}
   3293 		os << NL "layout(std430) buffer out_data {" NL "  ivec4 o_color[KSIZE];" NL "} r;" NL << TypePrefix<T>()
   3294 		   << "vec2 t(int i) {" NL "  return " << TypePrefix<T>()
   3295 		   << "vec2(i);" NL "}" NL "void main() {" NL "  int g_value[6] = int[](r.o_color[0].x, r.o_color[0].y+1, "
   3296 			  "r.o_color[0].z+2, r.o_color[0].w+3, r.o_color[1].r+4, "
   3297 			  "r.o_color[1].g+5);";
   3298 		if (stage == 0)
   3299 		{ // VS
   3300 			os << NL "  ivec2 coord = ivec2(gl_VertexID, g_value[0]);";
   3301 		}
   3302 		else if (stage == 4)
   3303 		{ // CS
   3304 			os << NL "  ivec2 coord = ivec2(gl_GlobalInvocationID.x, g_value[0]);";
   3305 		}
   3306 		os << NL "  ivec4 o_color = ivec4(0, 1, 0, 1);";
   3307 
   3308 		switch (target)
   3309 		{
   3310 		case T2D:
   3311 			os << NL "  ivec4 i = ivec4(1, 0, 0, 2);" NL "  imageAtomicExchange(g_image_2d, coord, t(0).x);" NL
   3312 					 "  if (imageAtomicAdd(g_image_2d, coord, t(2).x) != t(0).x) o_color = i;" NL
   3313 					 "  if (imageAtomicMin(g_image_2d, coord, t(3).x) != t(2).x) o_color = i;" NL
   3314 					 "  if (imageAtomicMax(g_image_2d, coord, t(4).x) != t(2).x) o_color = i;" NL
   3315 					 "  if (imageAtomicAnd(g_image_2d, coord, t(0).x) != t(4).x) o_color = i;" NL
   3316 					 "  if (imageAtomicOr(g_image_2d, coord, t(7).x) != t(0).x) o_color = i;" NL
   3317 					 "  if (imageAtomicXor(g_image_2d, coord, t(4).x) != t(7).x) o_color = i;" NL
   3318 					 "  if (imageAtomicExchange(g_image_2d, coord, t(1).x) != t(3).x) o_color = i;" NL
   3319 					 "  if (imageAtomicCompSwap(g_image_2d, coord, t(1).x, t(6).x) != t(1).x) o_color = i;" NL
   3320 					 "  if (imageAtomicExchange(g_image_2d, coord, t(0).x) != t(6).x) o_color = i;";
   3321 			break;
   3322 		case T3D:
   3323 			os << NL "  ivec4 i = ivec4(1, 0, 0, 3);" NL
   3324 					 "  imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(0).x);" NL
   3325 					 "  if (imageAtomicAdd(g_image_3d, ivec3(coord, 0), t(2).x) != t(0).x) o_color = i;" NL
   3326 					 "  if (imageAtomicMin(g_image_3d, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL
   3327 					 "  if (imageAtomicMax(g_image_3d, ivec3(coord, g_value[0]), t(4).x) != t(2).x) o_color = i;" NL
   3328 					 "  if (imageAtomicAnd(g_image_3d, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL
   3329 					 "  if (imageAtomicOr(g_image_3d, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL
   3330 					 "  if (imageAtomicXor(g_image_3d, ivec3(coord, 0), t(4).x) != t(7).x) o_color = i;" NL
   3331 					 "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL
   3332 					 "  if (imageAtomicCompSwap(g_image_3d, ivec3(coord, 0), t(1).x, t(6).x) != t(1).x) o_color = i;" NL
   3333 					 "  if (imageAtomicExchange(g_image_3d, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;";
   3334 			break;
   3335 		case TCM:
   3336 			os << NL
   3337 				"  ivec4 i = ivec4(1, 0, 0, 6);" NL "  imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(0).x);" NL
   3338 				"  if (imageAtomicAdd(g_image_cube, ivec3(coord, 0), t(g_value[2]).x) != t(0).x) o_color = i;" NL
   3339 				"  if (imageAtomicMin(g_image_cube, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL
   3340 				"  if (imageAtomicMax(g_image_cube, ivec3(coord, 0), t(4).x) != t(2).x) o_color = i;" NL
   3341 				"  if (imageAtomicAnd(g_image_cube, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL
   3342 				"  if (imageAtomicOr(g_image_cube, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL
   3343 				"  if (imageAtomicXor(g_image_cube, ivec3(coord, 0), t(4).x) != t(7).x) o_color = i;" NL
   3344 				"  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL
   3345 				"  if (imageAtomicCompSwap(g_image_cube, ivec3(coord, g_value[0]), t(1).x, t(6).x) != t(1).x) o_color "
   3346 				"= i;" NL "  if (imageAtomicExchange(g_image_cube, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;";
   3347 			break;
   3348 		case T2DA:
   3349 			os << NL
   3350 				"  ivec4 i = ivec4(1, 0, 0, 23);" NL
   3351 				"  imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(0).x);" NL
   3352 				"  if (imageAtomicAdd(g_image_2darray, ivec3(coord, 0), t(2).x) != t(0).x) o_color = i;" NL
   3353 				"  if (imageAtomicMin(g_image_2darray, ivec3(coord, 0), t(3).x) != t(2).x) o_color = i;" NL
   3354 				"  if (imageAtomicMax(g_image_2darray, ivec3(coord, 0), t(4).x) != t(2).x) o_color = i;" NL
   3355 				"  if (imageAtomicAnd(g_image_2darray, ivec3(coord, 0), t(0).x) != t(4).x) o_color = i;" NL
   3356 				"  if (imageAtomicOr(g_image_2darray, ivec3(coord, 0), t(7).x) != t(0).x) o_color = i;" NL
   3357 				"  if (imageAtomicXor(g_image_2darray, ivec3(coord, 0), t(g_value[4]).x) != t(7).x) o_color = i;" NL
   3358 				"  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(1).x) != t(3).x) o_color = i;" NL
   3359 				"  if (imageAtomicCompSwap(g_image_2darray, ivec3(coord, 0), t(1).x, t(6).x) != t(1).x) o_color = i;" NL
   3360 				"  if (imageAtomicExchange(g_image_2darray, ivec3(coord, 0), t(0).x) != t(6).x) o_color = i;";
   3361 			break;
   3362 		}
   3363 		os << NL "  r.o_color[coord.x] = o_color;" NL "}";
   3364 		return os.str();
   3365 	}
   3366 
   3367 protected:
   3368 	long RunStage(int stage)
   3369 	{
   3370 		if (!IsImageAtomicSupported())
   3371 			return NOT_SUPPORTED;
   3372 		if (!Atomic<GLint>(T2D, stage, GL_R32I))
   3373 			return ERROR;
   3374 		if (!Atomic<GLuint>(T2D, stage, GL_R32UI))
   3375 			return ERROR;
   3376 		if (!Atomic<GLint>(T3D, stage, GL_R32I))
   3377 			return ERROR;
   3378 		if (!Atomic<GLuint>(T3D, stage, GL_R32UI))
   3379 			return ERROR;
   3380 		if (!Atomic<GLint>(TCM, stage, GL_R32I))
   3381 			return ERROR;
   3382 		if (!Atomic<GLuint>(TCM, stage, GL_R32UI))
   3383 			return ERROR;
   3384 		if (!Atomic<GLint>(T2DA, stage, GL_R32I))
   3385 			return ERROR;
   3386 		if (!Atomic<GLuint>(T2DA, stage, GL_R32UI))
   3387 			return ERROR;
   3388 		return NO_ERROR;
   3389 	}
   3390 };
   3391 
   3392 //-----------------------------------------------------------------------------
   3393 // 1.3.4 BasicAllTargetsLoadStoreVS
   3394 //-----------------------------------------------------------------------------
   3395 class BasicAllTargetsLoadStoreVS : public LoadStoreMachine
   3396 {
   3397 	virtual long Run()
   3398 	{
   3399 		if (!IsVSFSAvailable(4, 0) || !IsSSBInVSFSAvailable(1))
   3400 			return NOT_SUPPORTED;
   3401 		return RunStage(0);
   3402 	}
   3403 };
   3404 
   3405 //-----------------------------------------------------------------------------
   3406 // 1.3.8 BasicAllTargetsLoadStoreCS
   3407 //-----------------------------------------------------------------------------
   3408 class BasicAllTargetsLoadStoreCS : public LoadStoreMachine
   3409 {
   3410 	virtual long Run()
   3411 	{
   3412 		return RunStage(4);
   3413 	}
   3414 };
   3415 
   3416 //-----------------------------------------------------------------------------
   3417 // 1.3.9 BasicAllTargetsAtomicVS
   3418 //-----------------------------------------------------------------------------
   3419 class BasicAllTargetsAtomicVS : public AtomicMachine
   3420 {
   3421 	virtual long Run()
   3422 	{
   3423 		if (!IsVSFSAvailable(4, 0) || !IsSSBInVSFSAvailable(1))
   3424 			return NOT_SUPPORTED;
   3425 		return RunStage(0);
   3426 	}
   3427 };
   3428 
   3429 //-----------------------------------------------------------------------------
   3430 // 1.3.13 BasicAllTargetsAtomicCS
   3431 //-----------------------------------------------------------------------------
   3432 class BasicAllTargetsAtomicCS : public AtomicMachine
   3433 {
   3434 	virtual long Run()
   3435 	{
   3436 		return RunStage(4);
   3437 	}
   3438 };
   3439 
   3440 //-----------------------------------------------------------------------------
   3441 // 1.4.1 BasicGLSLMisc
   3442 //-----------------------------------------------------------------------------
   3443 class BasicGLSLMiscFS : public ShaderImageLoadStoreBase
   3444 {
   3445 	GLuint m_texture;
   3446 	GLuint m_program;
   3447 	GLuint m_vao, m_vbo;
   3448 	GLuint m_buffer;
   3449 
   3450 	virtual long Setup()
   3451 	{
   3452 		m_texture = 0;
   3453 		m_program = 0;
   3454 		m_vao = m_vbo = 0;
   3455 		m_buffer	  = 0;
   3456 		return NO_ERROR;
   3457 	}
   3458 
   3459 	virtual long Run()
   3460 	{
   3461 		if (!IsVSFSAvailable(0, 2) || !IsSSBInVSFSAvailable(1))
   3462 			return NOT_SUPPORTED;
   3463 
   3464 		const int		   kSize = 32;
   3465 		std::vector<float> data(kSize * kSize * 4);
   3466 
   3467 		glGenTextures(1, &m_texture);
   3468 		glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
   3469 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3470 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3471 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, kSize, kSize, 4);
   3472 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 4, GL_RED, GL_FLOAT, &data[0]);
   3473 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   3474 
   3475 		const char* src_vs =
   3476 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   3477 
   3478 		const char* src_fs =
   3479 			NL "#define KSIZE 32" NL "layout(std430) buffer out_data {" NL "  ivec4 o_color[KSIZE*KSIZE];" NL "};" NL
   3480 			   "layout(r32f, binding = 0) coherent restrict uniform image2D g_image_layer0;" NL
   3481 			   "layout(r32f, binding = 1) volatile uniform image2D g_image_layer1;" NL "void main() {" NL
   3482 			   "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image_layer0, coord, vec4(1.0));" NL
   3483 			   "  memoryBarrier();" NL "  imageStore(g_image_layer1, coord, vec4(2.0));" NL "  memoryBarrier();" NL
   3484 			   "  imageStore(g_image_layer0, coord, vec4(3.0));" NL "  memoryBarrier();" NL
   3485 			   "  int coordIndex = coord.x + KSIZE * coord.y;" NL
   3486 			   "  o_color[coordIndex] = ivec4(imageLoad(g_image_layer0, coord) + imageLoad(g_image_layer1, coord));" NL
   3487 			   "}";
   3488 		m_program = BuildProgram(src_vs, src_fs);
   3489 
   3490 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   3491 
   3492 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
   3493 		glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
   3494 
   3495 		glClear(GL_COLOR_BUFFER_BIT);
   3496 		glViewport(0, 0, kSize, kSize);
   3497 
   3498 		std::vector<ivec4> o_data(kSize * kSize);
   3499 		glGenBuffers(1, &m_buffer);
   3500 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3501 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW);
   3502 
   3503 		glUseProgram(m_program);
   3504 		glBindVertexArray(m_vao);
   3505 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3506 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3507 
   3508 		bool status = true;
   3509 
   3510 		ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   3511 		for (int i = 0; i < kSize * kSize; ++i)
   3512 		{
   3513 			if (!Equal(out_data[i], ivec4(5, 0, 0, 2), 0))
   3514 			{
   3515 				status = false;
   3516 				m_context.getTestContext().getLog()
   3517 					<< tcu::TestLog::Message << "[" << i
   3518 					<< "] Check failed. Received: " << ToString(out_data[i]).c_str()
   3519 					<< " instead of: " << ToString(ivec4(5, 0, 0, 2)).c_str() << tcu::TestLog::EndMessage;
   3520 			}
   3521 		}
   3522 
   3523 		if (status)
   3524 			return NO_ERROR;
   3525 		else
   3526 			return ERROR;
   3527 	}
   3528 
   3529 	virtual long Cleanup()
   3530 	{
   3531 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   3532 		glDeleteTextures(1, &m_texture);
   3533 		glDeleteVertexArrays(1, &m_vao);
   3534 		glDeleteBuffers(1, &m_vbo);
   3535 		glDeleteBuffers(1, &m_buffer);
   3536 		glUseProgram(0);
   3537 		glDeleteProgram(m_program);
   3538 		return NO_ERROR;
   3539 	}
   3540 };
   3541 
   3542 class BasicGLSLMiscCS : public ShaderImageLoadStoreBase
   3543 {
   3544 	GLuint m_texture;
   3545 	GLuint m_program;
   3546 	GLuint m_buffer;
   3547 
   3548 	virtual long Setup()
   3549 	{
   3550 		m_texture = 0;
   3551 		m_program = 0;
   3552 		m_buffer  = 0;
   3553 		return NO_ERROR;
   3554 	}
   3555 
   3556 	virtual long Run()
   3557 	{
   3558 		const int		   kSize = 10;
   3559 		std::vector<float> data(kSize * kSize * 4);
   3560 
   3561 		glGenTextures(1, &m_texture);
   3562 		glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
   3563 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3564 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3565 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R32F, kSize, kSize, 4);
   3566 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kSize, kSize, 4, GL_RED, GL_FLOAT, &data[0]);
   3567 		glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
   3568 
   3569 		const char* src_cs =
   3570 			NL "#define KSIZE 10" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   3571 			   "layout(std430) buffer out_data {" NL "  ivec4 o_color[KSIZE*KSIZE];" NL "};" NL
   3572 			   "layout(r32f, binding = 0) coherent restrict uniform image2D g_image_layer0;" NL
   3573 			   "layout(r32f, binding = 1) volatile uniform image2D g_image_layer1;" NL "void main() {" NL
   3574 			   "  ivec2 coord = ivec2(gl_LocalInvocationID.xy);" NL "  imageStore(g_image_layer0, coord, vec4(1.0));" NL
   3575 			   "  memoryBarrier();" NL "  imageStore(g_image_layer1, coord, vec4(2.0));" NL "  memoryBarrier();" NL
   3576 			   "  imageStore(g_image_layer0, coord, vec4(3.0));" NL "  memoryBarrier();" NL
   3577 			   "  o_color[gl_LocalInvocationIndex] = ivec4(imageLoad(g_image_layer0, coord) + "
   3578 			   "imageLoad(g_image_layer1, coord));" NL "}";
   3579 		m_program = CreateComputeProgram(src_cs);
   3580 
   3581 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
   3582 		glBindImageTexture(1, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_R32F);
   3583 
   3584 		std::vector<ivec4> o_data(kSize * kSize);
   3585 		glGenBuffers(1, &m_buffer);
   3586 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3587 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &o_data[0], GL_STATIC_DRAW);
   3588 
   3589 		glUseProgram(m_program);
   3590 		glDispatchCompute(1, 1, 1);
   3591 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3592 
   3593 		bool status = true;
   3594 
   3595 		ivec4* out_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   3596 		for (int i = 0; i < kSize * kSize; ++i)
   3597 		{
   3598 			if (!Equal(out_data[i], ivec4(5, 0, 0, 2), 0))
   3599 			{
   3600 				status = false;
   3601 				m_context.getTestContext().getLog()
   3602 					<< tcu::TestLog::Message << "[" << i
   3603 					<< "] Check failed. Received: " << ToString(out_data[i]).c_str()
   3604 					<< " instead of: " << ToString(ivec4(5, 0, 0, 2)).c_str() << tcu::TestLog::EndMessage;
   3605 			}
   3606 		}
   3607 
   3608 		if (status)
   3609 			return NO_ERROR;
   3610 		else
   3611 			return ERROR;
   3612 	}
   3613 
   3614 	virtual long Cleanup()
   3615 	{
   3616 		glDeleteTextures(1, &m_texture);
   3617 		glUseProgram(0);
   3618 		glDeleteProgram(m_program);
   3619 		glDeleteBuffers(1, &m_buffer);
   3620 		return NO_ERROR;
   3621 	}
   3622 };
   3623 
   3624 //-----------------------------------------------------------------------------
   3625 // 1.4.2 BasicGLSLEarlyFragTests
   3626 //-----------------------------------------------------------------------------
   3627 class BasicGLSLEarlyFragTests : public ShaderImageLoadStoreBase
   3628 {
   3629 	GLuint m_texture[2];
   3630 	GLuint m_program[2];
   3631 	GLuint m_vao, m_vbo;
   3632 	GLuint c_program;
   3633 	GLuint m_buffer;
   3634 
   3635 	virtual long Setup()
   3636 	{
   3637 		m_texture[0] = m_texture[1] = 0;
   3638 		m_program[0] = m_program[1] = 0;
   3639 		m_vao = m_vbo = 0;
   3640 		m_buffer	  = 0;
   3641 		c_program	 = 0;
   3642 		return NO_ERROR;
   3643 	}
   3644 
   3645 	virtual long Run()
   3646 	{
   3647 		if (!IsVSFSAvailable(0, 1))
   3648 			return NOT_SUPPORTED;
   3649 
   3650 		const int		  kSize = 8;
   3651 		std::vector<vec4> data(kSize * kSize);
   3652 
   3653 		glGenTextures(2, m_texture);
   3654 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   3655 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3656 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3657 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   3658 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]);
   3659 		glBindTexture(GL_TEXTURE_2D, 0);
   3660 
   3661 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   3662 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3663 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3664 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   3665 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]);
   3666 		glBindTexture(GL_TEXTURE_2D, 0);
   3667 
   3668 		const char* glsl_vs =
   3669 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   3670 		const char* glsl_early_frag_tests_fs =
   3671 			NL "layout(early_fragment_tests) in;" NL "layout(location = 0) out vec4 o_color;" NL
   3672 			   "layout(rgba32f, binding = 0) writeonly coherent uniform image2D g_image;" NL "void main() {" NL
   3673 			   "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image, coord, vec4(17.0));" NL
   3674 			   "  o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
   3675 		const char* glsl_fs =
   3676 			NL "layout(location = 0) out vec4 o_color;" NL
   3677 			   "layout(rgba32f, binding = 1) writeonly coherent uniform image2D g_image;" NL "void main() {" NL
   3678 			   "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageStore(g_image, coord, vec4(13.0));" NL
   3679 			   "  o_color = vec4(1.0, 0.0, 0.0, 1.0);" NL "}";
   3680 		m_program[0] = BuildProgram(glsl_vs, glsl_early_frag_tests_fs);
   3681 		m_program[1] = BuildProgram(glsl_vs, glsl_fs);
   3682 
   3683 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   3684 
   3685 		glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   3686 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   3687 
   3688 		glViewport(0, 0, kSize, kSize);
   3689 		glBindVertexArray(m_vao);
   3690 
   3691 		glEnable(GL_DEPTH_TEST);
   3692 		glClearColor(0.0, 1.0f, 0.0, 1.0f);
   3693 		glClearDepthf(0.0f);
   3694 
   3695 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   3696 		glUseProgram(m_program[0]);
   3697 
   3698 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3699 
   3700 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   3701 		glUseProgram(m_program[1]);
   3702 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3703 
   3704 		const char* check_cs =
   3705 			NL "#define KSIZE 8" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   3706 			   "uniform sampler2D g_sampler;" NL "layout(std430) buffer OutputBuffer {" NL
   3707 			   "  vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL
   3708 			   "  data[gl_LocalInvocationIndex] = texelFetch(g_sampler, ivec2(gl_LocalInvocationID), 0);" NL "}";
   3709 
   3710 		c_program = CreateComputeProgram(check_cs);
   3711 		std::vector<vec4> out_data(kSize * kSize);
   3712 		glGenBuffers(1, &m_buffer);
   3713 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3714 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   3715 
   3716 		glActiveTexture(GL_TEXTURE5);
   3717 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   3718 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   3719 
   3720 		glUseProgram(c_program);
   3721 		glUniform1i(glGetUniformLocation(c_program, "g_sampler"), 5);
   3722 		glDispatchCompute(1, 1, 1);
   3723 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3724 		vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   3725 
   3726 		float					 expectedVal  = 0.0f;
   3727 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
   3728 		if (renderTarget.getDepthBits() == 0)
   3729 		{
   3730 			expectedVal = 17.0f;
   3731 		}
   3732 
   3733 		if (!CompareValues(map_data, kSize, vec4(expectedVal)))
   3734 			return ERROR;
   3735 		glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
   3736 
   3737 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   3738 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   3739 
   3740 		glDispatchCompute(1, 1, 1);
   3741 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3742 		map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   3743 
   3744 		if (!CompareValues(map_data, kSize, vec4(13.0f)))
   3745 			return ERROR;
   3746 
   3747 		return NO_ERROR;
   3748 	}
   3749 
   3750 	virtual long Cleanup()
   3751 	{
   3752 		glDisable(GL_DEPTH_TEST);
   3753 		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
   3754 		glClearDepthf(1.0f);
   3755 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   3756 		glDeleteTextures(2, m_texture);
   3757 		glDeleteVertexArrays(1, &m_vao);
   3758 		glDeleteBuffers(1, &m_vbo);
   3759 		glUseProgram(0);
   3760 		glDeleteProgram(m_program[0]);
   3761 		glDeleteProgram(m_program[1]);
   3762 		glDeleteProgram(c_program);
   3763 		glDeleteBuffers(1, &m_buffer);
   3764 		glActiveTexture(GL_TEXTURE0);
   3765 		return NO_ERROR;
   3766 	}
   3767 };
   3768 
   3769 //-----------------------------------------------------------------------------
   3770 // 1.4.3 BasicGLSLConst
   3771 //-----------------------------------------------------------------------------
   3772 class BasicGLSLConst : public ShaderImageLoadStoreBase
   3773 {
   3774 	GLuint m_program;
   3775 	GLuint m_buffer;
   3776 
   3777 	virtual long Setup()
   3778 	{
   3779 		m_program = 0;
   3780 		m_buffer  = 0;
   3781 		return NO_ERROR;
   3782 	}
   3783 
   3784 	virtual long Run()
   3785 	{
   3786 		const char* src_cs =
   3787 			NL "layout (local_size_x = 1) in;" NL "layout(std430) buffer out_data {" NL "  ivec4 o_color;" NL "};" NL
   3788 			   "uniform int MaxImageUnits;" NL "uniform int MaxCombinedShaderOutputResources;" NL
   3789 			   "uniform int MaxVertexImageUniforms;" NL "uniform int MaxFragmentImageUniforms;" NL
   3790 			   "uniform int MaxComputeImageUniforms;" NL "uniform int MaxCombinedImageUniforms;" NL "void main() {" NL
   3791 			   "  o_color = ivec4(0, 1, 0, 1);" NL
   3792 			   "  if (gl_MaxImageUnits != MaxImageUnits) o_color = ivec4(1, 0, 0, 1);" NL
   3793 			   "  if (gl_MaxCombinedShaderOutputResources != MaxCombinedShaderOutputResources) o_color = ivec4(1, 0, "
   3794 			   "0, 2);" NL "  if (gl_MaxVertexImageUniforms != MaxVertexImageUniforms) o_color = ivec4(1, 0, 0, 4);" NL
   3795 			   "  if (gl_MaxFragmentImageUniforms != MaxFragmentImageUniforms) o_color = ivec4(1, 0, 0, 5);" NL
   3796 			   "  if (gl_MaxComputeImageUniforms != MaxComputeImageUniforms) o_color = ivec4(1, 0, 0, 6);" NL
   3797 			   "  if (gl_MaxCombinedImageUniforms != MaxCombinedImageUniforms) o_color = ivec4(1, 0, 0, 9);" NL "}";
   3798 		m_program = CreateComputeProgram(src_cs);
   3799 		glUseProgram(m_program);
   3800 
   3801 		GLint i;
   3802 		glGetIntegerv(GL_MAX_IMAGE_UNITS, &i);
   3803 		glUniform1i(glGetUniformLocation(m_program, "MaxImageUnits"), i);
   3804 
   3805 		glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &i);
   3806 		glUniform1i(glGetUniformLocation(m_program, "MaxCombinedShaderOutputResources"), i);
   3807 
   3808 		glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &i);
   3809 		glUniform1i(glGetUniformLocation(m_program, "MaxVertexImageUniforms"), i);
   3810 
   3811 		glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &i);
   3812 		glUniform1i(glGetUniformLocation(m_program, "MaxFragmentImageUniforms"), i);
   3813 
   3814 		glGetIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &i);
   3815 		glUniform1i(glGetUniformLocation(m_program, "MaxComputeImageUniforms"), i);
   3816 
   3817 		glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &i);
   3818 		glUniform1i(glGetUniformLocation(m_program, "MaxCombinedImageUniforms"), i);
   3819 
   3820 		std::vector<ivec4> out_data(1);
   3821 		glGenBuffers(1, &m_buffer);
   3822 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3823 		glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4, &out_data[0], GL_STATIC_DRAW);
   3824 
   3825 		glDispatchCompute(1, 1, 1);
   3826 
   3827 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3828 		ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4, GL_MAP_READ_BIT);
   3829 
   3830 		if (!Equal(map_data[0], ivec4(0, 1, 0, 1), 0))
   3831 		{
   3832 			m_context.getTestContext().getLog()
   3833 				<< tcu::TestLog::Message << "[" << i << "] Value is: " << ToString(map_data[0]).c_str()
   3834 				<< ". Value should be: " << ToString(ivec4(0, 1, 0, 1)).c_str() << tcu::TestLog::EndMessage;
   3835 			return ERROR;
   3836 		}
   3837 		return NO_ERROR;
   3838 	}
   3839 
   3840 	virtual long Cleanup()
   3841 	{
   3842 		glUseProgram(0);
   3843 		glDeleteProgram(m_program);
   3844 		glDeleteBuffers(1, &m_buffer);
   3845 		return NO_ERROR;
   3846 	}
   3847 };
   3848 
   3849 //-----------------------------------------------------------------------------
   3850 // 2.1.1 AdvancedSyncImageAccess
   3851 //-----------------------------------------------------------------------------
   3852 class AdvancedSyncImageAccess : public ShaderImageLoadStoreBase
   3853 {
   3854 	GLuint m_buffer;
   3855 	GLuint m_texture;
   3856 	GLuint m_store_program;
   3857 	GLuint m_draw_program;
   3858 	GLuint m_attribless_vao;
   3859 
   3860 	virtual long Setup()
   3861 	{
   3862 		m_buffer		 = 0;
   3863 		m_texture		 = 0;
   3864 		m_store_program  = 0;
   3865 		m_draw_program   = 0;
   3866 		m_attribless_vao = 0;
   3867 		return NO_ERROR;
   3868 	}
   3869 
   3870 	virtual long Run()
   3871 	{
   3872 		if (!IsVSFSAvailable(1, 0) || !IsSSBInVSFSAvailable(1))
   3873 			return NOT_SUPPORTED;
   3874 
   3875 		const int		  kSize = 44;
   3876 		const char* const glsl_store_vs =
   3877 			NL "layout(rgba32f) writeonly uniform image2D g_output_data;" NL "void main() {" NL
   3878 			   "  vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL
   3879 			   "  imageStore(g_output_data, ivec2(gl_VertexID,0), vec4(data[gl_VertexID], 0.0, 1.0));" NL
   3880 			   "  gl_PointSize = 1.0;" NL "}";
   3881 		const char* const glsl_store_fs = NL "void main() {" NL "  discard;" NL "}";
   3882 		const char* const glsl_draw_vs =
   3883 			NL "out vec4 vs_color;" NL "layout(rgba32f) readonly uniform image2D g_image;" NL
   3884 			   "uniform sampler2D g_sampler;" NL "void main() {" NL
   3885 			   "  vec4 pi = imageLoad(g_image, ivec2(gl_VertexID, 0));" NL
   3886 			   "  vec4 ps = texelFetch(g_sampler, ivec2(gl_VertexID, 0), 0);" NL
   3887 			   "  if (pi != ps) vs_color = vec4(1.0, 0.0, 0.0, 1.0);" NL
   3888 			   "  else vs_color = vec4(0.0, 1.0, 0.0, 1.0);" NL "  gl_Position = pi;" NL "}";
   3889 		const char* const glsl_draw_fs =
   3890 			NL "#define KSIZE 44" NL "in vec4 vs_color;" NL "layout(std430) buffer OutputBuffer {" NL
   3891 			   "  vec4 o_color[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
   3892 			   "  int coordIndex = coord.x + KSIZE * coord.y;" NL "  o_color[coordIndex] = vs_color;" NL "}";
   3893 		m_store_program = BuildProgram(glsl_store_vs, glsl_store_fs);
   3894 		m_draw_program  = BuildProgram(glsl_draw_vs, glsl_draw_fs);
   3895 
   3896 		glGenVertexArrays(1, &m_attribless_vao);
   3897 		glBindVertexArray(m_attribless_vao);
   3898 
   3899 		glGenTextures(1, &m_texture);
   3900 		glBindTexture(GL_TEXTURE_2D, m_texture);
   3901 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   3902 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   3903 		std::vector<ivec4> data(4);
   3904 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1);
   3905 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 1, GL_RGBA, GL_FLOAT, &data[0]);
   3906 
   3907 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   3908 
   3909 		glUseProgram(m_store_program);
   3910 		glDrawArrays(GL_POINTS, 0, 4);
   3911 
   3912 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT);
   3913 
   3914 		glViewport(0, 0, kSize, kSize);
   3915 		glClear(GL_COLOR_BUFFER_BIT);
   3916 		glUseProgram(m_draw_program);
   3917 
   3918 		std::vector<vec4> out_data(kSize * kSize);
   3919 		glGenBuffers(1, &m_buffer);
   3920 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   3921 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &out_data[0], GL_STATIC_DRAW);
   3922 
   3923 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   3924 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   3925 		vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   3926 
   3927 		if (!CompareValues(map_data, kSize, vec4(0, 1, 0, 1)))
   3928 			return ERROR;
   3929 
   3930 		return NO_ERROR;
   3931 	}
   3932 
   3933 	virtual long Cleanup()
   3934 	{
   3935 		glUseProgram(0);
   3936 		glDeleteBuffers(1, &m_buffer);
   3937 		glDeleteTextures(1, &m_texture);
   3938 		glDeleteProgram(m_store_program);
   3939 		glDeleteProgram(m_draw_program);
   3940 		glDeleteVertexArrays(1, &m_attribless_vao);
   3941 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   3942 		return NO_ERROR;
   3943 	}
   3944 };
   3945 
   3946 //-----------------------------------------------------------------------------
   3947 // 2.1.2 AdvancedSyncVertexArray
   3948 //-----------------------------------------------------------------------------
   3949 class AdvancedSyncVertexArray : public ShaderImageLoadStoreBase
   3950 {
   3951 	GLuint m_position_buffer;
   3952 	GLuint m_color_buffer;
   3953 	GLuint m_element_buffer;
   3954 	GLuint m_texture[3];
   3955 	GLuint m_store_program;
   3956 	GLuint m_copy_program;
   3957 	GLuint m_draw_program;
   3958 	GLuint m_attribless_vao;
   3959 	GLuint m_draw_vao;
   3960 
   3961 	virtual long Setup()
   3962 	{
   3963 		m_position_buffer = 0;
   3964 		m_color_buffer	= 0;
   3965 		m_element_buffer  = 0;
   3966 		m_store_program   = 0;
   3967 		m_draw_program	= 0;
   3968 		m_copy_program	= 0;
   3969 		m_attribless_vao  = 0;
   3970 		m_draw_vao		  = 0;
   3971 		return NO_ERROR;
   3972 	}
   3973 
   3974 	virtual long Run()
   3975 	{
   3976 		if (!IsVSFSAvailable(3, 0))
   3977 			return NOT_SUPPORTED;
   3978 		const char* const glsl_store_vs =
   3979 			NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_position_buffer;" NL
   3980 			   "layout(rgba32f, binding = 1) writeonly uniform image2D g_color_buffer;" NL
   3981 			   "layout(r32ui, binding = 2) writeonly uniform uimage2D g_element_buffer;" NL "uniform vec4 g_color;" NL
   3982 			   "void main() {" NL "  vec2[4] data = vec2[4](vec2(-1, -1), vec2(1, -1), vec2(-1, 1), vec2(1, 1));" NL
   3983 			   "  imageStore(g_position_buffer, ivec2(gl_VertexID,0), vec4(data[gl_VertexID], 0.0, 1.0));" NL
   3984 			   "  imageStore(g_color_buffer, ivec2(gl_VertexID,0), g_color);" NL
   3985 			   "  imageStore(g_element_buffer, ivec2(gl_VertexID,0), uvec4(gl_VertexID));" NL "}";
   3986 		const char* const glsl_store_fs = NL "void main() {" NL "  discard;" NL "}";
   3987 		const char*		  glsl_copy_cs =
   3988 			NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE) in;" NL
   3989 			   "layout(rgba32f, binding = 0) readonly uniform image2D g_position_img;" NL
   3990 			   "layout(rgba32f, binding = 1) readonly uniform image2D g_color_img;" NL
   3991 			   "layout(r32ui, binding = 2) readonly uniform uimage2D g_element_img;" NL
   3992 			   "layout(std430, binding = 1) buffer g_position_buf {" NL "  vec2 g_pos[KSIZE];" NL "};" NL
   3993 			   "layout(std430, binding = 2) buffer g_color_buf {" NL "  vec4 g_col[KSIZE];" NL "};" NL
   3994 			   "layout(std430, binding = 3) buffer g_element_buf {" NL "  uint g_elem[KSIZE];" NL "};" NL
   3995 			   "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID.x, 0);" NL
   3996 			   "  g_pos[coord.x] = (imageLoad(g_position_img, coord)).xy;" NL
   3997 			   "  g_col[coord.x] = imageLoad(g_color_img, coord);" NL
   3998 			   "  g_elem[coord.x] = uint((imageLoad(g_element_img, coord)).x);" NL "}";
   3999 		const char* const glsl_draw_vs = NL
   4000 			"layout(location = 0) in vec4 i_position;" NL "layout(location = 1) in vec4 i_color;" NL
   4001 			"out vec4 vs_color;" NL "void main() {" NL "  gl_Position = i_position;" NL "  vs_color = i_color;" NL "}";
   4002 		const char* const glsl_draw_fs = NL "in vec4 vs_color;" NL "layout(location = 0) out vec4 o_color;" NL
   4003 											"void main() {" NL "  o_color = vs_color;" NL "}";
   4004 		m_store_program = BuildProgram(glsl_store_vs, glsl_store_fs);
   4005 		m_copy_program  = CreateComputeProgram(glsl_copy_cs);
   4006 		m_draw_program  = BuildProgram(glsl_draw_vs, glsl_draw_fs);
   4007 
   4008 		glGenTextures(3, m_texture);
   4009 		std::vector<ivec4> data(4);
   4010 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   4011 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1);
   4012 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4013 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4014 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   4015 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 4, 1);
   4016 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4017 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4018 		glBindTexture(GL_TEXTURE_2D, m_texture[2]);
   4019 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 4, 1);
   4020 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4021 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4022 
   4023 		glGenVertexArrays(1, &m_attribless_vao);
   4024 		glGenVertexArrays(1, &m_draw_vao);
   4025 		glBindVertexArray(m_draw_vao);
   4026 		glGenBuffers(1, &m_position_buffer);
   4027 		glBindBuffer(GL_ARRAY_BUFFER, m_position_buffer);
   4028 		glBufferData(GL_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW);
   4029 		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
   4030 		glGenBuffers(1, &m_color_buffer);
   4031 		glBindBuffer(GL_ARRAY_BUFFER, m_color_buffer);
   4032 		glBufferData(GL_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW);
   4033 		glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
   4034 		glBindBuffer(GL_ARRAY_BUFFER, 0);
   4035 		glEnableVertexAttribArray(0);
   4036 		glEnableVertexAttribArray(1);
   4037 		glGenBuffers(1, &m_element_buffer);
   4038 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_element_buffer);
   4039 		glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * 4 * 4, 0, GL_STATIC_DRAW);
   4040 		glBindVertexArray(0);
   4041 
   4042 		glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4043 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4044 		glBindImageTexture(2, m_texture[2], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
   4045 		glUseProgram(m_store_program);
   4046 		glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f);
   4047 		glBindVertexArray(m_attribless_vao);
   4048 		glDrawArrays(GL_POINTS, 0, 4);
   4049 
   4050 		glUseProgram(m_copy_program);
   4051 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_position_buffer);
   4052 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_color_buffer);
   4053 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_element_buffer);
   4054 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4055 		glDispatchCompute(1, 1, 1);
   4056 
   4057 		glClear(GL_COLOR_BUFFER_BIT);
   4058 		glUseProgram(m_draw_program);
   4059 		glBindVertexArray(m_draw_vao);
   4060 		glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
   4061 		glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
   4062 
   4063 		if (!CheckFB(vec4(0, 1, 0, 1)))
   4064 		{
   4065 			return ERROR;
   4066 		}
   4067 
   4068 		glUseProgram(m_store_program);
   4069 		glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 0.0f, 1.0f, 1.0f);
   4070 		glBindVertexArray(m_attribless_vao);
   4071 		glDrawArrays(GL_POINTS, 0, 4);
   4072 		glUseProgram(m_copy_program);
   4073 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4074 		glDispatchCompute(1, 1, 1);
   4075 		glClear(GL_COLOR_BUFFER_BIT);
   4076 		glUseProgram(m_draw_program);
   4077 		glBindVertexArray(m_draw_vao);
   4078 		glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT);
   4079 		glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
   4080 
   4081 		if (!CheckFB(vec4(0, 0, 1, 1)))
   4082 		{
   4083 			return ERROR;
   4084 		}
   4085 		return NO_ERROR;
   4086 	}
   4087 
   4088 	virtual long Cleanup()
   4089 	{
   4090 		glDisable(GL_RASTERIZER_DISCARD);
   4091 		glUseProgram(0);
   4092 		glDeleteTextures(3, m_texture);
   4093 		glDeleteBuffers(1, &m_position_buffer);
   4094 		glDeleteBuffers(1, &m_color_buffer);
   4095 		glDeleteBuffers(1, &m_element_buffer);
   4096 		glDeleteProgram(m_store_program);
   4097 		glDeleteProgram(m_copy_program);
   4098 		glDeleteProgram(m_draw_program);
   4099 		glDeleteVertexArrays(1, &m_attribless_vao);
   4100 		glDeleteVertexArrays(1, &m_draw_vao);
   4101 		return NO_ERROR;
   4102 	}
   4103 };
   4104 
   4105 //-----------------------------------------------------------------------------
   4106 // 2.1.6 AdvancedSyncImageAccess2
   4107 //-----------------------------------------------------------------------------
   4108 class AdvancedSyncImageAccess2 : public ShaderImageLoadStoreBase
   4109 {
   4110 	GLuint m_texture;
   4111 	GLuint m_store_program;
   4112 	GLuint m_draw_program;
   4113 	GLuint m_vao;
   4114 	GLuint m_vbo;
   4115 	GLuint m_buffer;
   4116 
   4117 	virtual long Setup()
   4118 	{
   4119 		m_texture		= 0;
   4120 		m_store_program = 0;
   4121 		m_draw_program  = 0;
   4122 		m_vao			= 0;
   4123 		m_vbo			= 0;
   4124 		m_buffer		= 0;
   4125 		return NO_ERROR;
   4126 	}
   4127 
   4128 	virtual long Run()
   4129 	{
   4130 		const int kSize = 32;
   4131 		if (!IsVSFSAvailable(0, 1) || !IsSSBInVSFSAvailable(1))
   4132 			return NOT_SUPPORTED;
   4133 		const char* const glsl_vs =
   4134 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   4135 		const char* const glsl_store_fs =
   4136 			NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "uniform vec4 g_color;" NL "void main() {" NL
   4137 			   "  imageStore(g_image, ivec2(gl_FragCoord.xy), g_color);" NL "  discard;" NL "}";
   4138 		const char* const glsl_draw_fs =
   4139 			NL "layout(location = 0) out vec4 o_color;" NL "uniform sampler2D g_sampler;" NL
   4140 			   "layout(std430) buffer OutputBuffer {" NL "  uvec4 counter;" NL "  vec4 data[];" NL "};" NL
   4141 			   "void main() {" NL "  uint idx = atomicAdd(counter[0], 1u);" NL
   4142 			   "  data[idx] = texelFetch(g_sampler, ivec2(gl_FragCoord.xy), 0);" NL "}";
   4143 		m_store_program = BuildProgram(glsl_vs, glsl_store_fs);
   4144 		m_draw_program  = BuildProgram(glsl_vs, glsl_draw_fs);
   4145 
   4146 		glGenTextures(1, &m_texture);
   4147 		glBindTexture(GL_TEXTURE_2D, m_texture);
   4148 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4149 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4150 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, getWindowWidth(), getWindowHeight());
   4151 		glBindTexture(GL_TEXTURE_2D, 0);
   4152 
   4153 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   4154 
   4155 		glViewport(0, 0, kSize, kSize);
   4156 		std::vector<vec4> data_b(kSize * kSize + 1);
   4157 		glGenBuffers(1, &m_buffer);
   4158 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4159 		glBufferData(GL_SHADER_STORAGE_BUFFER, (kSize * kSize + 1) * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4160 
   4161 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
   4162 		glUseProgram(m_store_program);
   4163 		glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 1.0f, 0.0f, 0.0f, 1.0f);
   4164 		glBindVertexArray(m_vao);
   4165 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   4166 
   4167 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4168 
   4169 		glUniform4f(glGetUniformLocation(m_store_program, "g_color"), 0.0f, 1.0f, 0.0f, 1.0f);
   4170 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   4171 
   4172 		glBindTexture(GL_TEXTURE_2D, m_texture);
   4173 		glUseProgram(m_draw_program);
   4174 		glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
   4175 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   4176 
   4177 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4178 		vec4* map_data =
   4179 			(vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 4 * 4, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4180 
   4181 		if (!CompareValues(map_data, kSize, vec4(0, 1, 0, 1)))
   4182 			return ERROR;
   4183 		return NO_ERROR;
   4184 	}
   4185 
   4186 	virtual long Cleanup()
   4187 	{
   4188 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4189 		glUseProgram(0);
   4190 		glDeleteBuffers(1, &m_vbo);
   4191 		glDeleteTextures(1, &m_texture);
   4192 		glDeleteProgram(m_store_program);
   4193 		glDeleteProgram(m_draw_program);
   4194 		glDeleteVertexArrays(1, &m_vao);
   4195 		glDeleteBuffers(1, &m_buffer);
   4196 		return NO_ERROR;
   4197 	}
   4198 };
   4199 
   4200 //-----------------------------------------------------------------------------
   4201 // 2.2.1 AdvancedAllStagesOneImage
   4202 //-----------------------------------------------------------------------------
   4203 class AdvancedAllStagesOneImage : public ShaderImageLoadStoreBase
   4204 {
   4205 	GLuint m_program;
   4206 	GLuint c_program;
   4207 	GLuint m_vao;
   4208 	GLuint m_vbo;
   4209 	GLuint m_buffer;
   4210 	GLuint m_texture;
   4211 
   4212 	virtual long Setup()
   4213 	{
   4214 		m_program = 0;
   4215 		c_program = 0;
   4216 		m_vao	 = 0;
   4217 		m_vbo	 = 0;
   4218 		m_buffer  = 0;
   4219 		m_texture = 0;
   4220 		return NO_ERROR;
   4221 	}
   4222 
   4223 	virtual long Run()
   4224 	{
   4225 		const int kSize = 64;
   4226 		if (!IsVSFSAvailable(1, 1) || !IsImageAtomicSupported())
   4227 			return NOT_SUPPORTED;
   4228 		const char* const glsl_vs =
   4229 			NL "layout(location = 0) in vec4 i_position;" NL
   4230 			   "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL "void main() {" NL
   4231 			   "  gl_Position = i_position;" NL "  imageAtomicAdd(g_image, ivec2(0, gl_VertexID), 100u);" NL "}";
   4232 		const char* const glsl_fs =
   4233 			NL "#define KSIZE 64" NL "layout(r32ui, binding = 3) coherent uniform uimage2D g_image;" NL
   4234 			   "void main() {" NL "  imageAtomicAdd(g_image, ivec2(0, int(gl_FragCoord.x) & 0x03), 0x1u);" NL "}";
   4235 		m_program = BuildProgram(glsl_vs, glsl_fs, true, true);
   4236 		const char* const glsl_cs =
   4237 			NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE) in;" NL
   4238 			   "layout(r32ui, binding = 3) uniform uimage2D g_image;" NL "layout(std430) buffer out_data {" NL
   4239 			   "  uvec4 data[KSIZE];" NL "};" NL "void main() {" NL
   4240 			   "  uvec4 v = imageLoad(g_image, ivec2(0, gl_LocalInvocationID.x));" NL
   4241 			   "  data[gl_LocalInvocationIndex] = v;" NL "}";
   4242 		c_program = CreateComputeProgram(glsl_cs, true);
   4243 		glUseProgram(m_program);
   4244 
   4245 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   4246 
   4247 		std::vector<uvec4> ui32(16);
   4248 		glGenTextures(1, &m_texture);
   4249 		glBindTexture(GL_TEXTURE_2D, m_texture);
   4250 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, 4, 4);
   4251 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4252 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4253 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, &ui32[0]);
   4254 		glBindTexture(GL_TEXTURE_2D, 0);
   4255 
   4256 		glBindImageTexture(3, m_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
   4257 
   4258 		glViewport(0, 0, kSize, kSize);
   4259 		glBindVertexArray(m_vao);
   4260 		glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
   4261 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4262 
   4263 		std::vector<vec4> data_b(4);
   4264 		glGenBuffers(1, &m_buffer);
   4265 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4266 		glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4267 		glUseProgram(c_program);
   4268 		glDispatchCompute(1, 1, 1);
   4269 
   4270 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4271 		uvec4* map_data = (uvec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * 4 * 4, GL_MAP_READ_BIT);
   4272 
   4273 		if (!CompareValues(map_data, 2, uvec4(1024 + 100, 0, 0, 1)))
   4274 			return ERROR;
   4275 		return NO_ERROR;
   4276 	}
   4277 
   4278 	virtual long Cleanup()
   4279 	{
   4280 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4281 		glUseProgram(0);
   4282 		glDeleteBuffers(1, &m_buffer);
   4283 		glDeleteBuffers(1, &m_vbo);
   4284 		glDeleteTextures(1, &m_texture);
   4285 		glDeleteProgram(m_program);
   4286 		glDeleteProgram(c_program);
   4287 		glDeleteVertexArrays(1, &m_vao);
   4288 		return NO_ERROR;
   4289 	}
   4290 };
   4291 
   4292 //-----------------------------------------------------------------------------
   4293 // 2.3.2 AdvancedMemoryOrder
   4294 //-----------------------------------------------------------------------------
   4295 class AdvancedMemoryOrderVSFS : public ShaderImageLoadStoreBase
   4296 {
   4297 	GLuint m_buffer;
   4298 	GLuint m_texture[2];
   4299 	GLuint m_program;
   4300 	GLuint m_vao;
   4301 	GLuint m_vbo;
   4302 
   4303 	virtual long Setup()
   4304 	{
   4305 		m_buffer  = 0;
   4306 		m_program = 0;
   4307 		m_vao	 = 0;
   4308 		m_vbo	 = 0;
   4309 		return NO_ERROR;
   4310 	}
   4311 
   4312 	virtual long Run()
   4313 	{
   4314 		const int kSize = 11;
   4315 		if (!IsVSFSAvailable(1, 1) || !IsSSBInVSFSAvailable(1))
   4316 			return NOT_SUPPORTED;
   4317 		const char* const glsl_vs = NL
   4318 			"layout(location = 0) in vec4 i_position;" NL "out vec4 vs_color;" NL
   4319 			"layout(r32f, binding = 0) uniform image2D g_image_vs;" NL "void main() {" NL
   4320 			"  gl_Position = i_position;" NL "  vs_color = vec4(41, 42, 43, 44);" NL
   4321 			"  imageStore(g_image_vs, ivec2(gl_VertexID), vec4(1.0));" NL
   4322 			"  imageStore(g_image_vs, ivec2(gl_VertexID), vec4(2.0));" NL
   4323 			"  imageStore(g_image_vs, ivec2(gl_VertexID), vec4(3.0));" NL
   4324 			"  if (imageLoad(g_image_vs, ivec2(gl_VertexID)) != vec4(3,0,0,1)) vs_color = vec4(21, 22, 23, 24);" NL "}";
   4325 		const char* const glsl_fs =
   4326 			NL "#define KSIZE 11" NL "in vec4 vs_color;" NL "layout(r32f, binding = 1) uniform image2D g_image;" NL
   4327 			   "layout(std430) buffer out_data {" NL "  vec4 data[KSIZE*KSIZE*4];" NL "};" NL "void main() {" NL
   4328 			   "  ivec2 coord = ivec2(gl_FragCoord);" NL "  int coordIndex = coord.x + KSIZE * coord.y;" NL
   4329 			   "  for (int i = 0; i < 4; ++i) {" NL "    data[coordIndex + i * KSIZE*KSIZE] = vs_color;" NL "  }" NL
   4330 			   "  for (int i = 0; i < 4; ++i) {" NL "    imageStore(g_image, coord, vec4(i+50));" NL
   4331 			   "    vec4 v = imageLoad(g_image, coord);" NL "    if (v.x != float(i+50)) {" NL
   4332 			   "      data[coordIndex + i * KSIZE*KSIZE] = vec4(v.xyz, i+10);" NL "      break;" NL "    }" NL "  }" NL
   4333 			   "}";
   4334 		m_program = BuildProgram(glsl_vs, glsl_fs);
   4335 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   4336 
   4337 		std::vector<float> data(kSize * kSize);
   4338 		glGenTextures(2, m_texture);
   4339 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   4340 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, kSize, kSize);
   4341 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4342 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4343 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RED, GL_FLOAT, &data[0]);
   4344 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   4345 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, kSize, kSize);
   4346 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4347 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4348 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RED, GL_FLOAT, &data[0]);
   4349 		glBindTexture(GL_TEXTURE_2D, 0);
   4350 
   4351 		glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
   4352 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
   4353 
   4354 		std::vector<vec4> data_b(kSize * kSize * 4);
   4355 		glGenBuffers(1, &m_buffer);
   4356 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4357 		glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4358 
   4359 		glUseProgram(m_program);
   4360 		glViewport(0, 0, kSize, kSize);
   4361 		glBindVertexArray(m_vao);
   4362 		glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
   4363 
   4364 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4365 		vec4* map_data =
   4366 			(vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 4 * kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4367 
   4368 		if (!CompareValues(map_data, kSize * 2, vec4(41, 42, 43, 44)))
   4369 			return ERROR;
   4370 		return NO_ERROR;
   4371 	}
   4372 
   4373 	virtual long Cleanup()
   4374 	{
   4375 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4376 		glUseProgram(0);
   4377 		glDeleteBuffers(1, &m_vbo);
   4378 		glDeleteBuffers(1, &m_buffer);
   4379 		glDeleteTextures(2, m_texture);
   4380 		glDeleteProgram(m_program);
   4381 		glDeleteVertexArrays(1, &m_vao);
   4382 		return NO_ERROR;
   4383 	}
   4384 };
   4385 
   4386 //-----------------------------------------------------------------------------
   4387 // 2.4.1 AdvancedSSOSimple
   4388 //-----------------------------------------------------------------------------
   4389 class AdvancedSSOSimple : public ShaderImageLoadStoreBase
   4390 {
   4391 	bool   pipeline;
   4392 	GLuint m_texture;
   4393 	GLuint m_pipeline[2];
   4394 	GLuint m_vsp, m_fsp0, m_fsp1;
   4395 	GLuint m_vao, m_vbo;
   4396 	GLuint m_program[2];
   4397 	GLuint c_program;
   4398 	GLuint m_buffer;
   4399 
   4400 	virtual long Setup()
   4401 	{
   4402 		c_program = 0;
   4403 		m_buffer  = 0;
   4404 		CreateFullViewportQuad(&m_vao, &m_vbo, NULL);
   4405 		glGenTextures(1, &m_texture);
   4406 		const char* const glsl_vs =
   4407 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   4408 		const char* const glsl_fs0 =
   4409 			NL "layout(rgba32f, binding = 2) writeonly uniform image2D g_image[2];" NL "void main() {" NL
   4410 			   "  int i = g_image.length();" NL "  imageStore(g_image[0], ivec2(gl_FragCoord), vec4(i+98));" NL
   4411 			   "  imageStore(g_image[1], ivec2(gl_FragCoord), vec4(i+99));" NL "  discard;" NL "}";
   4412 		const char* const glsl_fs1 =
   4413 			NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[2];" NL "void main() {" NL
   4414 			   "  int i = g_image.length();" NL "  imageStore(g_image[0], ivec2(gl_FragCoord), vec4(i+8));" NL
   4415 			   "  imageStore(g_image[1], ivec2(gl_FragCoord), vec4(i+9));" NL "  discard;" NL "}";
   4416 		if (pipeline)
   4417 		{
   4418 			glGenProgramPipelines(2, m_pipeline);
   4419 			m_vsp  = BuildShaderProgram(GL_VERTEX_SHADER, glsl_vs);
   4420 			m_fsp0 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs0);
   4421 			m_fsp1 = BuildShaderProgram(GL_FRAGMENT_SHADER, glsl_fs1);
   4422 		}
   4423 		else
   4424 		{
   4425 			m_program[0] = BuildProgram(glsl_vs, glsl_fs0);
   4426 			m_program[1] = BuildProgram(glsl_vs, glsl_fs1);
   4427 		}
   4428 		return NO_ERROR;
   4429 	}
   4430 
   4431 	virtual long Run()
   4432 	{
   4433 		if (!IsVSFSAvailable(0, 2))
   4434 			return NOT_SUPPORTED;
   4435 		const int kSize = 4;
   4436 
   4437 		if (pipeline)
   4438 		{
   4439 			glUseProgramStages(m_pipeline[0], GL_VERTEX_SHADER_BIT, m_vsp);
   4440 			glUseProgramStages(m_pipeline[0], GL_FRAGMENT_SHADER_BIT, m_fsp0);
   4441 			glUseProgramStages(m_pipeline[1], GL_VERTEX_SHADER_BIT, m_vsp);
   4442 			glUseProgramStages(m_pipeline[1], GL_FRAGMENT_SHADER_BIT, m_fsp1);
   4443 		}
   4444 		glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture);
   4445 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4446 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4447 		glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA32F, getWindowWidth(), getWindowHeight(), 8);
   4448 
   4449 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 6, GL_READ_WRITE, GL_RGBA32F);
   4450 		glBindImageTexture(1, m_texture, 0, GL_FALSE, 4, GL_READ_WRITE, GL_RGBA32F);
   4451 		glBindImageTexture(2, m_texture, 0, GL_FALSE, 1, GL_READ_WRITE, GL_RGBA32F);
   4452 		glBindImageTexture(3, m_texture, 0, GL_FALSE, 3, GL_READ_WRITE, GL_RGBA32F);
   4453 
   4454 		glBindVertexArray(m_vao);
   4455 		if (pipeline)
   4456 			glBindProgramPipeline(m_pipeline[0]);
   4457 		else
   4458 			glUseProgram(m_program[0]);
   4459 		glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, 1);
   4460 
   4461 		if (pipeline)
   4462 			glBindProgramPipeline(m_pipeline[1]);
   4463 		else
   4464 			glUseProgram(m_program[1]);
   4465 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   4466 
   4467 		const char* const glsl_cs =
   4468 			NL "#define KSIZE 4" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4469 			   "layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL
   4470 			   "layout(std430) buffer OutputBuffer {" NL "  uvec4 counter;" NL "  vec4 data[];" NL "};" NL
   4471 			   "void main() {" NL "  uint idx = atomicAdd(counter[0], 1u);" NL
   4472 			   "  data[idx][0] = (imageLoad(g_image[0], ivec2(gl_GlobalInvocationID))).z;" NL
   4473 			   "  data[idx][1] = (imageLoad(g_image[1], ivec2(gl_GlobalInvocationID))).z;" NL
   4474 			   "  data[idx][2] = (imageLoad(g_image[2], ivec2(gl_GlobalInvocationID))).z;" NL
   4475 			   "  data[idx][3] = (imageLoad(g_image[3], ivec2(gl_GlobalInvocationID))).z;" NL "}";
   4476 		c_program = CreateComputeProgram(glsl_cs);
   4477 		glUseProgram(c_program);
   4478 		int wsx   = (getWindowWidth() / kSize) * kSize;
   4479 		int wsy   = (getWindowHeight() / kSize) * kSize;
   4480 		int minor = wsx > wsy ? wsy : wsx;
   4481 
   4482 		std::vector<vec4> data_b(wsx * wsy + 1);
   4483 		glGenBuffers(1, &m_buffer);
   4484 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4485 		glBufferData(GL_SHADER_STORAGE_BUFFER, (wsx * wsy + 1) * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4486 
   4487 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4488 		glDispatchCompute(wsx / kSize, wsy / kSize, 1);
   4489 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4490 		vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 4 * 4, wsx * wsy * 4 * 4, GL_MAP_READ_BIT);
   4491 
   4492 		if (!CompareValues(map_data, minor, vec4(10, 11, 100, 101)))
   4493 			return ERROR;
   4494 		return NO_ERROR;
   4495 	}
   4496 
   4497 	virtual long Cleanup()
   4498 	{
   4499 		glUseProgram(0);
   4500 		glDeleteBuffers(1, &m_vbo);
   4501 		glDeleteTextures(1, &m_texture);
   4502 		if (pipeline)
   4503 		{
   4504 			glDeleteProgram(m_vsp);
   4505 			glDeleteProgram(m_fsp0);
   4506 			glDeleteProgram(m_fsp1);
   4507 			glDeleteProgramPipelines(2, m_pipeline);
   4508 		}
   4509 		else
   4510 		{
   4511 			glDeleteProgram(m_program[0]);
   4512 			glDeleteProgram(m_program[1]);
   4513 		}
   4514 		glDeleteProgram(c_program);
   4515 		glDeleteVertexArrays(1, &m_vao);
   4516 		glDeleteBuffers(1, &m_buffer);
   4517 		return NO_ERROR;
   4518 	}
   4519 
   4520 public:
   4521 	AdvancedSSOSimple() : pipeline(true)
   4522 	{
   4523 	}
   4524 };
   4525 
   4526 //-----------------------------------------------------------------------------
   4527 // 2.5 AdvancedCopyImage
   4528 //-----------------------------------------------------------------------------
   4529 class AdvancedCopyImageFS : public ShaderImageLoadStoreBase
   4530 {
   4531 	GLuint m_texture[2];
   4532 	GLuint m_program;
   4533 	GLuint c_program;
   4534 	GLuint m_vao, m_vbo, m_ebo;
   4535 	GLuint m_buffer;
   4536 
   4537 	virtual long Setup()
   4538 	{
   4539 		glGenTextures(2, m_texture);
   4540 		CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
   4541 		glGenBuffers(1, &m_buffer);
   4542 
   4543 		const char* const glsl_vs =
   4544 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   4545 		const char* const glsl_fs =
   4546 			NL "layout(rgba32f, binding = 3) readonly uniform image2D g_input_image;" NL
   4547 			   "layout(rgba32f, binding = 1) writeonly uniform image2D g_output_image;" NL "void main() {" NL
   4548 			   "  ivec2 coord = ivec2(gl_FragCoord);" NL
   4549 			   "  imageStore(g_output_image, coord, imageLoad(g_input_image, coord));" NL "  discard;" NL "}";
   4550 		m_program				  = BuildProgram(glsl_vs, glsl_fs);
   4551 		const char* const glsl_cs = NL
   4552 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4553 			"layout(rgba32f, binding = 2) readonly uniform image2D g_image;" NL "layout(std430) buffer out_data {" NL
   4554 			"  vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4555 			"  data[gl_LocalInvocationIndex] = imageLoad(g_image, coord);" NL "}";
   4556 		c_program = CreateComputeProgram(glsl_cs);
   4557 
   4558 		return NO_ERROR;
   4559 	}
   4560 
   4561 	virtual long Run()
   4562 	{
   4563 		const int kSize = 11;
   4564 		if (!IsVSFSAvailable(0, 2))
   4565 			return NOT_SUPPORTED;
   4566 
   4567 		std::vector<vec4> data(kSize * kSize, vec4(7.0f));
   4568 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   4569 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   4570 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4571 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4572 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]);
   4573 
   4574 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   4575 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   4576 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4577 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4578 
   4579 		glBindTexture(GL_TEXTURE_2D, 0);
   4580 
   4581 		glBindImageTexture(3, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   4582 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
   4583 		glBindImageTexture(2, m_texture[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   4584 
   4585 		std::vector<vec4> data_b(kSize * kSize);
   4586 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4587 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4588 
   4589 		glUseProgram(m_program);
   4590 		glBindVertexArray(m_vao);
   4591 		glViewport(0, 0, kSize, kSize);
   4592 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);
   4593 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4594 
   4595 		glUseProgram(c_program);
   4596 		glDispatchCompute(1, 1, 1);
   4597 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4598 		vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4599 
   4600 		if (!CompareValues(map_data, kSize, vec4(7.f)))
   4601 			return ERROR;
   4602 		return NO_ERROR;
   4603 	}
   4604 
   4605 	virtual long Cleanup()
   4606 	{
   4607 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4608 		glUseProgram(0);
   4609 		glDeleteBuffers(1, &m_vbo);
   4610 		glDeleteBuffers(1, &m_ebo);
   4611 		glDeleteBuffers(1, &m_buffer);
   4612 		glDeleteTextures(2, m_texture);
   4613 		glDeleteProgram(m_program);
   4614 		glDeleteProgram(c_program);
   4615 		glDeleteVertexArrays(1, &m_vao);
   4616 		return NO_ERROR;
   4617 	}
   4618 };
   4619 
   4620 class AdvancedCopyImageCS : public ShaderImageLoadStoreBase
   4621 {
   4622 	GLuint m_texture[2];
   4623 	GLuint m_program;
   4624 	GLuint c_program;
   4625 	GLuint m_buffer;
   4626 
   4627 	virtual long Setup()
   4628 	{
   4629 		glGenTextures(2, m_texture);
   4630 		glGenBuffers(1, &m_buffer);
   4631 
   4632 		const char* const glsl_cs =
   4633 			NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4634 			   "layout(rgba32f, binding = 3) readonly uniform image2D g_input_image;" NL
   4635 			   "layout(rgba32f, binding = 1) writeonly uniform image2D g_output_image;" NL "void main() {" NL
   4636 			   "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4637 			   "  imageStore(g_output_image, coord, imageLoad(g_input_image, coord));" NL "}";
   4638 		m_program					= CreateComputeProgram(glsl_cs);
   4639 		const char* const glsl_cs_c = NL
   4640 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4641 			"layout(rgba32f, binding = 2) readonly uniform image2D g_image;" NL "layout(std430) buffer out_data {" NL
   4642 			"  vec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4643 			"  data[gl_LocalInvocationIndex] = imageLoad(g_image, coord);" NL "}";
   4644 		c_program = CreateComputeProgram(glsl_cs_c);
   4645 
   4646 		return NO_ERROR;
   4647 	}
   4648 
   4649 	virtual long Run()
   4650 	{
   4651 		const int kSize = 11;
   4652 
   4653 		std::vector<vec4> data(kSize * kSize, vec4(7.0f));
   4654 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   4655 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   4656 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4657 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4658 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_FLOAT, &data[0]);
   4659 
   4660 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   4661 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, kSize, kSize);
   4662 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4663 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4664 
   4665 		glBindTexture(GL_TEXTURE_2D, 0);
   4666 
   4667 		glBindImageTexture(3, m_texture[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   4668 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
   4669 		glBindImageTexture(2, m_texture[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   4670 
   4671 		std::vector<vec4> data_b(kSize * kSize);
   4672 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4673 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data_b[0], GL_STATIC_DRAW);
   4674 
   4675 		glUseProgram(m_program);
   4676 		glDispatchCompute(1, 1, 1);
   4677 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4678 
   4679 		glUseProgram(c_program);
   4680 		glDispatchCompute(1, 1, 1);
   4681 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4682 		vec4* map_data = (vec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4683 
   4684 		if (!CompareValues(map_data, kSize, vec4(7.f)))
   4685 			return ERROR;
   4686 		return NO_ERROR;
   4687 	}
   4688 
   4689 	virtual long Cleanup()
   4690 	{
   4691 		glUseProgram(0);
   4692 		glDeleteBuffers(1, &m_buffer);
   4693 		glDeleteTextures(2, m_texture);
   4694 		glDeleteProgram(m_program);
   4695 		glDeleteProgram(c_program);
   4696 		return NO_ERROR;
   4697 	}
   4698 };
   4699 
   4700 //-----------------------------------------------------------------------------
   4701 // 2.6 AdvancedAllMips
   4702 //-----------------------------------------------------------------------------
   4703 class AdvancedAllMipsFS : public ShaderImageLoadStoreBase
   4704 {
   4705 	GLuint m_texture;
   4706 	GLuint m_store_program, m_load_program;
   4707 	GLuint m_vao, m_vbo, m_ebo;
   4708 	GLuint m_buffer;
   4709 
   4710 	virtual long Setup()
   4711 	{
   4712 		glGenTextures(1, &m_texture);
   4713 		CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
   4714 		glGenBuffers(1, &m_buffer);
   4715 
   4716 		const char* const glsl_vs =
   4717 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   4718 		const char* const glsl_store_fs =
   4719 			NL "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[4];" NL "void main() {" NL
   4720 			   "  imageStore(g_image[0], ivec2(gl_FragCoord), vec4(23));" NL
   4721 			   "  imageStore(g_image[1], ivec2(gl_FragCoord), vec4(24));" NL
   4722 			   "  imageStore(g_image[2], ivec2(gl_FragCoord), vec4(25));" NL
   4723 			   "  imageStore(g_image[3], ivec2(gl_FragCoord), vec4(26));" NL "  discard;" NL "}";
   4724 		const char* const glsl_load_cs = NL
   4725 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4726 			"layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL "layout(std430) buffer out_data {" NL
   4727 			"  ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4728 			"  data[gl_LocalInvocationIndex] = ivec4(2, 3, 4, 5);" NL "  vec4 c0 = imageLoad(g_image[0], coord);" NL
   4729 			"  vec4 c1 = imageLoad(g_image[1], coord);" NL "  vec4 c2 = imageLoad(g_image[2], coord);" NL
   4730 			"  vec4 c3 = imageLoad(g_image[3], coord);" NL
   4731 			"  if ((all(lessThan(coord, ivec2(2))) && c0 != vec4(23)) || (any(greaterThanEqual(coord, ivec2(2))) && "
   4732 			"c0.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][0] = int(c0.x);" NL
   4733 			"  if ((all(lessThan(coord, ivec2(4))) && c1 != vec4(24)) || (any(greaterThanEqual(coord, ivec2(4))) && "
   4734 			"c1.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][1] = int(c1.x);" NL
   4735 			"  if ((all(lessThan(coord, ivec2(8))) && c2 != vec4(25)) || (any(greaterThanEqual(coord, ivec2(8))) && "
   4736 			"c2.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][2] = int(c2.x);" NL
   4737 			"  if ((all(lessThan(coord, ivec2(16))) && c3 != vec4(26)) || (any(greaterThanEqual(coord, ivec2(16))) && "
   4738 			"c3.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][3] = int(c3.x);" NL "}";
   4739 		m_store_program = BuildProgram(glsl_vs, glsl_store_fs);
   4740 		m_load_program  = CreateComputeProgram(glsl_load_cs);
   4741 
   4742 		return NO_ERROR;
   4743 	}
   4744 
   4745 	virtual long Run()
   4746 	{
   4747 		const int kSize = 11;
   4748 		if (!IsVSFSAvailable(0, 4))
   4749 			return NOT_SUPPORTED;
   4750 		glBindTexture(GL_TEXTURE_2D, m_texture);
   4751 		glTexStorage2D(GL_TEXTURE_2D, 8, GL_RGBA32F, 128, 128);
   4752 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4753 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4754 		glBindTexture(GL_TEXTURE_2D, 0);
   4755 
   4756 		glBindImageTexture(0, m_texture, 6, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4757 		glBindImageTexture(1, m_texture, 5, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4758 		glBindImageTexture(2, m_texture, 4, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4759 		glBindImageTexture(3, m_texture, 3, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4760 
   4761 		std::vector<GLubyte> data(kSize * kSize * 4 * 4);
   4762 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4763 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW);
   4764 
   4765 		glViewport(0, 0, kSize, kSize);
   4766 		glBindVertexArray(m_vao);
   4767 
   4768 		glUseProgram(m_store_program);
   4769 		glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
   4770 
   4771 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4772 
   4773 		glUseProgram(m_load_program);
   4774 		glDispatchCompute(1, 1, 1);
   4775 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4776 		ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4777 
   4778 		if (!CompareValues(map_data, kSize, ivec4(2, 3, 4, 5)))
   4779 			return ERROR;
   4780 		return NO_ERROR;
   4781 	}
   4782 
   4783 	virtual long Cleanup()
   4784 	{
   4785 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4786 		glUseProgram(0);
   4787 		glDeleteBuffers(1, &m_vbo);
   4788 		glDeleteBuffers(1, &m_ebo);
   4789 		glDeleteTextures(1, &m_texture);
   4790 		glDeleteProgram(m_store_program);
   4791 		glDeleteProgram(m_load_program);
   4792 		glDeleteVertexArrays(1, &m_vao);
   4793 		glDeleteBuffers(1, &m_buffer);
   4794 		return NO_ERROR;
   4795 	}
   4796 };
   4797 
   4798 class AdvancedAllMipsCS : public ShaderImageLoadStoreBase
   4799 {
   4800 	GLuint m_texture;
   4801 	GLuint m_store_program, m_load_program;
   4802 	GLuint m_buffer;
   4803 
   4804 	virtual long Setup()
   4805 	{
   4806 		glGenTextures(1, &m_texture);
   4807 		glGenBuffers(1, &m_buffer);
   4808 
   4809 		const char* const glsl_store_cs =
   4810 			NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4811 			   "layout(rgba32f, binding = 0) writeonly uniform image2D g_image[4];" NL "void main() {" NL
   4812 			   "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL "  imageStore(g_image[0], coord, vec4(23));" NL
   4813 			   "  imageStore(g_image[1], coord, vec4(24));" NL "  imageStore(g_image[2], coord, vec4(25));" NL
   4814 			   "  imageStore(g_image[3], coord, vec4(26));" NL "}";
   4815 		const char* const glsl_load_cs = NL
   4816 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4817 			"layout(rgba32f, binding = 0) readonly uniform image2D g_image[4];" NL "layout(std430) buffer out_data {" NL
   4818 			"  ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4819 			"  data[gl_LocalInvocationIndex] = ivec4(2, 3, 4, 5);" NL "  vec4 c0 = imageLoad(g_image[0], coord);" NL
   4820 			"  vec4 c1 = imageLoad(g_image[1], coord);" NL "  vec4 c2 = imageLoad(g_image[2], coord);" NL
   4821 			"  vec4 c3 = imageLoad(g_image[3], coord);" NL
   4822 			"  if ((all(lessThan(coord, ivec2(2))) && c0 != vec4(23)) || (any(greaterThanEqual(coord, ivec2(2))) && "
   4823 			"c0.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][0] = int(c0.x);" NL
   4824 			"  if ((all(lessThan(coord, ivec2(4))) && c1 != vec4(24)) || (any(greaterThanEqual(coord, ivec2(4))) && "
   4825 			"c1.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][1] = int(c1.x);" NL
   4826 			"  if ((all(lessThan(coord, ivec2(8))) && c2 != vec4(25)) || (any(greaterThanEqual(coord, ivec2(8))) && "
   4827 			"c2.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][2] = int(c2.x);" NL
   4828 			"  if ((all(lessThan(coord, ivec2(16))) && c3 != vec4(26)) || (any(greaterThanEqual(coord, ivec2(16))) && "
   4829 			"c3.xyz != vec3(0.0)))" NL "      data[gl_LocalInvocationIndex][3] = int(c3.x);" NL "}";
   4830 		m_store_program = CreateComputeProgram(glsl_store_cs);
   4831 		m_load_program  = CreateComputeProgram(glsl_load_cs);
   4832 
   4833 		return NO_ERROR;
   4834 	}
   4835 
   4836 	virtual long Run()
   4837 	{
   4838 		const int kSize = 11;
   4839 		glBindTexture(GL_TEXTURE_2D, m_texture);
   4840 		glTexStorage2D(GL_TEXTURE_2D, 8, GL_RGBA32F, 128, 128);
   4841 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4842 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4843 		glBindTexture(GL_TEXTURE_2D, 0);
   4844 
   4845 		glBindImageTexture(0, m_texture, 6, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4846 		glBindImageTexture(1, m_texture, 5, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4847 		glBindImageTexture(2, m_texture, 4, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4848 		glBindImageTexture(3, m_texture, 3, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
   4849 
   4850 		std::vector<GLubyte> data(kSize * kSize * 4 * 4);
   4851 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4852 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW);
   4853 
   4854 		glUseProgram(m_store_program);
   4855 		glDispatchCompute(1, 1, 1);
   4856 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4857 
   4858 		glUseProgram(m_load_program);
   4859 		glDispatchCompute(1, 1, 1);
   4860 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4861 		ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4862 
   4863 		if (!CompareValues(map_data, kSize, ivec4(2, 3, 4, 5)))
   4864 			return ERROR;
   4865 		return NO_ERROR;
   4866 	}
   4867 
   4868 	virtual long Cleanup()
   4869 	{
   4870 		glUseProgram(0);
   4871 		glDeleteTextures(1, &m_texture);
   4872 		glDeleteProgram(m_store_program);
   4873 		glDeleteProgram(m_load_program);
   4874 		glDeleteBuffers(1, &m_buffer);
   4875 		return NO_ERROR;
   4876 	}
   4877 };
   4878 
   4879 //-----------------------------------------------------------------------------
   4880 // 2.7 AdvancedCast
   4881 //-----------------------------------------------------------------------------
   4882 class AdvancedCastFS : public ShaderImageLoadStoreBase
   4883 {
   4884 	GLuint m_texture[2];
   4885 	GLuint m_program;
   4886 	GLuint c_program;
   4887 	GLuint m_vao, m_vbo, m_ebo;
   4888 	GLuint m_buffer;
   4889 
   4890 	virtual long Setup()
   4891 	{
   4892 		glGenTextures(2, m_texture);
   4893 		glGenBuffers(1, &m_buffer);
   4894 		m_program = 0;
   4895 		c_program = 0;
   4896 		return NO_ERROR;
   4897 	}
   4898 
   4899 	virtual long Run()
   4900 	{
   4901 		if (!IsVSFSAvailable(0, 2) || !IsImageAtomicSupported())
   4902 			return NOT_SUPPORTED;
   4903 		const int kSize = 11;
   4904 		CreateFullViewportQuad(&m_vao, &m_vbo, &m_ebo);
   4905 
   4906 		const char* const glsl_vs =
   4907 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   4908 		const char* const glsl_fs =
   4909 			NL "#define KSIZE 11" NL "layout(r32i, binding = 0) coherent uniform iimage2D g_image0;" NL
   4910 			   "layout(r32ui, binding = 1) coherent uniform uimage2D g_image1;" NL "void main() {" NL
   4911 			   "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL "  imageAtomicAdd(g_image0, coord, 2);" NL
   4912 			   "  imageAtomicAdd(g_image0, coord, -1);" NL "  imageAtomicAdd(g_image1, coord, 1u);" NL
   4913 			   "  imageAtomicAdd(g_image1, coord, 2u);" NL "}";
   4914 		m_program = BuildProgram(glsl_vs, glsl_fs, false, true);
   4915 
   4916 		const char* const glsl_cs = NL
   4917 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   4918 			"layout(r32i, binding = 0) uniform iimage2D gi_image;" NL
   4919 			"layout(r32ui, binding = 1) uniform uimage2D gu_image;" NL "layout(std430) buffer out_data {" NL
   4920 			"  ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   4921 			"  data[gl_LocalInvocationIndex].yx = imageLoad(gi_image, coord).xy;" NL
   4922 			"  data[gl_LocalInvocationIndex].wz = ivec2(imageLoad(gu_image, coord).xz);" NL "}";
   4923 		c_program = CreateComputeProgram(glsl_cs);
   4924 
   4925 		std::vector<GLubyte> data(kSize * kSize * 4 * 4);
   4926 		glActiveTexture(GL_TEXTURE11);
   4927 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   4928 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
   4929 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
   4930 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4931 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4932 		glActiveTexture(GL_TEXTURE15);
   4933 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   4934 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
   4935 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
   4936 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   4937 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   4938 
   4939 		glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
   4940 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
   4941 
   4942 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   4943 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW);
   4944 
   4945 		glUseProgram(m_program);
   4946 		glBindVertexArray(m_vao);
   4947 		glViewport(0, 0, kSize, kSize);
   4948 		glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0);
   4949 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   4950 
   4951 		glUseProgram(c_program);
   4952 		glDispatchCompute(1, 1, 1);
   4953 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   4954 		ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   4955 
   4956 		if (!CompareValues(map_data, kSize, ivec4(0, 1, 0, 3)))
   4957 			return ERROR;
   4958 		return NO_ERROR;
   4959 	}
   4960 
   4961 	virtual long Cleanup()
   4962 	{
   4963 		glViewport(0, 0, getWindowWidth(), getWindowHeight());
   4964 		glUseProgram(0);
   4965 		glDeleteBuffers(1, &m_vbo);
   4966 		glDeleteBuffers(1, &m_ebo);
   4967 		glDeleteBuffers(1, &m_buffer);
   4968 		glDeleteTextures(2, m_texture);
   4969 		glDeleteProgram(m_program);
   4970 		glDeleteProgram(c_program);
   4971 		glDeleteVertexArrays(1, &m_vao);
   4972 		glActiveTexture(GL_TEXTURE0);
   4973 		return NO_ERROR;
   4974 	}
   4975 };
   4976 
   4977 class AdvancedCastCS : public ShaderImageLoadStoreBase
   4978 {
   4979 	GLuint m_texture[2];
   4980 	GLuint m_program;
   4981 	GLuint c_program;
   4982 	GLuint m_buffer;
   4983 
   4984 	virtual long Setup()
   4985 	{
   4986 		glGenTextures(2, m_texture);
   4987 		glGenBuffers(1, &m_buffer);
   4988 		m_program = 0;
   4989 		c_program = 0;
   4990 		return NO_ERROR;
   4991 	}
   4992 
   4993 	virtual long Run()
   4994 	{
   4995 		const int kSize = 11;
   4996 		if (!IsImageAtomicSupported())
   4997 			return NO_ERROR;
   4998 
   4999 		const char* const glsl_cs =
   5000 			NL "#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   5001 			   "layout(r32i, binding = 0) coherent uniform iimage2D g_image0;" NL
   5002 			   "layout(r32ui, binding = 1) coherent uniform uimage2D g_image1;" NL "void main() {" NL
   5003 			   "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL "  imageAtomicAdd(g_image0, coord, 222);" NL
   5004 			   "  imageAtomicAdd(g_image0, coord, -11);" NL "  imageAtomicAdd(g_image1, coord, 1u);" NL
   5005 			   "  imageAtomicAdd(g_image1, coord, 2u);" NL "}";
   5006 		m_program = CreateComputeProgram(glsl_cs, true);
   5007 
   5008 		const char* const glsl_cs_c = NL
   5009 			"#define KSIZE 11" NL "layout (local_size_x = KSIZE, local_size_y = KSIZE) in;" NL
   5010 			"layout(r32i, binding = 0) uniform iimage2D gi_image;" NL
   5011 			"layout(r32ui, binding = 1) uniform uimage2D gu_image;" NL "layout(std430) buffer out_data {" NL
   5012 			"  ivec4 data[KSIZE*KSIZE];" NL "};" NL "void main() {" NL "  ivec2 coord = ivec2(gl_LocalInvocationID);" NL
   5013 			"  data[gl_LocalInvocationIndex].yz = imageLoad(gi_image, coord).xw;" NL
   5014 			"  data[gl_LocalInvocationIndex].wx = ivec2(imageLoad(gu_image, coord).xy);" NL "}";
   5015 		c_program = CreateComputeProgram(glsl_cs_c);
   5016 
   5017 		std::vector<GLubyte> data(kSize * kSize * 4 * 4);
   5018 		glActiveTexture(GL_TEXTURE11);
   5019 		glBindTexture(GL_TEXTURE_2D, m_texture[0]);
   5020 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
   5021 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
   5022 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   5023 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   5024 		glActiveTexture(GL_TEXTURE15);
   5025 		glBindTexture(GL_TEXTURE_2D, m_texture[1]);
   5026 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
   5027 		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
   5028 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   5029 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   5030 
   5031 		glBindImageTexture(0, m_texture[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32I);
   5032 		glBindImageTexture(1, m_texture[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
   5033 
   5034 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
   5035 		glBufferData(GL_SHADER_STORAGE_BUFFER, kSize * kSize * 4 * 4, &data[0], GL_STATIC_DRAW);
   5036 
   5037 		glUseProgram(m_program);
   5038 		glDispatchCompute(1, 1, 1);
   5039 		glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
   5040 
   5041 		glUseProgram(c_program);
   5042 		glDispatchCompute(1, 1, 1);
   5043 		glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
   5044 		ivec4* map_data = (ivec4*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kSize * kSize * 4 * 4, GL_MAP_READ_BIT);
   5045 
   5046 		if (!CompareValues(map_data, kSize, ivec4(0, 211, 1, 3)))
   5047 			return ERROR;
   5048 		return NO_ERROR;
   5049 	}
   5050 
   5051 	virtual long Cleanup()
   5052 	{
   5053 		glUseProgram(0);
   5054 		glDeleteBuffers(1, &m_buffer);
   5055 		glDeleteTextures(2, m_texture);
   5056 		glDeleteProgram(m_program);
   5057 		glDeleteProgram(c_program);
   5058 		glActiveTexture(GL_TEXTURE0);
   5059 		return NO_ERROR;
   5060 	}
   5061 };
   5062 //-----------------------------------------------------------------------------
   5063 // 4.1 NegativeUniform
   5064 //-----------------------------------------------------------------------------
   5065 class NegativeUniform : public ShaderImageLoadStoreBase
   5066 {
   5067 	GLuint m_program;
   5068 
   5069 	virtual long Setup()
   5070 	{
   5071 		m_program = 0;
   5072 		return NO_ERROR;
   5073 	}
   5074 
   5075 	virtual long Run()
   5076 	{
   5077 		const char* glsl_vs =
   5078 			NL "layout(location = 0) in vec4 i_position;" NL "void main() {" NL "  gl_Position = i_position;" NL "}";
   5079 		const char* glsl_fs = NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "void main() {" NL
   5080 								 "  ivec2 coord = ivec2(gl_FragCoord.xy);" NL
   5081 								 "  imageStore(g_image, coord, vec4(0.0));" NL "  discard;" NL "}";
   5082 		m_program = BuildProgram(glsl_vs, glsl_fs);
   5083 
   5084 		GLint max_image_units;
   5085 		glGetIntegerv(GL_MAX_IMAGE_UNITS, &max_image_units);
   5086 		glUseProgram(m_program);
   5087 		bool  status = true;
   5088 		GLint i		 = 1;
   5089 		glUniform1i(glGetUniformLocation(m_program, "g_image"), 1);
   5090 		if (glGetError() != GL_INVALID_OPERATION)
   5091 			status = false;
   5092 		glUniform1iv(glGetUniformLocation(m_program, "g_image"), 1, &i);
   5093 		if (glGetError() != GL_INVALID_OPERATION)
   5094 			status = false;
   5095 		glUniform1ui(glGetUniformLocation(m_program, "g_image"), 0);
   5096 		if (glGetError() != GL_INVALID_OPERATION)
   5097 			status = false;
   5098 		glUniform2i(glGetUniformLocation(m_program, "g_image"), 0, 0);
   5099 		if (glGetError() != GL_INVALID_OPERATION)
   5100 			status = false;
   5101 
   5102 		if (!status)
   5103 		{
   5104 			m_context.getTestContext().getLog()
   5105 				<< tcu::TestLog::Message << "glUniform* should generate INVALID_OPERATION "
   5106 				<< "if the location refers to an image variable." << tcu::TestLog::EndMessage;
   5107 			return ERROR;
   5108 		}
   5109 
   5110 		glUseProgram(0);
   5111 		glProgramUniform1i(m_program, glGetUniformLocation(m_program, "g_image"), 1);
   5112 		if (glGetError() != GL_INVALID_OPERATION)
   5113 			status = false;
   5114 		glProgramUniform1iv(m_program, glGetUniformLocation(m_program, "g_image"), 1, &i);
   5115 		if (glGetError() != GL_INVALID_OPERATION)
   5116 			status = false;
   5117 		glProgramUniform1ui(m_program, glGetUniformLocation(m_program, "g_image"), 0);
   5118 		if (glGetError() != GL_INVALID_OPERATION)
   5119 			status = false;
   5120 		glProgramUniform2i(m_program, glGetUniformLocation(m_program, "g_image"), 0, 0);
   5121 		if (glGetError() != GL_INVALID_OPERATION)
   5122 			status = false;
   5123 
   5124 		if (!status)
   5125 		{
   5126 			m_context.getTestContext().getLog()
   5127 				<< tcu::TestLog::Message << "glProgramUniform* should generate INVALID_OPERATION "
   5128 				<< "if the location refers to an image variable." << tcu::TestLog::EndMessage;
   5129 			return ERROR;
   5130 		}
   5131 
   5132 		return NO_ERROR;
   5133 	}
   5134 
   5135 	virtual long Cleanup()
   5136 	{
   5137 		glUseProgram(0);
   5138 		glDeleteProgram(m_program);
   5139 		return NO_ERROR;
   5140 	}
   5141 };
   5142 
   5143 //-----------------------------------------------------------------------------
   5144 // 4.2 NegativeBind
   5145 //-----------------------------------------------------------------------------
   5146 class NegativeBind : public ShaderImageLoadStoreBase
   5147 {
   5148 	GLuint m_texture, m_texture2;
   5149 
   5150 	virtual long Setup()
   5151 	{
   5152 		m_texture  = 0;
   5153 		m_texture2 = 0;
   5154 		return NO_ERROR;
   5155 	}
   5156 
   5157 	virtual long Run()
   5158 	{
   5159 		GLint max_image_units;
   5160 		glGetIntegerv(GL_MAX_IMAGE_UNITS, &max_image_units);
   5161 		glGenTextures(1, &m_texture);
   5162 		glBindTexture(GL_TEXTURE_2D, m_texture);
   5163 		glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 64, 64);
   5164 
   5165 		glBindImageTexture(max_image_units, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   5166 		if (glGetError() != GL_INVALID_VALUE)
   5167 		{
   5168 			m_context.getTestContext().getLog()
   5169 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <unit> "
   5170 				<< "is greater than or equal to the value of MAX_IMAGE_UNITS." << tcu::TestLog::EndMessage;
   5171 			return ERROR;
   5172 		}
   5173 
   5174 		glBindImageTexture(0, 123, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   5175 		if (glGetError() != GL_INVALID_VALUE)
   5176 		{
   5177 			m_context.getTestContext().getLog()
   5178 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <texture> "
   5179 				<< "is not the name of an existing texture object." << tcu::TestLog::EndMessage;
   5180 			return ERROR;
   5181 		}
   5182 
   5183 		glBindImageTexture(1, m_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA);
   5184 		if (glGetError() != GL_INVALID_VALUE)
   5185 		{
   5186 			m_context.getTestContext().getLog()
   5187 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <format> "
   5188 				<< "is not a legal format." << tcu::TestLog::EndMessage;
   5189 			return ERROR;
   5190 		}
   5191 
   5192 		glBindImageTexture(1, m_texture, -1, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   5193 		if (glGetError() != GL_INVALID_VALUE)
   5194 		{
   5195 			m_context.getTestContext().getLog()
   5196 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <level> "
   5197 				<< "is less than zero." << tcu::TestLog::EndMessage;
   5198 			return ERROR;
   5199 		}
   5200 
   5201 		glBindImageTexture(1, m_texture, 0, GL_FALSE, -1, GL_READ_ONLY, GL_RGBA32F);
   5202 		if (glGetError() != GL_INVALID_VALUE)
   5203 		{
   5204 			m_context.getTestContext().getLog()
   5205 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <layer> "
   5206 				<< "is less than zero." << tcu::TestLog::EndMessage;
   5207 			return ERROR;
   5208 		}
   5209 
   5210 		glGenTextures(1, &m_texture2);
   5211 		glBindTexture(GL_TEXTURE_2D, m_texture2);
   5212 		glBindImageTexture(1, m_texture2, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
   5213 		if (glGetError() != GL_INVALID_OPERATION)
   5214 		{
   5215 			m_context.getTestContext().getLog()
   5216 				<< tcu::TestLog::Message << "BindImageTexture should generate INVALID_VALUE if <texture> "
   5217 				<< "is a mutable texture object." << tcu::TestLog::EndMessage;
   5218 			return ERROR;
   5219 		}
   5220 
   5221 		return NO_ERROR;
   5222 	}
   5223 
   5224 	virtual long Cleanup()
   5225 	{
   5226 		glDeleteTextures(1, &m_texture);
   5227 		glDeleteTextures(1, &m_texture2);
   5228 		return NO_ERROR;
   5229 	}
   5230 };
   5231 
   5232 //-----------------------------------------------------------------------------
   5233 // 4.3 NegativeCompileErrors
   5234 //-----------------------------------------------------------------------------
   5235 class NegativeCompileErrors : public ShaderImageLoadStoreBase
   5236 {
   5237 	virtual long Run()
   5238 	{
   5239 		if (!Compile( // writeonly & readonly qualifiers
   5240 				NL "layout(rgba32f) writeonly readonly uniform image2D g_image;" NL "void main() {" NL
   5241 				   "  vec4 o_color;" NL "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
   5242 			return ERROR;
   5243 
   5244 		if (!Compile( // writeonly && reading
   5245 				NL "layout(rgba32f) writeonly uniform image2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5246 				   "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
   5247 			return ERROR;
   5248 
   5249 		if (!Compile( //readonly && writing
   5250 				NL "uniform vec4 i_color;" NL "layout(rgba32f) readonly uniform image2D g_image;" NL "void main() {" NL
   5251 				   "  vec4 o_color;" NL "  imageStore(g_image, ivec2(0), i_color);" NL "  o_color = i_color;" NL "}"))
   5252 			return ERROR;
   5253 
   5254 		if (!Compile( // no format layout && load
   5255 				NL "uniform image2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5256 				   "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
   5257 			return ERROR;
   5258 
   5259 		if (!Compile( // no fromat layout && readonly && load
   5260 				NL "readonly uniform image2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5261 				   "  o_color = imageLoad(g_image, ivec2(0));" NL "}"))
   5262 			return ERROR;
   5263 
   5264 		if (!Compile( // target type image1D not supported
   5265 				NL "layout(r32i) uniform image1D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5266 				   "  o_color = vec4(1.0);" NL "}"))
   5267 			return ERROR;
   5268 
   5269 		if (!Compile( // format layout not compatible with type
   5270 				NL "layout(rgba16) writeonly uniform iimage2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5271 				   "  o_color = vec4(1.0);" NL "}"))
   5272 			return ERROR;
   5273 
   5274 		if (!Compile( // imageAtomicAdd doesn't support r32f
   5275 				NL "#extension GL_OES_shader_image_atomic : require" NL
   5276 				   "layout(r32f) coherent uniform image2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5277 				   "  imageAtomicAdd(g_image, ivec2(1), 10);" NL "  o_color = vec4(1.0);" NL "}"))
   5278 			return ERROR;
   5279 
   5280 		if (!Compile( // imageAtomicAdd doesn't support rgba8i
   5281 				NL "#extension GL_OES_shader_image_atomic : require" NL
   5282 				   "layout(rgba8i) coherent uniform iimage2D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5283 				   "  imageAtomicAdd(g_image, ivec2(1), 1);" NL "  o_color = vec4(1.0);" NL "}"))
   5284 			return ERROR;
   5285 
   5286 		if (!Compile( // format layout not compatible with type
   5287 				NL "layout(r32ui) uniform iimage3D g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5288 				   "  imageStore(g_image, ivec3(1), ivec4(1));" NL "  o_color = vec4(1.0);" NL "}"))
   5289 			return ERROR;
   5290 
   5291 		if (!Compile( // format layout not compatible with type
   5292 				NL "layout(r32f) uniform uimage2DArray g_image;" NL "void main() {" NL "  vec4 o_color;" NL
   5293 				   "  imageStore(g_image, ivec3(0), uvec4(1));" NL "  o_color = vec4(1.0);" NL "}"))
   5294 			return ERROR;
   5295 
   5296 		if (!Compile( // wrong function argument type
   5297 				NL "layout(r32f) coherent uniform image2D g_image;" NL "vec4 Load(iimage2D image) {" NL
   5298 				   "  return imageLoad(image, vec2(0));" NL "}" NL "void main() {" NL "  vec4 o_color;" NL
   5299 				   "  o_color = Load(g_image);" NL "}"))
   5300 			return ERROR;
   5301 
   5302 		return NO_ERROR;
   5303 	}
   5304 
   5305 	bool Compile(const std::string& source)
   5306 	{
   5307 		const char* const csVer  = "#version 310 es" NL "layout(local_size_x = 1) in;";
   5308 		const char* const src[3] = { csVer, kGLSLPrec, source.c_str() };
   5309 		const GLuint	  sh	 = glCreateShader(GL_COMPUTE_SHADER);
   5310 		glShaderSource(sh, 3, src, NULL);
   5311 		glCompileShader(sh);
   5312 
   5313 		GLchar log[1024];
   5314 		glGetShaderInfoLog(sh, sizeof(log), NULL, log);
   5315 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
   5316 											<< log << tcu::TestLog::EndMessage;
   5317 
   5318 		GLint status;
   5319 		glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
   5320 		glDeleteShader(sh);
   5321 
   5322 		if (status == GL_TRUE)
   5323 		{
   5324 			m_context.getTestContext().getLog()
   5325 				<< tcu::TestLog::Message << "Compilation should fail [compute shader]." << tcu::TestLog::EndMessage;
   5326 			return false;
   5327 		}
   5328 		const char* const fsVer   = "#version 310 es" NL "precision highp float;";
   5329 		const char* const fsrc[3] = { fsVer, kGLSLPrec, source.c_str() };
   5330 		const GLuint	  fsh	 = glCreateShader(GL_FRAGMENT_SHADER);
   5331 		glShaderSource(fsh, 3, fsrc, NULL);
   5332 		glCompileShader(fsh);
   5333 
   5334 		glGetShaderInfoLog(fsh, sizeof(log), NULL, log);
   5335 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
   5336 											<< log << tcu::TestLog::EndMessage;
   5337 		glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
   5338 		glDeleteShader(fsh);
   5339 
   5340 		if (status == GL_TRUE)
   5341 		{
   5342 			m_context.getTestContext().getLog()
   5343 				<< tcu::TestLog::Message << "Compilation should fail [fragment shader]." << tcu::TestLog::EndMessage;
   5344 			return false;
   5345 		}
   5346 
   5347 		return true;
   5348 	}
   5349 };
   5350 
   5351 //-----------------------------------------------------------------------------
   5352 // 4.4 NegativeLinkErrors
   5353 //-----------------------------------------------------------------------------
   5354 class NegativeLinkErrors : public ShaderImageLoadStoreBase
   5355 {
   5356 	virtual long Run()
   5357 	{
   5358 		if (!IsVSFSAvailable(1, 1))
   5359 			return NOT_SUPPORTED;
   5360 		if (!Link(NL "layout(location = 0) in vec4 i_position;" NL
   5361 					 "layout(rgba32f) writeonly uniform highp image3D g_image;" NL "void main() {" NL
   5362 					 "  imageStore(g_image, ivec3(gl_VertexID), vec4(0));" NL "  gl_Position = i_position;" NL "}",
   5363 
   5364 				  NL "precision highp float;" NL "layout(location = 0) out vec4 o_color;" NL
   5365 					 "layout(rgba32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL
   5366 					 "  imageStore(g_image, ivec2(gl_FragCoord), vec4(1.0));" NL "  o_color = vec4(1.0);" NL "}"))
   5367 			return ERROR;
   5368 
   5369 		if (!Link(NL "layout(location = 0) in vec4 i_position;" NL
   5370 					 "layout(rgba32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL
   5371 					 "  imageStore(g_image, ivec2(gl_VertexID), vec4(0));" NL "  gl_Position = i_position;" NL "}",
   5372 
   5373 				  NL "precision highp float;" NL "layout(location = 0) out vec4 o_color;" NL
   5374 					 "layout(r32f) writeonly uniform highp image2D g_image;" NL "void main() {" NL
   5375 					 "  imageStore(g_image, ivec2(gl_FragCoord), vec4(1.0));" NL "  o_color = vec4(1.0);" NL "}"))
   5376 			return ERROR;
   5377 
   5378 		return NO_ERROR;
   5379 	}
   5380 
   5381 	bool Link(const std::string& vs, const std::string& fs)
   5382 	{
   5383 		const char* const sVer = "#version 310 es";
   5384 		const GLuint	  p	= glCreateProgram();
   5385 
   5386 		const GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
   5387 		glAttachShader(p, vsh);
   5388 		glDeleteShader(vsh);
   5389 		const char* const vssrc[2] = { sVer, vs.c_str() };
   5390 		glShaderSource(vsh, 2, vssrc, NULL);
   5391 		glCompileShader(vsh);
   5392 
   5393 		const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
   5394 		glAttachShader(p, fsh);
   5395 		glDeleteShader(fsh);
   5396 		const char* const fssrc[2] = { sVer, fs.c_str() };
   5397 		glShaderSource(fsh, 2, fssrc, NULL);
   5398 		glCompileShader(fsh);
   5399 
   5400 		GLint status;
   5401 		glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
   5402 		if (status == GL_FALSE)
   5403 		{
   5404 			glDeleteProgram(p);
   5405 			m_context.getTestContext().getLog()
   5406 				<< tcu::TestLog::Message << "VS compilation should be ok." << tcu::TestLog::EndMessage;
   5407 			return false;
   5408 		}
   5409 		glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
   5410 		if (status == GL_FALSE)
   5411 		{
   5412 			glDeleteProgram(p);
   5413 			m_context.getTestContext().getLog()
   5414 				<< tcu::TestLog::Message << "FS compilation should be ok." << tcu::TestLog::EndMessage;
   5415 			return false;
   5416 		}
   5417 
   5418 		glLinkProgram(p);
   5419 
   5420 		GLchar log[1024];
   5421 		glGetProgramInfoLog(p, sizeof(log), NULL, log);
   5422 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program Info Log:\n"
   5423 											<< log << tcu::TestLog::EndMessage;
   5424 
   5425 		glGetProgramiv(p, GL_LINK_STATUS, &status);
   5426 		glDeleteProgram(p);
   5427 
   5428 		if (status == GL_TRUE)
   5429 		{
   5430 			m_context.getTestContext().getLog()
   5431 				<< tcu::TestLog::Message << "Link operation should fail." << tcu::TestLog::EndMessage;
   5432 			return false;
   5433 		}
   5434 
   5435 		return true;
   5436 	}
   5437 };
   5438 
   5439 } // anonymous namespace
   5440 
   5441 ShaderImageLoadStoreTests::ShaderImageLoadStoreTests(deqp::Context& context)
   5442 	: TestCaseGroup(context, "shader_image_load_store", "")
   5443 {
   5444 }
   5445 
   5446 ShaderImageLoadStoreTests::~ShaderImageLoadStoreTests(void)
   5447 {
   5448 }
   5449 
   5450 void ShaderImageLoadStoreTests::init()
   5451 {
   5452 	using namespace deqp;
   5453 	addChild(new TestSubcase(m_context, "basic-api-get", TestSubcase::Create<BasicAPIGet>));
   5454 	addChild(new TestSubcase(m_context, "basic-api-bind", TestSubcase::Create<BasicAPIBind>));
   5455 	addChild(new TestSubcase(m_context, "basic-api-barrier", TestSubcase::Create<BasicAPIBarrier>));
   5456 	addChild(new TestSubcase(m_context, "basic-api-barrier-byRegion", TestSubcase::Create<BasicAPIBarrierByRegion>));
   5457 	addChild(new TestSubcase(m_context, "basic-api-texParam", TestSubcase::Create<BasicAPITexParam>));
   5458 	addChild(new TestSubcase(m_context, "basic-allFormats-store-fs", TestSubcase::Create<BasicAllFormatsStoreFS>));
   5459 	addChild(new TestSubcase(m_context, "basic-allFormats-store-cs", TestSubcase::Create<BasicAllFormatsStoreCS>));
   5460 	addChild(new TestSubcase(m_context, "basic-allFormats-load-fs", TestSubcase::Create<BasicAllFormatsLoadFS>));
   5461 	addChild(new TestSubcase(m_context, "basic-allFormats-load-cs", TestSubcase::Create<BasicAllFormatsLoadCS>));
   5462 	addChild(new TestSubcase(m_context, "basic-allFormats-loadStoreComputeStage",
   5463 							 TestSubcase::Create<BasicAllFormatsLoadStoreComputeStage>));
   5464 	addChild(new TestSubcase(m_context, "basic-allTargets-store-fs", TestSubcase::Create<BasicAllTargetsStoreFS>));
   5465 	addChild(new TestSubcase(m_context, "basic-allTargets-store-cs", TestSubcase::Create<BasicAllTargetsStoreCS>));
   5466 	addChild(new TestSubcase(m_context, "basic-allTargets-load-fs", TestSubcase::Create<BasicAllTargetsLoadFS>));
   5467 	addChild(new TestSubcase(m_context, "basic-allTargets-load-cs", TestSubcase::Create<BasicAllTargetsLoadCS>));
   5468 	addChild(new TestSubcase(m_context, "basic-allTargets-atomicFS", TestSubcase::Create<BasicAllTargetsAtomicFS>));
   5469 	addChild(
   5470 		new TestSubcase(m_context, "basic-allTargets-loadStoreVS", TestSubcase::Create<BasicAllTargetsLoadStoreVS>));
   5471 	addChild(
   5472 		new TestSubcase(m_context, "basic-allTargets-loadStoreCS", TestSubcase::Create<BasicAllTargetsLoadStoreCS>));
   5473 	addChild(new TestSubcase(m_context, "basic-allTargets-atomicVS", TestSubcase::Create<BasicAllTargetsAtomicVS>));
   5474 	addChild(new TestSubcase(m_context, "basic-allTargets-atomicCS", TestSubcase::Create<BasicAllTargetsAtomicCS>));
   5475 	addChild(new TestSubcase(m_context, "basic-glsl-misc-fs", TestSubcase::Create<BasicGLSLMiscFS>));
   5476 	addChild(new TestSubcase(m_context, "basic-glsl-misc-cs", TestSubcase::Create<BasicGLSLMiscCS>));
   5477 	addChild(new TestSubcase(m_context, "basic-glsl-earlyFragTests", TestSubcase::Create<BasicGLSLEarlyFragTests>));
   5478 	addChild(new TestSubcase(m_context, "basic-glsl-const", TestSubcase::Create<BasicGLSLConst>));
   5479 	addChild(new TestSubcase(m_context, "advanced-sync-imageAccess", TestSubcase::Create<AdvancedSyncImageAccess>));
   5480 	addChild(new TestSubcase(m_context, "advanced-sync-vertexArray", TestSubcase::Create<AdvancedSyncVertexArray>));
   5481 	addChild(new TestSubcase(m_context, "advanced-sync-imageAccess2", TestSubcase::Create<AdvancedSyncImageAccess2>));
   5482 	addChild(new TestSubcase(m_context, "advanced-allStages-oneImage", TestSubcase::Create<AdvancedAllStagesOneImage>));
   5483 	addChild(new TestSubcase(m_context, "advanced-memory-order-vsfs", TestSubcase::Create<AdvancedMemoryOrderVSFS>));
   5484 	addChild(new TestSubcase(m_context, "advanced-sso-simple", TestSubcase::Create<AdvancedSSOSimple>));
   5485 	addChild(new TestSubcase(m_context, "advanced-copyImage-fs", TestSubcase::Create<AdvancedCopyImageFS>));
   5486 	addChild(new TestSubcase(m_context, "advanced-copyImage-cs", TestSubcase::Create<AdvancedCopyImageCS>));
   5487 	addChild(new TestSubcase(m_context, "advanced-allMips-fs", TestSubcase::Create<AdvancedAllMipsFS>));
   5488 	addChild(new TestSubcase(m_context, "advanced-allMips-cs", TestSubcase::Create<AdvancedAllMipsCS>));
   5489 	addChild(new TestSubcase(m_context, "advanced-cast-fs", TestSubcase::Create<AdvancedCastFS>));
   5490 	addChild(new TestSubcase(m_context, "advanced-cast-cs", TestSubcase::Create<AdvancedCastCS>));
   5491 	addChild(new TestSubcase(m_context, "negative-uniform", TestSubcase::Create<NegativeUniform>));
   5492 	addChild(new TestSubcase(m_context, "negative-bind", TestSubcase::Create<NegativeBind>));
   5493 	addChild(new TestSubcase(m_context, "negative-compileErrors", TestSubcase::Create<NegativeCompileErrors>));
   5494 	addChild(new TestSubcase(m_context, "negative-linkErrors", TestSubcase::Create<NegativeLinkErrors>));
   5495 }
   5496 
   5497 } // namespace es31compatibility
   5498 } // namespace gl4cts
   5499