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