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 "gl4cShaderImageSizeTests.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 
     33 namespace gl4cts
     34 {
     35 using namespace glw;
     36 
     37 namespace
     38 {
     39 typedef tcu::Vec3  vec3;
     40 typedef tcu::Vec4  vec4;
     41 typedef tcu::IVec4 ivec4;
     42 typedef tcu::UVec4 uvec4;
     43 
     44 class ShaderImageSizeBase : public deqp::SubcaseBase
     45 {
     46 	virtual std::string Title()
     47 	{
     48 		return "";
     49 	}
     50 
     51 	virtual std::string Purpose()
     52 	{
     53 		return "";
     54 	}
     55 
     56 	virtual std::string Method()
     57 	{
     58 		return "";
     59 	}
     60 
     61 	virtual std::string PassCriteria()
     62 	{
     63 		return "";
     64 	}
     65 
     66 public:
     67 	bool SupportedInVS(int requiredVS)
     68 	{
     69 		GLint imagesVS;
     70 		glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &imagesVS);
     71 		if (imagesVS >= requiredVS)
     72 			return true;
     73 		else
     74 		{
     75 			std::ostringstream reason;
     76 			reason << "Required " << requiredVS << " VS image uniforms but only " << imagesVS << " available."
     77 				   << std::endl;
     78 			OutputNotSupported(reason.str());
     79 			return false;
     80 		}
     81 	}
     82 
     83 	bool SupportedInTCS(int requiredTCS)
     84 	{
     85 		GLint imagesTCS;
     86 		glGetIntegerv(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, &imagesTCS);
     87 		if (imagesTCS >= requiredTCS)
     88 			return true;
     89 		else
     90 		{
     91 			std::ostringstream reason;
     92 			reason << "Required " << requiredTCS << " TCS image uniforms but only " << imagesTCS << " available."
     93 				   << std::endl;
     94 			OutputNotSupported(reason.str());
     95 			return false;
     96 		}
     97 	}
     98 
     99 	bool SupportedInTES(int requiredTES)
    100 	{
    101 		GLint imagesTES;
    102 		glGetIntegerv(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, &imagesTES);
    103 		if (imagesTES >= requiredTES)
    104 			return true;
    105 		else
    106 		{
    107 			std::ostringstream reason;
    108 			reason << "Required " << requiredTES << " TES image uniforms but only " << imagesTES << " available."
    109 				   << std::endl;
    110 			OutputNotSupported(reason.str());
    111 			return false;
    112 		}
    113 	}
    114 
    115 	bool SupportedInGS(int requiredGS)
    116 	{
    117 		GLint imagesGS;
    118 		glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS, &imagesGS);
    119 		if (imagesGS >= requiredGS)
    120 			return true;
    121 		else
    122 		{
    123 			std::ostringstream reason;
    124 			reason << "Required " << requiredGS << " GS image uniforms but only " << imagesGS << " available."
    125 				   << std::endl;
    126 			OutputNotSupported(reason.str());
    127 			return false;
    128 		}
    129 	}
    130 
    131 	bool SupportedInStage(int stage, int required)
    132 	{
    133 		switch (stage)
    134 		{
    135 		case 0:
    136 			return SupportedInVS(required);
    137 		case 1:
    138 			return SupportedInTCS(required);
    139 		case 2:
    140 			return SupportedInTES(required);
    141 		case 3:
    142 			return SupportedInGS(required);
    143 		default:
    144 			return true;
    145 		}
    146 	}
    147 
    148 	bool SupportedSamples(int required)
    149 	{
    150 		int i;
    151 		glGetIntegerv(GL_MAX_IMAGE_SAMPLES, &i);
    152 		if (i >= required)
    153 			return true;
    154 		else
    155 		{
    156 			std::ostringstream reason;
    157 			reason << "Required " << required << " image samples but only " << i << " available." << std::endl;
    158 			OutputNotSupported(reason.str());
    159 			return false;
    160 		}
    161 	}
    162 
    163 	int getWindowWidth()
    164 	{
    165 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    166 		return renderTarget.getWidth();
    167 	}
    168 
    169 	int getWindowHeight()
    170 	{
    171 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    172 		return renderTarget.getHeight();
    173 	}
    174 
    175 	inline bool ColorEqual(const vec4& c0, const vec4& c1, const vec4& epsilon)
    176 	{
    177 		if (fabs(c0[0] - c1[0]) > epsilon[0])
    178 			return false;
    179 		if (fabs(c0[1] - c1[1]) > epsilon[1])
    180 			return false;
    181 		if (fabs(c0[2] - c1[2]) > epsilon[2])
    182 			return false;
    183 		if (fabs(c0[3] - c1[3]) > epsilon[3])
    184 			return false;
    185 		return true;
    186 	}
    187 
    188 	template <class T>
    189 	std::string ToString(T v)
    190 	{
    191 		std::ostringstream s;
    192 		s << "[";
    193 		for (int i = 0; i < 4; ++i)
    194 			s << v[i] << (i == 3 ? "" : ",");
    195 		s << "]";
    196 		return s.str();
    197 	}
    198 
    199 	bool ValidateReadBuffer(int x, int y, int w, int h, const vec4& expected)
    200 	{
    201 		bool					 status		  = true;
    202 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
    203 		const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
    204 		vec4					 g_color_eps  = vec4(
    205 			1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
    206 			1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
    207 
    208 		std::vector<vec4> fb(w * h);
    209 		glReadPixels(x, y, w, h, GL_RGBA, GL_FLOAT, &fb[0]);
    210 
    211 		for (int yy = 0; yy < h; ++yy)
    212 		{
    213 			for (int xx = 0; xx < w; ++xx)
    214 			{
    215 				const int idx = yy * w + xx;
    216 				if (!ColorEqual(fb[idx], expected, g_color_eps))
    217 				{
    218 					m_context.getTestContext().getLog()
    219 						<< tcu::TestLog::Message << "First bad color: " << ToString(fb[idx])
    220 						<< tcu::TestLog::EndMessage;
    221 					status = false;
    222 					return status;
    223 				}
    224 			}
    225 		}
    226 		return status;
    227 	}
    228 
    229 	bool CheckProgram(GLuint program)
    230 	{
    231 		if (program == 0)
    232 			return true;
    233 		GLint status;
    234 		glGetProgramiv(program, GL_LINK_STATUS, &status);
    235 
    236 		if (status == GL_FALSE)
    237 		{
    238 			GLint attached_shaders;
    239 			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
    240 
    241 			if (attached_shaders > 0)
    242 			{
    243 				std::vector<GLuint> shaders(attached_shaders);
    244 				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
    245 
    246 				for (GLint i = 0; i < attached_shaders; ++i)
    247 				{
    248 					GLenum type;
    249 					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
    250 					switch (type)
    251 					{
    252 					case GL_VERTEX_SHADER:
    253 						m_context.getTestContext().getLog()
    254 							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
    255 						break;
    256 					case GL_TESS_CONTROL_SHADER:
    257 						m_context.getTestContext().getLog()
    258 							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
    259 							<< tcu::TestLog::EndMessage;
    260 						break;
    261 					case GL_TESS_EVALUATION_SHADER:
    262 						m_context.getTestContext().getLog()
    263 							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
    264 							<< tcu::TestLog::EndMessage;
    265 						break;
    266 					case GL_GEOMETRY_SHADER:
    267 						m_context.getTestContext().getLog()
    268 							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
    269 						break;
    270 					case GL_FRAGMENT_SHADER:
    271 						m_context.getTestContext().getLog()
    272 							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
    273 						break;
    274 					case GL_COMPUTE_SHADER:
    275 						m_context.getTestContext().getLog()
    276 							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
    277 						break;
    278 					default:
    279 						m_context.getTestContext().getLog()
    280 							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
    281 						break;
    282 					}
    283 					GLint length;
    284 					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
    285 					if (length > 0)
    286 					{
    287 						std::vector<GLchar> source(length);
    288 						glGetShaderSource(shaders[i], length, NULL, &source[0]);
    289 						m_context.getTestContext().getLog()
    290 							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
    291 					}
    292 					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
    293 					if (length > 0)
    294 					{
    295 						std::vector<GLchar> log(length);
    296 						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
    297 						m_context.getTestContext().getLog()
    298 							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
    299 					}
    300 				}
    301 			}
    302 			GLint length;
    303 			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
    304 			if (length > 0)
    305 			{
    306 				std::vector<GLchar> log(length);
    307 				glGetProgramInfoLog(program, length, NULL, &log[0]);
    308 				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
    309 			}
    310 		}
    311 		return status == GL_TRUE ? true : false;
    312 	}
    313 };
    314 
    315 template <typename T>
    316 std::string ImageTypePrefix();
    317 
    318 template <>
    319 std::string ImageTypePrefix<vec4>()
    320 {
    321 	return "";
    322 }
    323 
    324 template <>
    325 std::string ImageTypePrefix<ivec4>()
    326 {
    327 	return "i";
    328 }
    329 
    330 template <>
    331 std::string ImageTypePrefix<uvec4>()
    332 {
    333 	return "u";
    334 }
    335 
    336 template <typename T>
    337 std::string ImageFormatPostfix();
    338 
    339 template <>
    340 std::string ImageFormatPostfix<vec4>()
    341 {
    342 	return "f";
    343 }
    344 
    345 template <>
    346 std::string ImageFormatPostfix<ivec4>()
    347 {
    348 	return "i";
    349 }
    350 
    351 template <>
    352 std::string ImageFormatPostfix<uvec4>()
    353 {
    354 	return "ui";
    355 }
    356 
    357 template <typename T>
    358 GLenum TexInternalFormat();
    359 
    360 template <>
    361 GLenum TexInternalFormat<vec4>()
    362 {
    363 	return GL_RGBA32F;
    364 }
    365 
    366 template <>
    367 GLenum TexInternalFormat<ivec4>()
    368 {
    369 	return GL_RGBA32I;
    370 }
    371 
    372 template <>
    373 GLenum TexInternalFormat<uvec4>()
    374 {
    375 	return GL_RGBA32UI;
    376 }
    377 
    378 template <typename T>
    379 GLenum TexType();
    380 
    381 template <>
    382 GLenum TexType<vec4>()
    383 {
    384 	return GL_FLOAT;
    385 }
    386 
    387 template <>
    388 GLenum TexType<ivec4>()
    389 {
    390 	return GL_INT;
    391 }
    392 
    393 template <>
    394 GLenum TexType<uvec4>()
    395 {
    396 	return GL_UNSIGNED_INT;
    397 }
    398 
    399 template <typename T>
    400 GLenum TexFormat();
    401 
    402 template <>
    403 GLenum TexFormat<vec4>()
    404 {
    405 	return GL_RGBA;
    406 }
    407 
    408 template <>
    409 GLenum TexFormat<ivec4>()
    410 {
    411 	return GL_RGBA_INTEGER;
    412 }
    413 
    414 template <>
    415 GLenum TexFormat<uvec4>()
    416 {
    417 	return GL_RGBA_INTEGER;
    418 }
    419 //=============================================================================
    420 // ImageSizeMachine
    421 //-----------------------------------------------------------------------------
    422 class ImageSizeMachine : public deqp::GLWrapper
    423 {
    424 	GLuint m_pipeline;
    425 	GLuint m_program[3];
    426 	GLuint m_vertex_array;
    427 	GLuint m_texture;
    428 
    429 	template <typename T>
    430 	std::string GenShader(int stage, bool ms_and_1d, bool subroutine)
    431 	{
    432 		std::ostringstream os;
    433 		os << "#version 430 core";
    434 		if (stage == 4)
    435 		{ // CS
    436 			os << NL "#extension GL_ARB_compute_shader : require";
    437 		}
    438 		os << NL "layout(binding = 0, rgba32i) writeonly uniform iimage2D g_result;";
    439 		if (ms_and_1d == false)
    440 		{
    441 			os << NL "layout(binding = 1, rgba32" << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>()
    442 			   << "image2D g_image_2d;" NL "layout(binding = 2, rgba32" << ImageFormatPostfix<T>() << ") uniform "
    443 			   << ImageTypePrefix<T>() << "image3D g_image_3d;" NL "layout(binding = 3, rgba32"
    444 			   << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>()
    445 			   << "imageCube g_image_cube;" NL "layout(binding = 4, rgba32" << ImageFormatPostfix<T>() << ") uniform "
    446 			   << ImageTypePrefix<T>() << "imageCubeArray g_image_cube_array;" NL "layout(binding = 5, rgba32"
    447 			   << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>()
    448 			   << "image2DRect g_image_rect;" NL "layout(binding = 6, rgba32" << ImageFormatPostfix<T>() << ") uniform "
    449 			   << ImageTypePrefix<T>() << "image2DArray g_image_2d_array;" NL "layout(binding = 7, rgba32"
    450 			   << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>() << "imageBuffer g_image_buffer;";
    451 		}
    452 		else
    453 		{
    454 			os << NL "layout(binding = 1, rgba32" << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>()
    455 			   << "image1D g_image_1d;" NL "layout(binding = 2, rgba32" << ImageFormatPostfix<T>() << ") uniform "
    456 			   << ImageTypePrefix<T>() << "image1DArray g_image_1d_array;" NL "layout(binding = 3, rgba32"
    457 			   << ImageFormatPostfix<T>() << ") uniform " << ImageTypePrefix<T>()
    458 			   << "image2DMS g_image_2dms;" NL "layout(binding = 4, rgba32" << ImageFormatPostfix<T>() << ") uniform "
    459 			   << ImageTypePrefix<T>() << "image2DMSArray g_image_2dms_array;";
    460 		}
    461 		if (subroutine)
    462 		{
    463 			os << NL "subroutine void FuncType(int coord);" NL "subroutine uniform FuncType g_func;";
    464 		}
    465 		if (stage == 0)
    466 		{ // VS
    467 			os << NL "void main() {" NL "  int coord = gl_VertexID;";
    468 		}
    469 		else if (stage == 1)
    470 		{ // TCS
    471 			os << NL "layout(vertices = 1) out;" NL "void main() {" NL "  gl_TessLevelInner[0] = 1;" NL
    472 					 "  gl_TessLevelInner[1] = 1;" NL "  gl_TessLevelOuter[0] = 1;" NL "  gl_TessLevelOuter[1] = 1;" NL
    473 					 "  gl_TessLevelOuter[2] = 1;" NL "  gl_TessLevelOuter[3] = 1;" NL "  int coord = gl_PrimitiveID;";
    474 		}
    475 		else if (stage == 2)
    476 		{ // TES
    477 			os << NL "layout(quads, point_mode) in;" NL "void main() {" NL "  int coord = gl_PrimitiveID;";
    478 		}
    479 		else if (stage == 3)
    480 		{ // GS
    481 			os << NL "layout(points) in;" NL "layout(points, max_vertices = 1) out;" NL "void main() {" NL
    482 					 "  int coord = gl_PrimitiveIDIn;";
    483 		}
    484 		else if (stage == 4)
    485 		{ // CS
    486 			os << NL "layout(local_size_x = 1) in;" NL "void main() {" NL "  int coord = int(gl_GlobalInvocationID.x);";
    487 		}
    488 		else if (stage == 5)
    489 		{ // FS
    490 			os << NL "void main() {" NL "  int coord = gl_PrimitiveID;";
    491 		}
    492 		if (subroutine)
    493 		{
    494 			os << NL "  g_func(coord);" NL "}" NL "subroutine(FuncType) void Func0(int coord) {";
    495 		}
    496 		if (ms_and_1d == false)
    497 		{
    498 			os << NL "  imageStore(g_result, ivec2(coord, 0), ivec4(imageSize(g_image_2d), 0, 0));" NL
    499 					 "  imageStore(g_result, ivec2(coord, 1), ivec4(imageSize(g_image_3d), 0));" NL
    500 					 "  imageStore(g_result, ivec2(coord, 2), ivec4(imageSize(g_image_cube), 0, 0));" NL
    501 					 "  imageStore(g_result, ivec2(coord, 3), ivec4(imageSize(g_image_cube_array), 0));" NL
    502 					 "  imageStore(g_result, ivec2(coord, 4), ivec4(imageSize(g_image_rect), 0, 0));" NL
    503 					 "  imageStore(g_result, ivec2(coord, 5), ivec4(imageSize(g_image_2d_array), 0));" NL
    504 					 "  imageStore(g_result, ivec2(coord, 6), ivec4(imageSize(g_image_buffer), 0, 0, 0));" NL "}";
    505 		}
    506 		else
    507 		{
    508 			os << NL "  imageStore(g_result, ivec2(coord, 0), ivec4(imageSize(g_image_1d), 0, 0, 0));" NL
    509 					 "  imageStore(g_result, ivec2(coord, 1), ivec4(imageSize(g_image_1d_array), 0, 0));" NL
    510 					 "  imageStore(g_result, ivec2(coord, 2), ivec4(imageSize(g_image_2dms), 0, 0));" NL
    511 					 "  imageStore(g_result, ivec2(coord, 3), ivec4(imageSize(g_image_2dms_array), 0));" NL
    512 					 "  imageStore(g_result, ivec2(coord, 4), ivec4(0));" NL
    513 					 "  imageStore(g_result, ivec2(coord, 5), ivec4(0));" NL
    514 					 "  imageStore(g_result, ivec2(coord, 6), ivec4(0));" NL "}";
    515 		}
    516 		return os.str();
    517 	}
    518 
    519 	bool CheckProgram(GLuint program)
    520 	{
    521 		if (program == 0)
    522 			return true;
    523 		GLint status;
    524 		glGetProgramiv(program, GL_LINK_STATUS, &status);
    525 
    526 		if (status == GL_FALSE)
    527 		{
    528 			GLint attached_shaders;
    529 			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
    530 
    531 			if (attached_shaders > 0)
    532 			{
    533 				std::vector<GLuint> shaders(attached_shaders);
    534 				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
    535 
    536 				for (GLint i = 0; i < attached_shaders; ++i)
    537 				{
    538 					GLenum type;
    539 					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
    540 					switch (type)
    541 					{
    542 					case GL_VERTEX_SHADER:
    543 						m_context.getTestContext().getLog()
    544 							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
    545 						break;
    546 					case GL_TESS_CONTROL_SHADER:
    547 						m_context.getTestContext().getLog()
    548 							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
    549 							<< tcu::TestLog::EndMessage;
    550 						break;
    551 					case GL_TESS_EVALUATION_SHADER:
    552 						m_context.getTestContext().getLog()
    553 							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
    554 							<< tcu::TestLog::EndMessage;
    555 						break;
    556 					case GL_GEOMETRY_SHADER:
    557 						m_context.getTestContext().getLog()
    558 							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
    559 						break;
    560 					case GL_FRAGMENT_SHADER:
    561 						m_context.getTestContext().getLog()
    562 							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
    563 						break;
    564 					case GL_COMPUTE_SHADER:
    565 						m_context.getTestContext().getLog()
    566 							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
    567 						break;
    568 					default:
    569 						m_context.getTestContext().getLog()
    570 							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
    571 						break;
    572 					}
    573 					GLint length;
    574 					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
    575 					if (length > 0)
    576 					{
    577 						std::vector<GLchar> source(length);
    578 						glGetShaderSource(shaders[i], length, NULL, &source[0]);
    579 						m_context.getTestContext().getLog()
    580 							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
    581 					}
    582 					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
    583 					if (length > 0)
    584 					{
    585 						std::vector<GLchar> log(length);
    586 						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
    587 						m_context.getTestContext().getLog()
    588 							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
    589 					}
    590 				}
    591 			}
    592 			GLint length;
    593 			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
    594 			if (length > 0)
    595 			{
    596 				std::vector<GLchar> log(length);
    597 				glGetProgramInfoLog(program, length, NULL, &log[0]);
    598 				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
    599 			}
    600 		}
    601 		return status == GL_TRUE ? true : false;
    602 	}
    603 
    604 public:
    605 	ImageSizeMachine()
    606 	{
    607 		glGenProgramPipelines(1, &m_pipeline);
    608 		memset(m_program, 0, sizeof(m_program));
    609 		glGenVertexArrays(1, &m_vertex_array);
    610 		glGenTextures(1, &m_texture);
    611 	}
    612 
    613 	~ImageSizeMachine()
    614 	{
    615 		glDeleteProgramPipelines(1, &m_pipeline);
    616 		for (int i = 0; i < 3; ++i)
    617 			glDeleteProgram(m_program[i]);
    618 		glDeleteVertexArrays(1, &m_vertex_array);
    619 		glDeleteTextures(1, &m_texture);
    620 	}
    621 
    622 	template <typename T>
    623 	long Run(int stage, bool ms_and_1d, ivec4 expected_result[7], bool subroutine = false)
    624 	{
    625 		if (stage == 0)
    626 		{ // VS
    627 			std::string		  vs	  = GenShader<T>(stage, ms_and_1d, subroutine);
    628 			const char* const glsl_vs = vs.c_str();
    629 			m_program[0]			  = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    630 			glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    631 		}
    632 		else if (stage == 1)
    633 		{ // TCS
    634 			const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
    635 										"void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}";
    636 			const char* const glsl_tes = "#version 430 core" NL "layout(quads, point_mode) in;" NL "void main() {}";
    637 			std::string		  tcs	  = GenShader<T>(stage, ms_and_1d, subroutine);
    638 			const char* const glsl_tcs = tcs.c_str();
    639 			m_program[0]			   = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    640 			m_program[1]			   = glCreateShaderProgramv(GL_TESS_CONTROL_SHADER, 1, &glsl_tcs);
    641 			m_program[2]			   = glCreateShaderProgramv(GL_TESS_EVALUATION_SHADER, 1, &glsl_tes);
    642 			glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    643 			glUseProgramStages(m_pipeline, GL_TESS_CONTROL_SHADER_BIT, m_program[1]);
    644 			glUseProgramStages(m_pipeline, GL_TESS_EVALUATION_SHADER_BIT, m_program[2]);
    645 		}
    646 		else if (stage == 2)
    647 		{ // TES
    648 			const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
    649 										"void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}";
    650 			std::string		  tes	  = GenShader<T>(stage, ms_and_1d, subroutine);
    651 			const char* const glsl_tes = tes.c_str();
    652 			m_program[0]			   = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    653 			m_program[1]			   = glCreateShaderProgramv(GL_TESS_EVALUATION_SHADER, 1, &glsl_tes);
    654 			glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    655 			glUseProgramStages(m_pipeline, GL_TESS_EVALUATION_SHADER_BIT, m_program[1]);
    656 		}
    657 		else if (stage == 3)
    658 		{ // GS
    659 			const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
    660 										"void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}";
    661 			std::string		  gs	  = GenShader<T>(stage, ms_and_1d, subroutine);
    662 			const char* const glsl_gs = gs.c_str();
    663 			m_program[0]			  = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    664 			m_program[1]			  = glCreateShaderProgramv(GL_GEOMETRY_SHADER, 1, &glsl_gs);
    665 			glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    666 			glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, m_program[1]);
    667 		}
    668 		else if (stage == 4)
    669 		{ // CS
    670 			std::string		  cs	  = GenShader<T>(stage, ms_and_1d, subroutine);
    671 			const char* const glsl_cs = cs.c_str();
    672 			m_program[0]			  = glCreateShaderProgramv(GL_COMPUTE_SHADER, 1, &glsl_cs);
    673 			glUseProgramStages(m_pipeline, GL_COMPUTE_SHADER_BIT, m_program[0]);
    674 		}
    675 		else if (stage == 5)
    676 		{ // FS
    677 			const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
    678 										"void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}";
    679 			std::string		  fs	  = GenShader<T>(stage, ms_and_1d, subroutine);
    680 			const char* const glsl_fs = fs.c_str();
    681 			m_program[0]			  = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    682 			m_program[1]			  = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
    683 			glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    684 			glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_program[1]);
    685 		}
    686 		for (int i = 0; i < 3; ++i)
    687 		{
    688 			if (!CheckProgram(m_program[i]))
    689 				return ERROR;
    690 		}
    691 
    692 		glBindTexture(GL_TEXTURE_2D, m_texture);
    693 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    694 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    695 		{
    696 			ivec4 data[7];
    697 			for (int i  = 0; i < 7; ++i)
    698 				data[i] = ivec4(100000);
    699 			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, 1, 7, 0, GL_RGBA_INTEGER, GL_INT, &data[0]);
    700 		}
    701 		glBindTexture(GL_TEXTURE_2D, 0);
    702 
    703 		glBindImageTexture(0, m_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32I);
    704 		glBindProgramPipeline(m_pipeline);
    705 		glBindVertexArray(m_vertex_array);
    706 		if (stage != 5)
    707 		{
    708 			glEnable(GL_RASTERIZER_DISCARD);
    709 		}
    710 		if (stage == 1 || stage == 2)
    711 		{ // TCS or TES
    712 			glPatchParameteri(GL_PATCH_VERTICES, 1);
    713 			glDrawArrays(GL_PATCHES, 0, 1);
    714 			glPatchParameteri(GL_PATCH_VERTICES, 3);
    715 		}
    716 		else if (stage == 4)
    717 		{ // CS
    718 			glDispatchCompute(1, 1, 1);
    719 		}
    720 		else
    721 		{
    722 			glDrawArrays(GL_POINTS, 0, 1);
    723 		}
    724 		glDisable(GL_RASTERIZER_DISCARD);
    725 
    726 		glBindTexture(GL_TEXTURE_2D, m_texture);
    727 		glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
    728 		{
    729 			ivec4 data[7];
    730 			glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA_INTEGER, GL_INT, &data[0]);
    731 			for (int i = 0; i < 7; ++i)
    732 			{
    733 				if (data[i] != expected_result[i])
    734 				{
    735 					m_context.getTestContext().getLog()
    736 						<< tcu::TestLog::Message << "Returned value is: (" << data[i][0] << " " << data[i][1] << " "
    737 						<< data[i][2] << " " << data[i][3] << "). Expected value is: (" << expected_result[i][0] << " "
    738 						<< expected_result[i][1] << " " << expected_result[i][2] << " " << expected_result[i][3]
    739 						<< "). Image unit is: " << (i + 1) << tcu::TestLog::EndMessage;
    740 					return ERROR;
    741 				}
    742 			}
    743 		}
    744 		return NO_ERROR;
    745 	}
    746 };
    747 //=============================================================================
    748 // 1.1.x.y BasicNonMS
    749 //-----------------------------------------------------------------------------
    750 
    751 template <typename T, int STAGE>
    752 class BasicNonMS : public ShaderImageSizeBase
    753 {
    754 	GLuint m_texture[7];
    755 	GLuint m_buffer;
    756 
    757 	virtual long Setup()
    758 	{
    759 		glGenTextures(7, m_texture);
    760 		glGenBuffers(1, &m_buffer);
    761 		return NO_ERROR;
    762 	}
    763 
    764 	virtual long Run()
    765 	{
    766 		if (!SupportedInStage(STAGE, 8))
    767 			return NOT_SUPPORTED;
    768 
    769 		const GLenum target[7] = { GL_TEXTURE_2D,		 GL_TEXTURE_3D,
    770 								   GL_TEXTURE_CUBE_MAP,  GL_TEXTURE_CUBE_MAP_ARRAY,
    771 								   GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY,
    772 								   GL_TEXTURE_BUFFER };
    773 		for (int i = 0; i < 7; ++i)
    774 		{
    775 			glBindTexture(target[i], m_texture[i]);
    776 			if (target[i] != GL_TEXTURE_BUFFER)
    777 			{
    778 				glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    779 				glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    780 			}
    781 
    782 			if (i == 0)
    783 			{
    784 				glTexStorage2D(target[i], 10, TexInternalFormat<T>(), 512, 128);
    785 				glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    786 			}
    787 			else if (i == 1)
    788 			{
    789 				glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 8, 8, 4);
    790 				glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    791 			}
    792 			else if (i == 2)
    793 			{
    794 				glTexStorage2D(target[i], 4, TexInternalFormat<T>(), 16, 16);
    795 				glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
    796 			}
    797 			else if (i == 3)
    798 			{
    799 				glTexStorage3D(target[i], 2, TexInternalFormat<T>(), 4, 4, 12);
    800 				glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    801 			}
    802 			else if (i == 4)
    803 			{
    804 				glTexStorage2D(target[i], 1, TexInternalFormat<T>(), 16, 8);
    805 				glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    806 			}
    807 			else if (i == 5)
    808 			{
    809 				glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 127, 39, 12);
    810 				glBindImageTexture(6, m_texture[i], 2, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    811 			}
    812 			else if (i == 6)
    813 			{
    814 				std::vector<GLubyte> data(256);
    815 				glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
    816 				glBufferData(GL_TEXTURE_BUFFER, 256, &data[0], GL_STATIC_DRAW);
    817 				glTexBuffer(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer);
    818 				glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    819 			}
    820 		}
    821 		ImageSizeMachine machine;
    822 		ivec4			 res[7] = { ivec4(256, 64, 0, 0), ivec4(8, 8, 4, 0),   ivec4(16, 16, 0, 0), ivec4(2, 2, 2, 0),
    823 						 ivec4(16, 8, 0, 0),   ivec4(31, 9, 12, 0), ivec4(16, 0, 0, 0) };
    824 		return machine.Run<T>(STAGE, false, res);
    825 	}
    826 
    827 	virtual long Cleanup()
    828 	{
    829 		glDeleteTextures(7, m_texture);
    830 		glDeleteBuffers(1, &m_buffer);
    831 		return NO_ERROR;
    832 	}
    833 };
    834 //=============================================================================
    835 // 1.2.x.y BasicMS
    836 //-----------------------------------------------------------------------------
    837 
    838 template <typename T, int STAGE>
    839 class BasicMS : public ShaderImageSizeBase
    840 {
    841 	GLuint m_texture[4];
    842 
    843 	virtual long Setup()
    844 	{
    845 		glGenTextures(4, m_texture);
    846 		return NO_ERROR;
    847 	}
    848 
    849 	virtual long Run()
    850 	{
    851 		if (!SupportedInStage(STAGE, 5))
    852 			return NOT_SUPPORTED;
    853 		if (!SupportedSamples(4))
    854 			return NOT_SUPPORTED;
    855 
    856 		const GLenum target[4] = { GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE,
    857 								   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
    858 		for (int i = 0; i < 4; ++i)
    859 		{
    860 			glBindTexture(target[i], m_texture[i]);
    861 			if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY)
    862 			{
    863 				glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    864 				glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    865 			}
    866 
    867 			if (i == 0)
    868 			{
    869 				glTexStorage1D(target[i], 10, TexInternalFormat<T>(), 512);
    870 				glBindImageTexture(1, m_texture[i], 6, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    871 			}
    872 			else if (i == 1)
    873 			{
    874 				glTexStorage2D(target[i], 3, TexInternalFormat<T>(), 15, 7);
    875 				glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    876 			}
    877 			else if (i == 2)
    878 			{
    879 				glTexImage2DMultisample(target[i], 4, TexInternalFormat<T>(), 17, 19, GL_FALSE);
    880 				glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
    881 			}
    882 			else if (i == 3)
    883 			{
    884 				glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE);
    885 				glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
    886 			}
    887 		}
    888 		ImageSizeMachine machine;
    889 		ivec4 res[7] = { ivec4(8, 0, 0, 0), ivec4(7, 7, 0, 0), ivec4(17, 19, 0, 0), ivec4(64, 32, 5, 0), ivec4(0),
    890 						 ivec4(0),			ivec4(0) };
    891 		return machine.Run<T>(STAGE, true, res);
    892 	}
    893 
    894 	virtual long Cleanup()
    895 	{
    896 		glDeleteTextures(4, m_texture);
    897 		return NO_ERROR;
    898 	}
    899 };
    900 //=============================================================================
    901 // 2.1 AdvancedChangeSize
    902 //-----------------------------------------------------------------------------
    903 class AdvancedChangeSize : public ShaderImageSizeBase
    904 {
    905 	GLuint m_pipeline;
    906 	GLuint m_program[2];
    907 	GLuint m_vertex_array;
    908 	GLuint m_texture[2];
    909 
    910 	virtual long Setup()
    911 	{
    912 		glGenProgramPipelines(1, &m_pipeline);
    913 		memset(m_program, 0, sizeof(m_program));
    914 		glGenVertexArrays(1, &m_vertex_array);
    915 		glGenTextures(2, m_texture);
    916 		return NO_ERROR;
    917 	}
    918 
    919 	virtual long Run()
    920 	{
    921 		const char* const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
    922 									"const vec2 g_position[3] = { vec2(-1, -1), vec2(3, -1), vec2(-1, 3) };" NL
    923 									"void main() { gl_Position = vec4(g_position[gl_VertexID], 0, 1); }";
    924 		const char* const glsl_fs =
    925 			"#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL
    926 			"layout(binding = 0, rgba8) uniform image2D g_image[2];" NL "uniform ivec2 g_expected_size[2];" NL
    927 			"uniform int g_0 = 0, g_1 = 1;" NL "void main() {" NL "  vec4 c = vec4(0, 1, 0, 1);" NL
    928 			"  if (imageSize(g_image[g_0]).xy != g_expected_size[g_0]) c = vec4(1, 0, 0, 1);" NL
    929 			"  if (imageSize(g_image[g_1]).yx != g_expected_size[g_1]) c = vec4(1, 0, 0, 1);" NL "  g_color = c;" NL
    930 			"}";
    931 		m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
    932 		m_program[1] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
    933 		for (int i = 0; i < 2; ++i)
    934 			if (!CheckProgram(m_program[i]))
    935 				return ERROR;
    936 
    937 		glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
    938 		glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_program[1]);
    939 
    940 		glBindVertexArray(m_vertex_array);
    941 		glBindProgramPipeline(m_pipeline);
    942 
    943 		int size[2] = { 32, 128 };
    944 		for (int i = 0; i < 2; ++i)
    945 		{
    946 			glBindTexture(GL_TEXTURE_2D, m_texture[i]);
    947 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    948 			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    949 			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[i], size[i], 0, GL_RGBA, GL_FLOAT, NULL);
    950 			glBindImageTexture(i, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
    951 		}
    952 
    953 		for (int i = 0; i < 3; ++i)
    954 		{
    955 			glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[0]"), size[0],
    956 							   size[0]);
    957 			glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[1]"), size[1],
    958 							   size[1]);
    959 			glClear(GL_COLOR_BUFFER_BIT);
    960 			glDrawArrays(GL_TRIANGLES, 0, 3);
    961 
    962 			{
    963 				bool			  status = true;
    964 				std::vector<vec3> fb(getWindowWidth() * getWindowHeight());
    965 				glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
    966 				if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
    967 					status = false;
    968 				if (!status)
    969 					return ERROR;
    970 			}
    971 
    972 			size[0] /= 2;
    973 			size[1] /= 2;
    974 
    975 			glBindTexture(GL_TEXTURE_2D, m_texture[0]);
    976 			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[0], size[0], 0, GL_RGBA, GL_FLOAT, NULL);
    977 			glBindTexture(GL_TEXTURE_2D, m_texture[1]);
    978 			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[1], size[1], 0, GL_RGBA, GL_FLOAT, NULL);
    979 		}
    980 		return NO_ERROR;
    981 	}
    982 
    983 	virtual long Cleanup()
    984 	{
    985 		glDeleteProgramPipelines(1, &m_pipeline);
    986 		for (int i = 0; i < 2; ++i)
    987 			glDeleteProgram(m_program[i]);
    988 		glDeleteVertexArrays(1, &m_vertex_array);
    989 		glDeleteTextures(2, m_texture);
    990 		return NO_ERROR;
    991 	}
    992 };
    993 //=============================================================================
    994 // 2.2.x.y AdvancedNonMS
    995 //-----------------------------------------------------------------------------
    996 
    997 template <typename T, int STAGE>
    998 class AdvancedNonMS : public ShaderImageSizeBase
    999 {
   1000 	GLuint m_texture[7];
   1001 	GLuint m_buffer;
   1002 
   1003 	virtual long Setup()
   1004 	{
   1005 		glGenTextures(7, m_texture);
   1006 		glGenBuffers(1, &m_buffer);
   1007 		return NO_ERROR;
   1008 	}
   1009 
   1010 	virtual long Run()
   1011 	{
   1012 		if (!SupportedInStage(STAGE, 8))
   1013 			return NOT_SUPPORTED;
   1014 
   1015 		const GLenum target[7] = { GL_TEXTURE_2D_ARRAY,		  GL_TEXTURE_3D,		GL_TEXTURE_CUBE_MAP_ARRAY,
   1016 								   GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY,
   1017 								   GL_TEXTURE_BUFFER };
   1018 		for (int i = 0; i < 7; ++i)
   1019 		{
   1020 			glBindTexture(target[i], m_texture[i]);
   1021 			if (target[i] != GL_TEXTURE_BUFFER)
   1022 			{
   1023 				glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1024 				glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1025 			}
   1026 
   1027 			if (i == 0)
   1028 			{
   1029 				glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 7, 0, TexFormat<T>(), TexType<T>(), NULL);
   1030 				glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 7, 0, TexFormat<T>(), TexType<T>(), NULL);
   1031 				glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 3, GL_READ_ONLY, TexInternalFormat<T>());
   1032 			}
   1033 			else if (i == 1)
   1034 			{
   1035 				glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 2, 0, TexFormat<T>(), TexType<T>(), NULL);
   1036 				glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 1, 0, TexFormat<T>(), TexType<T>(), NULL);
   1037 				glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 1, 0, TexFormat<T>(), TexType<T>(), NULL);
   1038 				glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1039 			}
   1040 			else if (i == 2)
   1041 			{
   1042 				glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 12, 0, TexFormat<T>(), TexType<T>(), NULL);
   1043 				glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 12, 0, TexFormat<T>(), TexType<T>(), NULL);
   1044 				glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>());
   1045 			}
   1046 			else if (i == 3)
   1047 			{
   1048 				glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
   1049 				glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
   1050 				glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
   1051 				glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1052 			}
   1053 			else if (i == 4)
   1054 			{
   1055 				glTexImage2D(target[i], 0, TexInternalFormat<T>(), 123, 11, 0, TexFormat<T>(), TexType<T>(), NULL);
   1056 				glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
   1057 			}
   1058 			else if (i == 5)
   1059 			{
   1060 				glTexImage3D(target[i], 0, TexInternalFormat<T>(), 13, 7, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
   1061 				glTexImage3D(target[i], 1, TexInternalFormat<T>(), 6, 3, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
   1062 				glTexImage3D(target[i], 2, TexInternalFormat<T>(), 3, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
   1063 				glTexImage3D(target[i], 3, TexInternalFormat<T>(), 1, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
   1064 				glBindImageTexture(6, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1065 			}
   1066 			else if (i == 6)
   1067 			{
   1068 				glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
   1069 				glBufferData(GL_TEXTURE_BUFFER, 1024, NULL, GL_STATIC_DRAW);
   1070 				glTexBufferRange(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer, 256, 512);
   1071 				glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, TexInternalFormat<T>());
   1072 			}
   1073 		}
   1074 		ImageSizeMachine machine;
   1075 		ivec4			 res[7] = { ivec4(1, 1, 0, 0),	ivec4(2, 2, 1, 0), ivec4(2, 2, 0, 0), ivec4(2, 2, 3, 0),
   1076 						 ivec4(123, 11, 0, 0), ivec4(6, 3, 4, 0), ivec4(32, 0, 0, 0) };
   1077 		return machine.Run<T>(STAGE, false, res, true);
   1078 	}
   1079 
   1080 	virtual long Cleanup()
   1081 	{
   1082 		glDeleteTextures(7, m_texture);
   1083 		glDeleteBuffers(1, &m_buffer);
   1084 		return NO_ERROR;
   1085 	}
   1086 };
   1087 //=============================================================================
   1088 // 2.3.x.y AdvancedMS
   1089 //-----------------------------------------------------------------------------
   1090 template <typename T, int STAGE>
   1091 class AdvancedMS : public ShaderImageSizeBase
   1092 {
   1093 	GLuint m_texture[4];
   1094 
   1095 	virtual long Setup()
   1096 	{
   1097 		glGenTextures(4, m_texture);
   1098 		return NO_ERROR;
   1099 	}
   1100 
   1101 	virtual long Run()
   1102 	{
   1103 		if (!SupportedInStage(STAGE, 5))
   1104 			return NOT_SUPPORTED;
   1105 		if (!SupportedSamples(4))
   1106 			return NOT_SUPPORTED;
   1107 
   1108 		const GLenum target[4] = { GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
   1109 								   GL_TEXTURE_2D_MULTISAMPLE_ARRAY };
   1110 		for (int i = 0; i < 4; ++i)
   1111 		{
   1112 			glBindTexture(target[i], m_texture[i]);
   1113 			if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY)
   1114 			{
   1115 				glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1116 				glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1117 			}
   1118 
   1119 			if (i == 0)
   1120 			{
   1121 				glTexImage1D(target[i], 0, TexInternalFormat<T>(), 7, 0, TexFormat<T>(), TexType<T>(), NULL);
   1122 				glTexImage1D(target[i], 1, TexInternalFormat<T>(), 3, 0, TexFormat<T>(), TexType<T>(), NULL);
   1123 				glTexImage1D(target[i], 2, TexInternalFormat<T>(), 1, 0, TexFormat<T>(), TexType<T>(), NULL);
   1124 				glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1125 			}
   1126 			else if (i == 1)
   1127 			{
   1128 				glTexImage2D(target[i], 0, TexInternalFormat<T>(), 7, 15, 0, TexFormat<T>(), TexType<T>(), NULL);
   1129 				glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1130 			}
   1131 			else if (i == 2)
   1132 			{
   1133 				glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 7, 9, 3, GL_FALSE);
   1134 				glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>());
   1135 			}
   1136 			else if (i == 3)
   1137 			{
   1138 				glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE);
   1139 				glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
   1140 			}
   1141 		}
   1142 		ImageSizeMachine machine;
   1143 		ivec4			 res[7] = { ivec4(3, 0, 0, 0), ivec4(7, 15, 0, 0), ivec4(7, 9, 0, 0), ivec4(64, 32, 5, 0),
   1144 						 ivec4(0),			ivec4(0),			ivec4(0) };
   1145 		return machine.Run<T>(STAGE, true, res, true);
   1146 	}
   1147 
   1148 	virtual long Cleanup()
   1149 	{
   1150 		glDeleteTextures(4, m_texture);
   1151 		return NO_ERROR;
   1152 	}
   1153 };
   1154 //=============================================================================
   1155 // 4.1 NegativeCompileTime
   1156 //-----------------------------------------------------------------------------
   1157 class NegativeCompileTime : public ShaderImageSizeBase
   1158 {
   1159 	virtual long Run()
   1160 	{
   1161 		// '#extension GL_ARB_shader_image_size : require' is missing
   1162 		if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 g_color;" NL
   1163 					 "layout(binding = 0, rg16f) uniform image2D g_image;" NL "uniform ivec2 g_expected_size;" NL
   1164 					 "void main() {" NL "  if (imageSize(g_image) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL
   1165 					 "  else g_color = vec4(1, 0, 0, 1);" NL "}"))
   1166 			return ERROR;
   1167 		// imageSize(sampler)
   1168 		if (!Compile("#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL
   1169 					 "layout(binding = 0) uniform sampler2D g_sampler;" NL "uniform ivec2 g_expected_size;" NL
   1170 					 "void main() {" NL "  if (imageSize(g_sampler) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL
   1171 					 "  else g_color = vec4(1, 0, 0, 1);" NL "}"))
   1172 			return ERROR;
   1173 		return NO_ERROR;
   1174 	}
   1175 
   1176 	bool Compile(const std::string& source)
   1177 	{
   1178 		const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
   1179 
   1180 		const char* const src = source.c_str();
   1181 		glShaderSource(sh, 1, &src, NULL);
   1182 		glCompileShader(sh);
   1183 
   1184 		GLchar log[1024];
   1185 		glGetShaderInfoLog(sh, sizeof(log), NULL, log);
   1186 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
   1187 											<< log << tcu::TestLog::EndMessage;
   1188 
   1189 		GLint status;
   1190 		glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
   1191 		glDeleteShader(sh);
   1192 
   1193 		if (status == GL_TRUE)
   1194 		{
   1195 			m_context.getTestContext().getLog()
   1196 				<< tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage;
   1197 			return false;
   1198 		}
   1199 		return true;
   1200 	}
   1201 };
   1202 
   1203 } // anonymous namespace
   1204 
   1205 ShaderImageSizeTests::ShaderImageSizeTests(deqp::Context& context) : TestCaseGroup(context, "shader_image_size", "")
   1206 {
   1207 }
   1208 
   1209 ShaderImageSizeTests::~ShaderImageSizeTests(void)
   1210 {
   1211 }
   1212 
   1213 void ShaderImageSizeTests::init()
   1214 {
   1215 	using namespace deqp;
   1216 	addChild(new TestSubcase(m_context, "basic-nonMS-vs-float", TestSubcase::Create<BasicNonMS<vec4, 0> >));
   1217 	addChild(new TestSubcase(m_context, "basic-nonMS-vs-int", TestSubcase::Create<BasicNonMS<ivec4, 0> >));
   1218 	addChild(new TestSubcase(m_context, "basic-nonMS-vs-uint", TestSubcase::Create<BasicNonMS<uvec4, 0> >));
   1219 	addChild(new TestSubcase(m_context, "basic-nonMS-tcs-float", TestSubcase::Create<BasicNonMS<vec4, 1> >));
   1220 	addChild(new TestSubcase(m_context, "basic-nonMS-tcs-int", TestSubcase::Create<BasicNonMS<ivec4, 1> >));
   1221 	addChild(new TestSubcase(m_context, "basic-nonMS-tcs-uint", TestSubcase::Create<BasicNonMS<uvec4, 1> >));
   1222 	addChild(new TestSubcase(m_context, "basic-nonMS-tes-float", TestSubcase::Create<BasicNonMS<vec4, 2> >));
   1223 	addChild(new TestSubcase(m_context, "basic-nonMS-tes-int", TestSubcase::Create<BasicNonMS<ivec4, 2> >));
   1224 	addChild(new TestSubcase(m_context, "basic-nonMS-tes-uint", TestSubcase::Create<BasicNonMS<uvec4, 2> >));
   1225 	addChild(new TestSubcase(m_context, "basic-nonMS-gs-float", TestSubcase::Create<BasicNonMS<vec4, 3> >));
   1226 	addChild(new TestSubcase(m_context, "basic-nonMS-gs-int", TestSubcase::Create<BasicNonMS<ivec4, 3> >));
   1227 	addChild(new TestSubcase(m_context, "basic-nonMS-gs-uint", TestSubcase::Create<BasicNonMS<uvec4, 3> >));
   1228 	addChild(new TestSubcase(m_context, "basic-nonMS-fs-float", TestSubcase::Create<BasicNonMS<vec4, 5> >));
   1229 	addChild(new TestSubcase(m_context, "basic-nonMS-fs-int", TestSubcase::Create<BasicNonMS<ivec4, 5> >));
   1230 	addChild(new TestSubcase(m_context, "basic-nonMS-fs-uint", TestSubcase::Create<BasicNonMS<uvec4, 5> >));
   1231 	addChild(new TestSubcase(m_context, "basic-nonMS-cs-float", TestSubcase::Create<BasicNonMS<vec4, 4> >));
   1232 	addChild(new TestSubcase(m_context, "basic-nonMS-cs-int", TestSubcase::Create<BasicNonMS<ivec4, 4> >));
   1233 	addChild(new TestSubcase(m_context, "basic-nonMS-cs-uint", TestSubcase::Create<BasicNonMS<uvec4, 4> >));
   1234 	addChild(new TestSubcase(m_context, "basic-ms-vs-float", TestSubcase::Create<BasicMS<vec4, 0> >));
   1235 	addChild(new TestSubcase(m_context, "basic-ms-vs-int", TestSubcase::Create<BasicMS<ivec4, 0> >));
   1236 	addChild(new TestSubcase(m_context, "basic-ms-vs-uint", TestSubcase::Create<BasicMS<uvec4, 0> >));
   1237 	addChild(new TestSubcase(m_context, "basic-ms-tcs-float", TestSubcase::Create<BasicMS<vec4, 1> >));
   1238 	addChild(new TestSubcase(m_context, "basic-ms-tcs-int", TestSubcase::Create<BasicMS<ivec4, 1> >));
   1239 	addChild(new TestSubcase(m_context, "basic-ms-tcs-uint", TestSubcase::Create<BasicMS<uvec4, 1> >));
   1240 	addChild(new TestSubcase(m_context, "basic-ms-tes-float", TestSubcase::Create<BasicMS<vec4, 2> >));
   1241 	addChild(new TestSubcase(m_context, "basic-ms-tes-int", TestSubcase::Create<BasicMS<ivec4, 2> >));
   1242 	addChild(new TestSubcase(m_context, "basic-ms-tes-uint", TestSubcase::Create<BasicMS<uvec4, 2> >));
   1243 	addChild(new TestSubcase(m_context, "basic-ms-gs-float", TestSubcase::Create<BasicMS<vec4, 3> >));
   1244 	addChild(new TestSubcase(m_context, "basic-ms-gs-int", TestSubcase::Create<BasicMS<ivec4, 3> >));
   1245 	addChild(new TestSubcase(m_context, "basic-ms-gs-uint", TestSubcase::Create<BasicMS<uvec4, 3> >));
   1246 	addChild(new TestSubcase(m_context, "basic-ms-fs-float", TestSubcase::Create<BasicMS<vec4, 5> >));
   1247 	addChild(new TestSubcase(m_context, "basic-ms-fs-int", TestSubcase::Create<BasicMS<ivec4, 5> >));
   1248 	addChild(new TestSubcase(m_context, "basic-ms-fs-uint", TestSubcase::Create<BasicMS<uvec4, 5> >));
   1249 	addChild(new TestSubcase(m_context, "basic-ms-cs-float", TestSubcase::Create<BasicMS<vec4, 4> >));
   1250 	addChild(new TestSubcase(m_context, "basic-ms-cs-int", TestSubcase::Create<BasicMS<ivec4, 4> >));
   1251 	addChild(new TestSubcase(m_context, "basic-ms-cs-uint", TestSubcase::Create<BasicMS<uvec4, 4> >));
   1252 	addChild(new TestSubcase(m_context, "advanced-changeSize", TestSubcase::Create<AdvancedChangeSize>));
   1253 	addChild(new TestSubcase(m_context, "advanced-nonMS-vs-float", TestSubcase::Create<AdvancedNonMS<vec4, 0> >));
   1254 	addChild(new TestSubcase(m_context, "advanced-nonMS-vs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 0> >));
   1255 	addChild(new TestSubcase(m_context, "advanced-nonMS-vs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 0> >));
   1256 	addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-float", TestSubcase::Create<AdvancedNonMS<vec4, 1> >));
   1257 	addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 1> >));
   1258 	addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 1> >));
   1259 	addChild(new TestSubcase(m_context, "advanced-nonMS-tes-float", TestSubcase::Create<AdvancedNonMS<vec4, 2> >));
   1260 	addChild(new TestSubcase(m_context, "advanced-nonMS-tes-int", TestSubcase::Create<AdvancedNonMS<ivec4, 2> >));
   1261 	addChild(new TestSubcase(m_context, "advanced-nonMS-tes-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 2> >));
   1262 	addChild(new TestSubcase(m_context, "advanced-nonMS-gs-float", TestSubcase::Create<AdvancedNonMS<vec4, 3> >));
   1263 	addChild(new TestSubcase(m_context, "advanced-nonMS-gs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 3> >));
   1264 	addChild(new TestSubcase(m_context, "advanced-nonMS-gs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 3> >));
   1265 	addChild(new TestSubcase(m_context, "advanced-nonMS-fs-float", TestSubcase::Create<AdvancedNonMS<vec4, 5> >));
   1266 	addChild(new TestSubcase(m_context, "advanced-nonMS-fs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 5> >));
   1267 	addChild(new TestSubcase(m_context, "advanced-nonMS-fs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 5> >));
   1268 	addChild(new TestSubcase(m_context, "advanced-nonMS-cs-float", TestSubcase::Create<AdvancedNonMS<vec4, 4> >));
   1269 	addChild(new TestSubcase(m_context, "advanced-nonMS-cs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 4> >));
   1270 	addChild(new TestSubcase(m_context, "advanced-nonMS-cs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 4> >));
   1271 	addChild(new TestSubcase(m_context, "advanced-ms-vs-float", TestSubcase::Create<AdvancedMS<vec4, 0> >));
   1272 	addChild(new TestSubcase(m_context, "advanced-ms-vs-int", TestSubcase::Create<AdvancedMS<ivec4, 0> >));
   1273 	addChild(new TestSubcase(m_context, "advanced-ms-vs-uint", TestSubcase::Create<AdvancedMS<uvec4, 0> >));
   1274 	addChild(new TestSubcase(m_context, "advanced-ms-tcs-float", TestSubcase::Create<AdvancedMS<vec4, 1> >));
   1275 	addChild(new TestSubcase(m_context, "advanced-ms-tcs-int", TestSubcase::Create<AdvancedMS<ivec4, 1> >));
   1276 	addChild(new TestSubcase(m_context, "advanced-ms-tcs-uint", TestSubcase::Create<AdvancedMS<uvec4, 1> >));
   1277 	addChild(new TestSubcase(m_context, "advanced-ms-tes-float", TestSubcase::Create<AdvancedMS<vec4, 2> >));
   1278 	addChild(new TestSubcase(m_context, "advanced-ms-tes-int", TestSubcase::Create<AdvancedMS<ivec4, 2> >));
   1279 	addChild(new TestSubcase(m_context, "advanced-ms-tes-uint", TestSubcase::Create<AdvancedMS<uvec4, 2> >));
   1280 	addChild(new TestSubcase(m_context, "advanced-ms-gs-float", TestSubcase::Create<AdvancedMS<vec4, 3> >));
   1281 	addChild(new TestSubcase(m_context, "advanced-ms-gs-int", TestSubcase::Create<AdvancedMS<ivec4, 3> >));
   1282 	addChild(new TestSubcase(m_context, "advanced-ms-gs-uint", TestSubcase::Create<AdvancedMS<uvec4, 3> >));
   1283 	addChild(new TestSubcase(m_context, "advanced-ms-fs-float", TestSubcase::Create<AdvancedMS<vec4, 5> >));
   1284 	addChild(new TestSubcase(m_context, "advanced-ms-fs-int", TestSubcase::Create<AdvancedMS<ivec4, 5> >));
   1285 	addChild(new TestSubcase(m_context, "advanced-ms-fs-uint", TestSubcase::Create<AdvancedMS<uvec4, 5> >));
   1286 	addChild(new TestSubcase(m_context, "advanced-ms-cs-float", TestSubcase::Create<AdvancedMS<vec4, 4> >));
   1287 	addChild(new TestSubcase(m_context, "advanced-ms-cs-int", TestSubcase::Create<AdvancedMS<ivec4, 4> >));
   1288 	addChild(new TestSubcase(m_context, "advanced-ms-cs-uint", TestSubcase::Create<AdvancedMS<uvec4, 4> >));
   1289 	addChild(new TestSubcase(m_context, "negative-compileTime", TestSubcase::Create<NegativeCompileTime>));
   1290 }
   1291 
   1292 } // namespace gl4cts
   1293