• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
Title()46 	virtual std::string Title()
47 	{
48 		return "";
49 	}
50 
Purpose()51 	virtual std::string Purpose()
52 	{
53 		return "";
54 	}
55 
Method()56 	virtual std::string Method()
57 	{
58 		return "";
59 	}
60 
PassCriteria()61 	virtual std::string PassCriteria()
62 	{
63 		return "";
64 	}
65 
66 public:
SupportedInVS(int requiredVS)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 
SupportedInTCS(int requiredTCS)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 
SupportedInTES(int requiredTES)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 
SupportedInGS(int requiredGS)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 
SupportedInStage(int stage,int required)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 
SupportedSamples(int required)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 
getWindowWidth()163 	int getWindowWidth()
164 	{
165 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
166 		return renderTarget.getWidth();
167 	}
168 
getWindowHeight()169 	int getWindowHeight()
170 	{
171 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
172 		return renderTarget.getHeight();
173 	}
174 
ColorEqual(const vec4 & c0,const vec4 & c1,const vec4 & epsilon)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>
ToString(T v)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 
ValidateReadBuffer(int x,int y,int w,int h,const vec4 & expected)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 
CheckProgram(GLuint program)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 <>
ImageTypePrefix()319 std::string ImageTypePrefix<vec4>()
320 {
321 	return "";
322 }
323 
324 template <>
ImageTypePrefix()325 std::string ImageTypePrefix<ivec4>()
326 {
327 	return "i";
328 }
329 
330 template <>
ImageTypePrefix()331 std::string ImageTypePrefix<uvec4>()
332 {
333 	return "u";
334 }
335 
336 template <typename T>
337 std::string ImageFormatPostfix();
338 
339 template <>
ImageFormatPostfix()340 std::string ImageFormatPostfix<vec4>()
341 {
342 	return "f";
343 }
344 
345 template <>
ImageFormatPostfix()346 std::string ImageFormatPostfix<ivec4>()
347 {
348 	return "i";
349 }
350 
351 template <>
ImageFormatPostfix()352 std::string ImageFormatPostfix<uvec4>()
353 {
354 	return "ui";
355 }
356 
357 template <typename T>
358 GLenum TexInternalFormat();
359 
360 template <>
TexInternalFormat()361 GLenum TexInternalFormat<vec4>()
362 {
363 	return GL_RGBA32F;
364 }
365 
366 template <>
TexInternalFormat()367 GLenum TexInternalFormat<ivec4>()
368 {
369 	return GL_RGBA32I;
370 }
371 
372 template <>
TexInternalFormat()373 GLenum TexInternalFormat<uvec4>()
374 {
375 	return GL_RGBA32UI;
376 }
377 
378 template <typename T>
379 GLenum TexType();
380 
381 template <>
TexType()382 GLenum TexType<vec4>()
383 {
384 	return GL_FLOAT;
385 }
386 
387 template <>
TexType()388 GLenum TexType<ivec4>()
389 {
390 	return GL_INT;
391 }
392 
393 template <>
TexType()394 GLenum TexType<uvec4>()
395 {
396 	return GL_UNSIGNED_INT;
397 }
398 
399 template <typename T>
400 GLenum TexFormat();
401 
402 template <>
TexFormat()403 GLenum TexFormat<vec4>()
404 {
405 	return GL_RGBA;
406 }
407 
408 template <>
TexFormat()409 GLenum TexFormat<ivec4>()
410 {
411 	return GL_RGBA_INTEGER;
412 }
413 
414 template <>
TexFormat()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>
GenShader(int stage,bool ms_and_1d,bool subroutine)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 			   << "image2D 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 
CheckProgram(GLuint program)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:
ImageSizeMachine()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 
~ImageSizeMachine()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>
Run(int stage,bool ms_and_1d,ivec4 expected_result[7],bool subroutine=false)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 
Setup()757 	virtual long Setup()
758 	{
759 		glGenTextures(7, m_texture);
760 		glGenBuffers(1, &m_buffer);
761 		return NO_ERROR;
762 	}
763 
Run()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 
Cleanup()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 
Setup()843 	virtual long Setup()
844 	{
845 		glGenTextures(4, m_texture);
846 		return NO_ERROR;
847 	}
848 
Run()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 
Cleanup()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 
Setup()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 
Run()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 
Cleanup()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 
Setup()1003 	virtual long Setup()
1004 	{
1005 		glGenTextures(7, m_texture);
1006 		glGenBuffers(1, &m_buffer);
1007 		return NO_ERROR;
1008 	}
1009 
Run()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 
Cleanup()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 
Setup()1095 	virtual long Setup()
1096 	{
1097 		glGenTextures(4, m_texture);
1098 		return NO_ERROR;
1099 	}
1100 
Run()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 
Cleanup()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 {
Run()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 
Compile(const std::string & source)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 
ShaderImageSizeTests(deqp::Context & context)1205 ShaderImageSizeTests::ShaderImageSizeTests(deqp::Context& context) : TestCaseGroup(context, "shader_image_size", "")
1206 {
1207 }
1208 
~ShaderImageSizeTests(void)1209 ShaderImageSizeTests::~ShaderImageSizeTests(void)
1210 {
1211 }
1212 
init()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