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] = {
770 GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY,
771 GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BUFFER};
772 for (int i = 0; i < 7; ++i)
773 {
774 glBindTexture(target[i], m_texture[i]);
775 if (target[i] != GL_TEXTURE_BUFFER)
776 {
777 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
778 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
779 }
780
781 if (i == 0)
782 {
783 glTexStorage2D(target[i], 10, TexInternalFormat<T>(), 512, 128);
784 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
785 }
786 else if (i == 1)
787 {
788 glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 8, 8, 4);
789 glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
790 }
791 else if (i == 2)
792 {
793 glTexStorage2D(target[i], 4, TexInternalFormat<T>(), 16, 16);
794 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
795 }
796 else if (i == 3)
797 {
798 glTexStorage3D(target[i], 2, TexInternalFormat<T>(), 4, 4, 12);
799 glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
800 }
801 else if (i == 4)
802 {
803 glTexStorage2D(target[i], 1, TexInternalFormat<T>(), 16, 8);
804 glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
805 }
806 else if (i == 5)
807 {
808 glTexStorage3D(target[i], 3, TexInternalFormat<T>(), 127, 39, 12);
809 glBindImageTexture(6, m_texture[i], 2, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
810 }
811 else if (i == 6)
812 {
813 std::vector<GLubyte> data(256);
814 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
815 glBufferData(GL_TEXTURE_BUFFER, 256, &data[0], GL_STATIC_DRAW);
816 glTexBuffer(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer);
817 glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
818 }
819 }
820 ImageSizeMachine machine;
821 ivec4 res[7] = {ivec4(256, 64, 0, 0), ivec4(8, 8, 4, 0), ivec4(16, 16, 0, 0), ivec4(2, 2, 2, 0),
822 ivec4(16, 8, 0, 0), ivec4(31, 9, 12, 0), ivec4(16, 0, 0, 0)};
823 return machine.Run<T>(STAGE, false, res);
824 }
825
Cleanup()826 virtual long Cleanup()
827 {
828 glDeleteTextures(7, m_texture);
829 glDeleteBuffers(1, &m_buffer);
830 return NO_ERROR;
831 }
832 };
833 //=============================================================================
834 // 1.2.x.y BasicMS
835 //-----------------------------------------------------------------------------
836
837 template <typename T, int STAGE>
838 class BasicMS : public ShaderImageSizeBase
839 {
840 GLuint m_texture[4];
841
Setup()842 virtual long Setup()
843 {
844 glGenTextures(4, m_texture);
845 return NO_ERROR;
846 }
847
Run()848 virtual long Run()
849 {
850 if (!SupportedInStage(STAGE, 5))
851 return NOT_SUPPORTED;
852 if (!SupportedSamples(4))
853 return NOT_SUPPORTED;
854
855 const GLenum target[4] = {GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE,
856 GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
857 for (int i = 0; i < 4; ++i)
858 {
859 glBindTexture(target[i], m_texture[i]);
860 if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY)
861 {
862 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
863 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
864 }
865
866 if (i == 0)
867 {
868 glTexStorage1D(target[i], 10, TexInternalFormat<T>(), 512);
869 glBindImageTexture(1, m_texture[i], 6, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
870 }
871 else if (i == 1)
872 {
873 glTexStorage2D(target[i], 3, TexInternalFormat<T>(), 15, 7);
874 glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
875 }
876 else if (i == 2)
877 {
878 glTexImage2DMultisample(target[i], 4, TexInternalFormat<T>(), 17, 19, GL_FALSE);
879 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
880 }
881 else if (i == 3)
882 {
883 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE);
884 glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
885 }
886 }
887 ImageSizeMachine machine;
888 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),
889 ivec4(0), ivec4(0)};
890 return machine.Run<T>(STAGE, true, res);
891 }
892
Cleanup()893 virtual long Cleanup()
894 {
895 glDeleteTextures(4, m_texture);
896 return NO_ERROR;
897 }
898 };
899 //=============================================================================
900 // 2.1 AdvancedChangeSize
901 //-----------------------------------------------------------------------------
902 class AdvancedChangeSize : public ShaderImageSizeBase
903 {
904 GLuint m_pipeline;
905 GLuint m_program[2];
906 GLuint m_vertex_array;
907 GLuint m_texture[2];
908
Setup()909 virtual long Setup()
910 {
911 glGenProgramPipelines(1, &m_pipeline);
912 memset(m_program, 0, sizeof(m_program));
913 glGenVertexArrays(1, &m_vertex_array);
914 glGenTextures(2, m_texture);
915 return NO_ERROR;
916 }
917
Run()918 virtual long Run()
919 {
920 const char *const glsl_vs = "#version 430 core" NL "out gl_PerVertex { vec4 gl_Position; };" NL
921 "const vec2 g_position[3] = { vec2(-1, -1), vec2(3, -1), vec2(-1, 3) };" NL
922 "void main() { gl_Position = vec4(g_position[gl_VertexID], 0, 1); }";
923 const char *const glsl_fs =
924 "#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL
925 "layout(binding = 0, rgba8) uniform image2D g_image[2];" NL "uniform ivec2 g_expected_size[2];" NL
926 "uniform int g_0 = 0, g_1 = 1;" NL "void main() {" NL " vec4 c = vec4(0, 1, 0, 1);" NL
927 " if (imageSize(g_image[g_0]).xy != g_expected_size[g_0]) c = vec4(1, 0, 0, 1);" NL
928 " if (imageSize(g_image[g_1]).yx != g_expected_size[g_1]) c = vec4(1, 0, 0, 1);" NL " g_color = c;" NL
929 "}";
930 m_program[0] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
931 m_program[1] = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
932 for (int i = 0; i < 2; ++i)
933 if (!CheckProgram(m_program[i]))
934 return ERROR;
935
936 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_program[0]);
937 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_program[1]);
938
939 glBindVertexArray(m_vertex_array);
940 glBindProgramPipeline(m_pipeline);
941
942 int size[2] = {32, 128};
943 for (int i = 0; i < 2; ++i)
944 {
945 glBindTexture(GL_TEXTURE_2D, m_texture[i]);
946 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
947 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
948 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[i], size[i], 0, GL_RGBA, GL_FLOAT, NULL);
949 glBindImageTexture(i, m_texture[i], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
950 }
951
952 for (int i = 0; i < 3; ++i)
953 {
954 glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[0]"), size[0],
955 size[0]);
956 glProgramUniform2i(m_program[1], glGetUniformLocation(m_program[1], "g_expected_size[1]"), size[1],
957 size[1]);
958 glClear(GL_COLOR_BUFFER_BIT);
959 glDrawArrays(GL_TRIANGLES, 0, 3);
960
961 {
962 bool status = true;
963 std::vector<vec3> fb(getWindowWidth() * getWindowHeight());
964 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
965 if (!ValidateReadBuffer(0, 0, getWindowWidth(), getWindowHeight(), vec4(0, 1, 0, 1)))
966 status = false;
967 if (!status)
968 return ERROR;
969 }
970
971 size[0] /= 2;
972 size[1] /= 2;
973
974 glBindTexture(GL_TEXTURE_2D, m_texture[0]);
975 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[0], size[0], 0, GL_RGBA, GL_FLOAT, NULL);
976 glBindTexture(GL_TEXTURE_2D, m_texture[1]);
977 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size[1], size[1], 0, GL_RGBA, GL_FLOAT, NULL);
978 }
979 return NO_ERROR;
980 }
981
Cleanup()982 virtual long Cleanup()
983 {
984 glDeleteProgramPipelines(1, &m_pipeline);
985 for (int i = 0; i < 2; ++i)
986 glDeleteProgram(m_program[i]);
987 glDeleteVertexArrays(1, &m_vertex_array);
988 glDeleteTextures(2, m_texture);
989 return NO_ERROR;
990 }
991 };
992 //=============================================================================
993 // 2.2.x.y AdvancedNonMS
994 //-----------------------------------------------------------------------------
995
996 template <typename T, int STAGE>
997 class AdvancedNonMS : public ShaderImageSizeBase
998 {
999 GLuint m_texture[7];
1000 GLuint m_buffer;
1001
Setup()1002 virtual long Setup()
1003 {
1004 glGenTextures(7, m_texture);
1005 glGenBuffers(1, &m_buffer);
1006 return NO_ERROR;
1007 }
1008
Run()1009 virtual long Run()
1010 {
1011 if (!SupportedInStage(STAGE, 8))
1012 return NOT_SUPPORTED;
1013
1014 const GLenum target[7] = {GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP_ARRAY,
1015 GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D_ARRAY,
1016 GL_TEXTURE_BUFFER};
1017 for (int i = 0; i < 7; ++i)
1018 {
1019 glBindTexture(target[i], m_texture[i]);
1020 if (target[i] != GL_TEXTURE_BUFFER)
1021 {
1022 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1023 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1024 }
1025
1026 if (i == 0)
1027 {
1028 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 7, 0, TexFormat<T>(), TexType<T>(), NULL);
1029 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 7, 0, TexFormat<T>(), TexType<T>(), NULL);
1030 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 3, GL_READ_ONLY, TexInternalFormat<T>());
1031 }
1032 else if (i == 1)
1033 {
1034 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 2, 0, TexFormat<T>(), TexType<T>(), NULL);
1035 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 1, 0, TexFormat<T>(), TexType<T>(), NULL);
1036 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 1, 0, TexFormat<T>(), TexType<T>(), NULL);
1037 glBindImageTexture(2, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1038 }
1039 else if (i == 2)
1040 {
1041 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 2, 2, 12, 0, TexFormat<T>(), TexType<T>(), NULL);
1042 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 1, 1, 12, 0, TexFormat<T>(), TexType<T>(), NULL);
1043 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>());
1044 }
1045 else if (i == 3)
1046 {
1047 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 4, 4, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
1048 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 2, 2, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
1049 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 1, 1, 18, 0, TexFormat<T>(), TexType<T>(), NULL);
1050 glBindImageTexture(4, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1051 }
1052 else if (i == 4)
1053 {
1054 glTexImage2D(target[i], 0, TexInternalFormat<T>(), 123, 11, 0, TexFormat<T>(), TexType<T>(), NULL);
1055 glBindImageTexture(5, m_texture[i], 0, GL_FALSE, 0, GL_READ_WRITE, TexInternalFormat<T>());
1056 }
1057 else if (i == 5)
1058 {
1059 glTexImage3D(target[i], 0, TexInternalFormat<T>(), 13, 7, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
1060 glTexImage3D(target[i], 1, TexInternalFormat<T>(), 6, 3, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
1061 glTexImage3D(target[i], 2, TexInternalFormat<T>(), 3, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
1062 glTexImage3D(target[i], 3, TexInternalFormat<T>(), 1, 1, 4, 0, TexFormat<T>(), TexType<T>(), NULL);
1063 glBindImageTexture(6, m_texture[i], 1, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1064 }
1065 else if (i == 6)
1066 {
1067 glBindBuffer(GL_TEXTURE_BUFFER, m_buffer);
1068 glBufferData(GL_TEXTURE_BUFFER, 1024, NULL, GL_STATIC_DRAW);
1069 glTexBufferRange(GL_TEXTURE_BUFFER, TexInternalFormat<T>(), m_buffer, 256, 512);
1070 glBindImageTexture(7, m_texture[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, TexInternalFormat<T>());
1071 }
1072 }
1073 ImageSizeMachine machine;
1074 ivec4 res[7] = {ivec4(1, 1, 0, 0), ivec4(2, 2, 1, 0), ivec4(2, 2, 0, 0), ivec4(2, 2, 3, 0),
1075 ivec4(123, 11, 0, 0), ivec4(6, 3, 4, 0), ivec4(32, 0, 0, 0)};
1076 return machine.Run<T>(STAGE, false, res, true);
1077 }
1078
Cleanup()1079 virtual long Cleanup()
1080 {
1081 glDeleteTextures(7, m_texture);
1082 glDeleteBuffers(1, &m_buffer);
1083 return NO_ERROR;
1084 }
1085 };
1086 //=============================================================================
1087 // 2.3.x.y AdvancedMS
1088 //-----------------------------------------------------------------------------
1089 template <typename T, int STAGE>
1090 class AdvancedMS : public ShaderImageSizeBase
1091 {
1092 GLuint m_texture[4];
1093
Setup()1094 virtual long Setup()
1095 {
1096 glGenTextures(4, m_texture);
1097 return NO_ERROR;
1098 }
1099
Run()1100 virtual long Run()
1101 {
1102 if (!SupportedInStage(STAGE, 5))
1103 return NOT_SUPPORTED;
1104 if (!SupportedSamples(4))
1105 return NOT_SUPPORTED;
1106
1107 const GLenum target[4] = {GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
1108 GL_TEXTURE_2D_MULTISAMPLE_ARRAY};
1109 for (int i = 0; i < 4; ++i)
1110 {
1111 glBindTexture(target[i], m_texture[i]);
1112 if (target[i] == GL_TEXTURE_1D || target[i] == GL_TEXTURE_1D_ARRAY)
1113 {
1114 glTexParameteri(target[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1115 glTexParameteri(target[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1116 }
1117
1118 if (i == 0)
1119 {
1120 glTexImage1D(target[i], 0, TexInternalFormat<T>(), 7, 0, TexFormat<T>(), TexType<T>(), NULL);
1121 glTexImage1D(target[i], 1, TexInternalFormat<T>(), 3, 0, TexFormat<T>(), TexType<T>(), NULL);
1122 glTexImage1D(target[i], 2, TexInternalFormat<T>(), 1, 0, TexFormat<T>(), TexType<T>(), NULL);
1123 glBindImageTexture(1, m_texture[i], 1, GL_FALSE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1124 }
1125 else if (i == 1)
1126 {
1127 glTexImage2D(target[i], 0, TexInternalFormat<T>(), 7, 15, 0, TexFormat<T>(), TexType<T>(), NULL);
1128 glBindImageTexture(2, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1129 }
1130 else if (i == 2)
1131 {
1132 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 7, 9, 3, GL_FALSE);
1133 glBindImageTexture(3, m_texture[i], 0, GL_FALSE, 1, GL_READ_WRITE, TexInternalFormat<T>());
1134 }
1135 else if (i == 3)
1136 {
1137 glTexImage3DMultisample(target[i], 4, TexInternalFormat<T>(), 64, 32, 5, GL_FALSE);
1138 glBindImageTexture(4, m_texture[i], 0, GL_TRUE, 0, GL_READ_ONLY, TexInternalFormat<T>());
1139 }
1140 }
1141 ImageSizeMachine machine;
1142 ivec4 res[7] = {ivec4(3, 0, 0, 0), ivec4(7, 15, 0, 0), ivec4(7, 9, 0, 0), ivec4(64, 32, 5, 0),
1143 ivec4(0), ivec4(0), ivec4(0)};
1144 return machine.Run<T>(STAGE, true, res, true);
1145 }
1146
Cleanup()1147 virtual long Cleanup()
1148 {
1149 glDeleteTextures(4, m_texture);
1150 return NO_ERROR;
1151 }
1152 };
1153 //=============================================================================
1154 // 4.1 NegativeCompileTime
1155 //-----------------------------------------------------------------------------
1156 class NegativeCompileTime : public ShaderImageSizeBase
1157 {
Run()1158 virtual long Run()
1159 {
1160 // '#extension GL_ARB_shader_image_size : require' is missing
1161 if (!Compile("#version 420 core" NL "layout(location = 0) out vec4 g_color;" NL
1162 "layout(binding = 0, rg16f) uniform image2D g_image;" NL "uniform ivec2 g_expected_size;" NL
1163 "void main() {" NL " if (imageSize(g_image) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL
1164 " else g_color = vec4(1, 0, 0, 1);" NL "}"))
1165 return ERROR;
1166 // imageSize(sampler)
1167 if (!Compile("#version 430 core" NL "layout(location = 0) out vec4 g_color;" NL
1168 "layout(binding = 0) uniform sampler2D g_sampler;" NL "uniform ivec2 g_expected_size;" NL
1169 "void main() {" NL " if (imageSize(g_sampler) == g_expected_size) g_color = vec4(0, 1, 0, 1);" NL
1170 " else g_color = vec4(1, 0, 0, 1);" NL "}"))
1171 return ERROR;
1172 return NO_ERROR;
1173 }
1174
Compile(const std::string & source)1175 bool Compile(const std::string &source)
1176 {
1177 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER);
1178
1179 const char *const src = source.c_str();
1180 glShaderSource(sh, 1, &src, NULL);
1181 glCompileShader(sh);
1182
1183 GLchar log[1024];
1184 glGetShaderInfoLog(sh, sizeof(log), NULL, log);
1185 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader Info Log:\n"
1186 << log << tcu::TestLog::EndMessage;
1187
1188 GLint status;
1189 glGetShaderiv(sh, GL_COMPILE_STATUS, &status);
1190 glDeleteShader(sh);
1191
1192 if (status == GL_TRUE)
1193 {
1194 m_context.getTestContext().getLog()
1195 << tcu::TestLog::Message << "Compilation should fail." << tcu::TestLog::EndMessage;
1196 return false;
1197 }
1198 return true;
1199 }
1200 };
1201
1202 } // anonymous namespace
1203
ShaderImageSizeTests(deqp::Context & context)1204 ShaderImageSizeTests::ShaderImageSizeTests(deqp::Context &context) : TestCaseGroup(context, "shader_image_size", "")
1205 {
1206 }
1207
~ShaderImageSizeTests(void)1208 ShaderImageSizeTests::~ShaderImageSizeTests(void)
1209 {
1210 }
1211
init()1212 void ShaderImageSizeTests::init()
1213 {
1214 using namespace deqp;
1215 addChild(new TestSubcase(m_context, "basic-nonMS-vs-float", TestSubcase::Create<BasicNonMS<vec4, 0>>));
1216 addChild(new TestSubcase(m_context, "basic-nonMS-vs-int", TestSubcase::Create<BasicNonMS<ivec4, 0>>));
1217 addChild(new TestSubcase(m_context, "basic-nonMS-vs-uint", TestSubcase::Create<BasicNonMS<uvec4, 0>>));
1218 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-float", TestSubcase::Create<BasicNonMS<vec4, 1>>));
1219 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-int", TestSubcase::Create<BasicNonMS<ivec4, 1>>));
1220 addChild(new TestSubcase(m_context, "basic-nonMS-tcs-uint", TestSubcase::Create<BasicNonMS<uvec4, 1>>));
1221 addChild(new TestSubcase(m_context, "basic-nonMS-tes-float", TestSubcase::Create<BasicNonMS<vec4, 2>>));
1222 addChild(new TestSubcase(m_context, "basic-nonMS-tes-int", TestSubcase::Create<BasicNonMS<ivec4, 2>>));
1223 addChild(new TestSubcase(m_context, "basic-nonMS-tes-uint", TestSubcase::Create<BasicNonMS<uvec4, 2>>));
1224 addChild(new TestSubcase(m_context, "basic-nonMS-gs-float", TestSubcase::Create<BasicNonMS<vec4, 3>>));
1225 addChild(new TestSubcase(m_context, "basic-nonMS-gs-int", TestSubcase::Create<BasicNonMS<ivec4, 3>>));
1226 addChild(new TestSubcase(m_context, "basic-nonMS-gs-uint", TestSubcase::Create<BasicNonMS<uvec4, 3>>));
1227 addChild(new TestSubcase(m_context, "basic-nonMS-fs-float", TestSubcase::Create<BasicNonMS<vec4, 5>>));
1228 addChild(new TestSubcase(m_context, "basic-nonMS-fs-int", TestSubcase::Create<BasicNonMS<ivec4, 5>>));
1229 addChild(new TestSubcase(m_context, "basic-nonMS-fs-uint", TestSubcase::Create<BasicNonMS<uvec4, 5>>));
1230 addChild(new TestSubcase(m_context, "basic-nonMS-cs-float", TestSubcase::Create<BasicNonMS<vec4, 4>>));
1231 addChild(new TestSubcase(m_context, "basic-nonMS-cs-int", TestSubcase::Create<BasicNonMS<ivec4, 4>>));
1232 addChild(new TestSubcase(m_context, "basic-nonMS-cs-uint", TestSubcase::Create<BasicNonMS<uvec4, 4>>));
1233 addChild(new TestSubcase(m_context, "basic-ms-vs-float", TestSubcase::Create<BasicMS<vec4, 0>>));
1234 addChild(new TestSubcase(m_context, "basic-ms-vs-int", TestSubcase::Create<BasicMS<ivec4, 0>>));
1235 addChild(new TestSubcase(m_context, "basic-ms-vs-uint", TestSubcase::Create<BasicMS<uvec4, 0>>));
1236 addChild(new TestSubcase(m_context, "basic-ms-tcs-float", TestSubcase::Create<BasicMS<vec4, 1>>));
1237 addChild(new TestSubcase(m_context, "basic-ms-tcs-int", TestSubcase::Create<BasicMS<ivec4, 1>>));
1238 addChild(new TestSubcase(m_context, "basic-ms-tcs-uint", TestSubcase::Create<BasicMS<uvec4, 1>>));
1239 addChild(new TestSubcase(m_context, "basic-ms-tes-float", TestSubcase::Create<BasicMS<vec4, 2>>));
1240 addChild(new TestSubcase(m_context, "basic-ms-tes-int", TestSubcase::Create<BasicMS<ivec4, 2>>));
1241 addChild(new TestSubcase(m_context, "basic-ms-tes-uint", TestSubcase::Create<BasicMS<uvec4, 2>>));
1242 addChild(new TestSubcase(m_context, "basic-ms-gs-float", TestSubcase::Create<BasicMS<vec4, 3>>));
1243 addChild(new TestSubcase(m_context, "basic-ms-gs-int", TestSubcase::Create<BasicMS<ivec4, 3>>));
1244 addChild(new TestSubcase(m_context, "basic-ms-gs-uint", TestSubcase::Create<BasicMS<uvec4, 3>>));
1245 addChild(new TestSubcase(m_context, "basic-ms-fs-float", TestSubcase::Create<BasicMS<vec4, 5>>));
1246 addChild(new TestSubcase(m_context, "basic-ms-fs-int", TestSubcase::Create<BasicMS<ivec4, 5>>));
1247 addChild(new TestSubcase(m_context, "basic-ms-fs-uint", TestSubcase::Create<BasicMS<uvec4, 5>>));
1248 addChild(new TestSubcase(m_context, "basic-ms-cs-float", TestSubcase::Create<BasicMS<vec4, 4>>));
1249 addChild(new TestSubcase(m_context, "basic-ms-cs-int", TestSubcase::Create<BasicMS<ivec4, 4>>));
1250 addChild(new TestSubcase(m_context, "basic-ms-cs-uint", TestSubcase::Create<BasicMS<uvec4, 4>>));
1251 addChild(new TestSubcase(m_context, "advanced-changeSize", TestSubcase::Create<AdvancedChangeSize>));
1252 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-float", TestSubcase::Create<AdvancedNonMS<vec4, 0>>));
1253 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 0>>));
1254 addChild(new TestSubcase(m_context, "advanced-nonMS-vs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 0>>));
1255 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-float", TestSubcase::Create<AdvancedNonMS<vec4, 1>>));
1256 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 1>>));
1257 addChild(new TestSubcase(m_context, "advanced-nonMS-tcs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 1>>));
1258 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-float", TestSubcase::Create<AdvancedNonMS<vec4, 2>>));
1259 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-int", TestSubcase::Create<AdvancedNonMS<ivec4, 2>>));
1260 addChild(new TestSubcase(m_context, "advanced-nonMS-tes-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 2>>));
1261 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-float", TestSubcase::Create<AdvancedNonMS<vec4, 3>>));
1262 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 3>>));
1263 addChild(new TestSubcase(m_context, "advanced-nonMS-gs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 3>>));
1264 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-float", TestSubcase::Create<AdvancedNonMS<vec4, 5>>));
1265 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 5>>));
1266 addChild(new TestSubcase(m_context, "advanced-nonMS-fs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 5>>));
1267 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-float", TestSubcase::Create<AdvancedNonMS<vec4, 4>>));
1268 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-int", TestSubcase::Create<AdvancedNonMS<ivec4, 4>>));
1269 addChild(new TestSubcase(m_context, "advanced-nonMS-cs-uint", TestSubcase::Create<AdvancedNonMS<uvec4, 4>>));
1270 addChild(new TestSubcase(m_context, "advanced-ms-vs-float", TestSubcase::Create<AdvancedMS<vec4, 0>>));
1271 addChild(new TestSubcase(m_context, "advanced-ms-vs-int", TestSubcase::Create<AdvancedMS<ivec4, 0>>));
1272 addChild(new TestSubcase(m_context, "advanced-ms-vs-uint", TestSubcase::Create<AdvancedMS<uvec4, 0>>));
1273 addChild(new TestSubcase(m_context, "advanced-ms-tcs-float", TestSubcase::Create<AdvancedMS<vec4, 1>>));
1274 addChild(new TestSubcase(m_context, "advanced-ms-tcs-int", TestSubcase::Create<AdvancedMS<ivec4, 1>>));
1275 addChild(new TestSubcase(m_context, "advanced-ms-tcs-uint", TestSubcase::Create<AdvancedMS<uvec4, 1>>));
1276 addChild(new TestSubcase(m_context, "advanced-ms-tes-float", TestSubcase::Create<AdvancedMS<vec4, 2>>));
1277 addChild(new TestSubcase(m_context, "advanced-ms-tes-int", TestSubcase::Create<AdvancedMS<ivec4, 2>>));
1278 addChild(new TestSubcase(m_context, "advanced-ms-tes-uint", TestSubcase::Create<AdvancedMS<uvec4, 2>>));
1279 addChild(new TestSubcase(m_context, "advanced-ms-gs-float", TestSubcase::Create<AdvancedMS<vec4, 3>>));
1280 addChild(new TestSubcase(m_context, "advanced-ms-gs-int", TestSubcase::Create<AdvancedMS<ivec4, 3>>));
1281 addChild(new TestSubcase(m_context, "advanced-ms-gs-uint", TestSubcase::Create<AdvancedMS<uvec4, 3>>));
1282 addChild(new TestSubcase(m_context, "advanced-ms-fs-float", TestSubcase::Create<AdvancedMS<vec4, 5>>));
1283 addChild(new TestSubcase(m_context, "advanced-ms-fs-int", TestSubcase::Create<AdvancedMS<ivec4, 5>>));
1284 addChild(new TestSubcase(m_context, "advanced-ms-fs-uint", TestSubcase::Create<AdvancedMS<uvec4, 5>>));
1285 addChild(new TestSubcase(m_context, "advanced-ms-cs-float", TestSubcase::Create<AdvancedMS<vec4, 4>>));
1286 addChild(new TestSubcase(m_context, "advanced-ms-cs-int", TestSubcase::Create<AdvancedMS<ivec4, 4>>));
1287 addChild(new TestSubcase(m_context, "advanced-ms-cs-uint", TestSubcase::Create<AdvancedMS<uvec4, 4>>));
1288 addChild(new TestSubcase(m_context, "negative-compileTime", TestSubcase::Create<NegativeCompileTime>));
1289 }
1290
1291 } // namespace gl4cts
1292