1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
25 * \file glcViewportArrayTests.cpp
26 * \brief Implements conformance tests for "Viewport Array" functionality.
27 */ /*-------------------------------------------------------------------*/
29 #include "glcViewportArrayTests.hpp"
31 #include "gluContextInfo.hpp"
32 #include "gluDefs.hpp"
33 #include "gluStrUtil.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 #include "tcuRenderTarget.hpp"
37 #include "tcuTestLog.hpp"
49 namespace ViewportArray
53 * @param context CTS context.
55 Utils::buffer::buffer(deqp::Context& context) : m_id(0), m_context(context), m_target(0)
62 Utils::buffer::~buffer()
66 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
68 gl.deleteBuffers(1, &m_id);
73 /** Execute BindBuffer
76 void Utils::buffer::bind() const
78 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
80 gl.bindBuffer(m_target, m_id);
81 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
84 /** Execute BindBufferRange
86 * @param index <index> parameter
87 * @param offset <offset> parameter
88 * @param size <size> parameter
90 void Utils::buffer::bindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size)
92 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
94 gl.bindBufferRange(m_target, index, m_id, offset, size);
95 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
100 * @param target Target that will be used by this buffer
102 void Utils::buffer::generate(glw::GLenum target)
104 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
108 gl.genBuffers(1, &m_id);
109 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
112 /** Maps buffer content
114 * @param access Access rights for mapped region
116 * @return Mapped memory
118 void* Utils::buffer::map(GLenum access) const
120 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
122 gl.bindBuffer(m_target, m_id);
123 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
125 void* result = gl.mapBuffer(m_target, access);
126 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
134 void Utils::buffer::unmap() const
136 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
138 gl.bindBuffer(m_target, m_id);
139 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
141 gl.unmapBuffer(m_target);
142 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
145 /** Execute BufferData
147 * @param size <size> parameter
148 * @param data <data> parameter
149 * @param usage <usage> parameter
151 void Utils::buffer::update(glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage)
153 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
155 gl.bindBuffer(m_target, m_id);
156 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
158 gl.bufferData(m_target, size, data, usage);
159 GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData");
164 * @param context CTS context
166 Utils::framebuffer::framebuffer(deqp::Context& context) : m_id(0), m_context(context)
168 /* Nothing to be done here */
174 Utils::framebuffer::~framebuffer()
178 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
180 gl.deleteFramebuffers(1, &m_id);
185 /** Attach texture to specified attachment
187 * @param attachment Attachment
188 * @param texture_id Texture id
189 * @param width Texture width
190 * @param height Texture height
192 void Utils::framebuffer::attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width,
195 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
199 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
200 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
202 gl.viewport(0 /* x */, 0 /* y */, width, height);
203 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
206 /** Binds framebuffer to DRAW_FRAMEBUFFER
209 void Utils::framebuffer::bind()
211 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
213 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_id);
214 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
217 /** Clear framebuffer
219 * @param mask <mask> parameter of glClear. Decides which shall be cleared
221 void Utils::framebuffer::clear(glw::GLenum mask)
223 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
226 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
229 /** Specifies clear color
231 * @param red Red channel
232 * @param green Green channel
233 * @param blue Blue channel
234 * @param alpha Alpha channel
236 void Utils::framebuffer::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
238 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
240 gl.clearColor(red, green, blue, alpha);
241 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
244 /** Generate framebuffer
247 void Utils::framebuffer::generate()
249 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
251 gl.genFramebuffers(1, &m_id);
252 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
255 Utils::shaderCompilationException::shaderCompilationException(const glw::GLchar* source, const glw::GLchar* message)
256 : m_shader_source(source), m_error_message(message)
258 /* Nothing to be done */
261 const char* Utils::shaderCompilationException::what() const throw()
263 return "Shader compilation failed";
266 Utils::programLinkageException::programLinkageException(const glw::GLchar* message) : m_error_message(message)
268 /* Nothing to be done */
271 const char* Utils::programLinkageException::what() const throw()
273 return "Program linking failed";
276 const glw::GLenum Utils::program::ARB_COMPUTE_SHADER = 0x91B9;
280 * @param context CTS context.
282 Utils::program::program(deqp::Context& context)
283 : m_compute_shader_id(0)
284 , m_fragment_shader_id(0)
285 , m_geometry_shader_id(0)
286 , m_program_object_id(0)
287 , m_tesselation_control_shader_id(0)
288 , m_tesselation_evaluation_shader_id(0)
289 , m_vertex_shader_id(0)
292 /* Nothing to be done here */
298 Utils::program::~program()
305 * @param compute_shader_code Compute shader source code
306 * @param fragment_shader_code Fragment shader source code
307 * @param geometry_shader_code Geometry shader source code
308 * @param tesselation_control_shader_code Tesselation control shader source code
309 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
310 * @param vertex_shader_code Vertex shader source code
311 * @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback
312 * @param n_varying_names Number of varyings to be captured with transfrom feedback
313 * @param is_separable Selects if monolithis or separable program should be built. Defaults to false
315 void Utils::program::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
316 const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code,
317 const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code,
318 const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable)
320 /* GL entry points */
321 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
323 /* Create shader objects and compile */
324 if (0 != compute_shader_code)
326 m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
327 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
329 compile(m_compute_shader_id, compute_shader_code);
332 if (0 != fragment_shader_code)
334 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
335 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
337 compile(m_fragment_shader_id, fragment_shader_code);
340 if (0 != geometry_shader_code)
342 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
343 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
345 compile(m_geometry_shader_id, geometry_shader_code);
348 if (0 != tesselation_control_shader_code)
350 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
351 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
353 compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
356 if (0 != tesselation_evaluation_shader_code)
358 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
359 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
361 compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
364 if (0 != vertex_shader_code)
366 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
367 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
369 compile(m_vertex_shader_id, vertex_shader_code);
372 /* Create program object */
373 m_program_object_id = gl.createProgram();
374 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
376 /* Set up captyured varyings' names */
377 if (0 != n_varying_names)
379 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
380 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
383 /* Set separable parameter */
384 if (true == is_separable)
386 gl.programParameteri(m_program_object_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
387 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
394 void Utils::program::compile(GLuint shader_id, const GLchar* source) const
396 /* GL entry points */
397 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
399 /* Compilation status */
400 glw::GLint status = GL_FALSE;
402 /* Set source code */
403 gl.shaderSource(shader_id, 1 /* count */, &source, 0 /* lengths */);
404 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
407 gl.compileShader(shader_id);
408 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
410 /* Get compilation status */
411 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
412 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
414 /* Log compilation error */
415 if (GL_TRUE != status)
417 glw::GLint length = 0;
418 std::vector<glw::GLchar> message;
420 /* Error log length */
421 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
422 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
424 /* Prepare storage */
425 message.resize(length);
428 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
429 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
431 throw shaderCompilationException(source, &message[0]);
435 glw::GLint Utils::program::getAttribLocation(const glw::GLchar* name) const
437 /* GL entry points */
438 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
440 GLint location = gl.getAttribLocation(m_program_object_id, name);
441 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
446 /** Get subroutine index
448 * @param subroutine_name Subroutine name
450 * @return Index of subroutine
452 GLuint Utils::program::getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const
454 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
457 index = gl.getSubroutineIndex(m_program_object_id, shader_stage, subroutine_name);
458 GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex");
460 if (GL_INVALID_INDEX == index)
462 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine: " << subroutine_name
463 << " is not available" << tcu::TestLog::EndMessage;
465 TCU_FAIL("Subroutine is not available");
471 /** Get subroutine uniform location
473 * @param uniform_name Subroutine uniform name
475 * @return Location of subroutine uniform
477 GLint Utils::program::getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const
479 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
482 location = gl.getSubroutineUniformLocation(m_program_object_id, shader_stage, uniform_name);
483 GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation");
487 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine uniform: " << uniform_name
488 << " is not available" << tcu::TestLog::EndMessage;
490 TCU_FAIL("Subroutine uniform is not available");
496 /** Get uniform location
498 * @param uniform_name Subroutine uniform name
500 * @return Location of uniform
502 GLint Utils::program::getUniformLocation(const glw::GLchar* uniform_name) const
504 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
507 location = gl.getUniformLocation(m_program_object_id, uniform_name);
508 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
512 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Uniform: " << uniform_name
513 << " is not available" << tcu::TestLog::EndMessage;
515 TCU_FAIL("Uniform is not available");
521 /** Attach shaders and link program
524 void Utils::program::link() const
526 /* GL entry points */
527 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
530 glw::GLint status = GL_FALSE;
533 if (0 != m_compute_shader_id)
535 gl.attachShader(m_program_object_id, m_compute_shader_id);
536 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
539 if (0 != m_fragment_shader_id)
541 gl.attachShader(m_program_object_id, m_fragment_shader_id);
542 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
545 if (0 != m_geometry_shader_id)
547 gl.attachShader(m_program_object_id, m_geometry_shader_id);
548 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
551 if (0 != m_tesselation_control_shader_id)
553 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
554 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
557 if (0 != m_tesselation_evaluation_shader_id)
559 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
560 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
563 if (0 != m_vertex_shader_id)
565 gl.attachShader(m_program_object_id, m_vertex_shader_id);
566 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
570 gl.linkProgram(m_program_object_id);
571 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
573 /* Get link status */
574 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
575 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
578 if (GL_TRUE != status)
580 glw::GLint length = 0;
581 std::vector<glw::GLchar> message;
583 /* Get error log length */
584 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
585 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
587 message.resize(length);
590 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
591 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
593 throw programLinkageException(&message[0]);
597 /** Delete program object and all attached shaders
600 void Utils::program::remove()
602 /* GL entry points */
603 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
605 /* Make sure program object is no longer used by GL */
608 /* Clean program object */
609 if (0 != m_program_object_id)
611 gl.deleteProgram(m_program_object_id);
612 m_program_object_id = 0;
616 if (0 != m_compute_shader_id)
618 gl.deleteShader(m_compute_shader_id);
619 m_compute_shader_id = 0;
622 if (0 != m_fragment_shader_id)
624 gl.deleteShader(m_fragment_shader_id);
625 m_fragment_shader_id = 0;
628 if (0 != m_geometry_shader_id)
630 gl.deleteShader(m_geometry_shader_id);
631 m_geometry_shader_id = 0;
634 if (0 != m_tesselation_control_shader_id)
636 gl.deleteShader(m_tesselation_control_shader_id);
637 m_tesselation_control_shader_id = 0;
640 if (0 != m_tesselation_evaluation_shader_id)
642 gl.deleteShader(m_tesselation_evaluation_shader_id);
643 m_tesselation_evaluation_shader_id = 0;
646 if (0 != m_vertex_shader_id)
648 gl.deleteShader(m_vertex_shader_id);
649 m_vertex_shader_id = 0;
653 /** Execute UseProgram
656 void Utils::program::use() const
658 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
660 gl.useProgram(m_program_object_id);
661 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
664 void Utils::program::printShaderSource(const GLchar* source, tcu::MessageBuilder& log)
666 GLuint line_number = 0;
668 log << "Shader source.";
670 log << "\nLine||Source\n";
675 const GLchar* next_line = strchr(source, '\n');
680 line.assign(source, next_line - source);
689 log << std::setw(4) << line_number << "||" << line;
699 * @param context CTS context.
701 Utils::texture::texture(deqp::Context& context) : m_id(0), m_context(context), m_is_array(false)
703 /* Nothing to done here */
709 Utils::texture::~texture()
714 /** Bind texture to GL_TEXTURE_2D
717 void Utils::texture::bind() const
719 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
721 if (false == m_is_array)
723 gl.bindTexture(GL_TEXTURE_2D, m_id);
724 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
728 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_id);
729 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
733 /** Create 2d texture
735 * @param width Width of texture
736 * @param height Height of texture
737 * @param internal_format Internal format of texture
739 void Utils::texture::create(GLuint width, GLuint height, GLenum internal_format)
741 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
747 gl.genTextures(1, &m_id);
748 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
752 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, internal_format, width, height);
753 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
756 /** Create 2d texture array
758 * @param width Width of texture
759 * @param height Height of texture
760 * @param depth Depth of texture
761 * @param internal_format Internal format of texture
763 void Utils::texture::create(GLuint width, GLuint height, GLuint depth, GLenum internal_format)
765 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
771 gl.genTextures(1, &m_id);
772 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
776 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, internal_format, width, height, depth);
777 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
780 /** Get contents of texture
782 * @param format Format of image
783 * @param type Type of image
784 * @param out_data Buffer for image
786 void Utils::texture::get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data) const
788 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
792 GLenum textarget = GL_TEXTURE_2D;
794 if (true == m_is_array)
796 textarget = GL_TEXTURE_2D_ARRAY;
799 gl.getTexImage(textarget, 0 /* level */, format, type, out_data);
800 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
806 void Utils::texture::release()
810 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
812 gl.deleteTextures(1, &m_id);
817 /** Update contents of texture
819 * @param width Width of texture
820 * @param height Height of texture
821 * @param depth Depth of texture
822 * @param format Format of data
823 * @param type Type of data
824 * @param data Buffer with image
826 void Utils::texture::update(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format,
827 glw::GLenum type, glw::GLvoid* data)
829 static const GLuint level = 0;
831 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
835 if (false == m_is_array)
837 gl.texSubImage2D(GL_TEXTURE_2D, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
838 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
842 gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format,
844 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
850 * @param context CTS context.
852 Utils::vertexArray::vertexArray(deqp::Context& context) : m_id(0), m_context(context)
859 Utils::vertexArray::~vertexArray()
863 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
865 gl.deleteVertexArrays(1, &m_id);
871 /** Execute BindVertexArray
874 void Utils::vertexArray::bind()
876 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
878 gl.bindVertexArray(m_id);
879 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
882 /** Execute GenVertexArrays
885 void Utils::vertexArray::generate()
887 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
889 gl.genVertexArrays(1, &m_id);
890 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
895 * @param context Test context
897 APIErrors::APIErrors(deqp::Context& context, const glcts::ExtParameters& extParams)
898 : TestCaseBase(context, extParams, "api_errors", "Test verifies error generated by API")
900 /* Nothing to be done here */
905 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
907 tcu::TestNode::IterateResult APIErrors::iterate()
909 /* GL entry points */
910 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
913 bool test_result = true;
915 GLint max_viewports = 0;
916 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
917 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
920 * * DepthRangeArrayv generates INVALID_VALUE when <first> + <count> is greater
921 * than or equal to the value of MAX_VIEWPORTS;
924 std::vector<GLdouble> data;
925 data.resize(max_viewports * 2 /* near + far */);
927 for (GLint i = 0; i < max_viewports; ++i)
930 data[i * 2 + 1] = 1.0;
933 gl.depthRangeArrayv(0, max_viewports - 1, &data[0]);
934 checkGLError(GL_NO_ERROR, "depthRangeArrayv, correct parameters", test_result);
936 gl.depthRangeArrayv(max_viewports, 1, &data[0]);
937 checkGLError(GL_INVALID_VALUE, "depthRangeArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
939 gl.depthRangeArrayv(1, max_viewports - 1, &data[0]);
940 checkGLError(GL_NO_ERROR, "depthRangeArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
942 gl.depthRangeArrayv(1, max_viewports, &data[0]);
943 checkGLError(GL_INVALID_VALUE, "depthRangeArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
947 * * DepthRangeIndexed generates INVALID_VALUE when <index> is greater than or
948 * equal to the value of MAX_VIEWPORTS;
951 gl.depthRangeIndexed(0 /* index */, 0.0, 1.0);
952 checkGLError(GL_NO_ERROR, "depthRangeIndexed, <index> == 0", test_result);
954 gl.depthRangeIndexed(max_viewports - 1 /* index */, 0.0, 1.0);
955 checkGLError(GL_NO_ERROR, "depthRangeIndexed, <index> == GL_MAX_VIEWPORTS - 1", test_result);
957 gl.depthRangeIndexed(max_viewports /* index */, 0.0, 1.0);
958 checkGLError(GL_INVALID_VALUE, "depthRangeIndexed, <index> == GL_MAX_VIEWPORTS", test_result);
960 gl.depthRangeIndexed(max_viewports + 1 /* index */, 0.0, 1.0);
961 checkGLError(GL_INVALID_VALUE, "depthRangeIndexed, <index> > GL_MAX_VIEWPORTS", test_result);
965 * * ViewportArrayv generates INVALID_VALUE when <first> + <count> is greater
966 * than or equal to the value of MAX_VIEWPORTS;
969 std::vector<GLfloat> data;
970 data.resize(max_viewports * 4 /* x + y + w + h */);
972 for (GLint i = 0; i < max_viewports; ++i)
974 data[i * 4 + 0] = 0.0f;
975 data[i * 4 + 1] = 0.0f;
976 data[i * 4 + 2] = 1.0f;
977 data[i * 4 + 3] = 1.0f;
980 gl.viewportArrayv(0, max_viewports - 1, &data[0]);
981 checkGLError(GL_NO_ERROR, "viewportArrayv, correct parameters", test_result);
983 gl.viewportArrayv(max_viewports, 1, &data[0]);
984 checkGLError(GL_INVALID_VALUE, "viewportArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
986 gl.viewportArrayv(1, max_viewports - 1, &data[0]);
987 checkGLError(GL_NO_ERROR, "viewportArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
989 gl.viewportArrayv(1, max_viewports, &data[0]);
990 checkGLError(GL_INVALID_VALUE, "viewportArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
994 * * ViewportIndexedf and ViewportIndexedfv generate INVALID_VALUE when <index>
995 * is greater than or equal to the value of MAX_VIEWPORTS;
998 GLfloat data[4 /* x + y + w + h */];
1005 gl.viewportIndexedf(0 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1006 checkGLError(GL_NO_ERROR, "viewportIndexedf, <index> == 0", test_result);
1008 gl.viewportIndexedf(max_viewports - 1 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1009 checkGLError(GL_NO_ERROR, "viewportIndexedf, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1011 gl.viewportIndexedf(max_viewports /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1012 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, <index> == GL_MAX_VIEWPORTS", test_result);
1014 gl.viewportIndexedf(max_viewports + 1 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1015 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, <index> > GL_MAX_VIEWPORTS", test_result);
1017 gl.viewportIndexedfv(0 /* index */, data);
1018 checkGLError(GL_NO_ERROR, "viewportIndexedfv, <index> == 0", test_result);
1020 gl.viewportIndexedfv(max_viewports - 1 /* index */, data);
1021 checkGLError(GL_NO_ERROR, "viewportIndexedfv, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1023 gl.viewportIndexedfv(max_viewports /* index */, data);
1024 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, <index> == GL_MAX_VIEWPORTS", test_result);
1026 gl.viewportIndexedfv(max_viewports + 1 /* index */, data);
1027 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, <index> > GL_MAX_VIEWPORTS", test_result);
1031 * * ViewportArrayv, Viewport, ViewportIndexedf and ViewportIndexedfv generate
1032 * INVALID_VALUE when <w> or <h> values are negative;
1035 gl.viewport(0, 0, -1, 1);
1036 checkGLError(GL_INVALID_VALUE, "viewport, negative width", test_result);
1038 gl.viewport(0, 0, 1, -1);
1039 checkGLError(GL_INVALID_VALUE, "viewport, negative height", test_result);
1041 for (GLint i = 0; i < max_viewports; ++i)
1043 std::vector<GLfloat> data;
1044 data.resize(max_viewports * 4 /* x + y + w + h */);
1046 for (GLint j = 0; j < max_viewports; ++j)
1048 data[j * 4 + 0] = 0.0f;
1049 data[j * 4 + 1] = 0.0f;
1050 data[j * 4 + 2] = 1.0f;
1051 data[j * 4 + 3] = 1.0f;
1054 /* Set width to -1 */
1055 data[i * 4 + 2] = -1.0f;
1057 gl.viewportArrayv(0, max_viewports, &data[0]);
1058 checkGLError(GL_INVALID_VALUE, "viewportArrayv, negative width", test_result);
1060 gl.viewportIndexedf(i /* index */, 0.0f, 0.0f, -1.0f, 1.0f);
1061 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, negative width", test_result);
1063 gl.viewportIndexedfv(i /* index */, &data[i * 4]);
1064 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, negative width", test_result);
1066 /* Set width to 1 and height to -1*/
1067 data[i * 4 + 2] = 1.0f;
1068 data[i * 4 + 3] = -1.0f;
1070 gl.viewportArrayv(0, max_viewports, &data[0]);
1071 checkGLError(GL_INVALID_VALUE, "viewportArrayv, negative height", test_result);
1073 gl.viewportIndexedf(i /* index */, 0.0f, 0.0f, 1.0f, -1.0f);
1074 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, negative height", test_result);
1076 gl.viewportIndexedfv(i /* index */, &data[i * 4]);
1077 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, negative height", test_result);
1082 * * ScissorArrayv generates INVALID_VALUE when <first> + <count> is greater
1083 * than or equal to the value of MAX_VIEWPORTS;
1086 std::vector<GLint> data;
1087 data.resize(max_viewports * 4 /* x + y + w + h */);
1089 for (GLint i = 0; i < max_viewports; ++i)
1091 data[i * 4 + 0] = 0;
1092 data[i * 4 + 1] = 0;
1093 data[i * 4 + 2] = 1;
1094 data[i * 4 + 3] = 1;
1097 gl.scissorArrayv(0, max_viewports - 1, &data[0]);
1098 checkGLError(GL_NO_ERROR, "scissorArrayv, correct parameters", test_result);
1100 gl.scissorArrayv(max_viewports, 1, &data[0]);
1101 checkGLError(GL_INVALID_VALUE, "scissorArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
1103 gl.scissorArrayv(1, max_viewports - 1, &data[0]);
1104 checkGLError(GL_NO_ERROR, "scissorArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
1106 gl.scissorArrayv(1, max_viewports, &data[0]);
1107 checkGLError(GL_INVALID_VALUE, "scissorArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
1111 * * ScissorIndexed and ScissorIndexedv generate INVALID_VALUE when <index> is
1112 * greater than or equal to the value of MAX_VIEWPORTS;
1115 GLint data[4 /* x + y + w + h */];
1122 gl.scissorIndexed(0 /* index */, 0, 0, 1, 1);
1123 checkGLError(GL_NO_ERROR, "scissorIndexed, <index> == 0", test_result);
1125 gl.scissorIndexed(max_viewports - 1 /* index */, 0, 0, 1, 1);
1126 checkGLError(GL_NO_ERROR, "scissorIndexed, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1128 gl.scissorIndexed(max_viewports /* index */, 0, 0, 1, 1);
1129 checkGLError(GL_INVALID_VALUE, "scissorIndexed, <index> == GL_MAX_VIEWPORTS", test_result);
1131 gl.scissorIndexed(max_viewports + 1 /* index */, 0, 0, 1, 1);
1132 checkGLError(GL_INVALID_VALUE, "scissorIndexed, <index> > GL_MAX_VIEWPORTS", test_result);
1134 gl.scissorIndexedv(0 /* index */, data);
1135 checkGLError(GL_NO_ERROR, "scissorIndexedv, <index> == 0", test_result);
1137 gl.scissorIndexedv(max_viewports - 1 /* index */, data);
1138 checkGLError(GL_NO_ERROR, "scissorIndexedv, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1140 gl.scissorIndexedv(max_viewports /* index */, data);
1141 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, <index> == GL_MAX_VIEWPORTS", test_result);
1143 gl.scissorIndexedv(max_viewports + 1 /* index */, data);
1144 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, <index> > GL_MAX_VIEWPORTS", test_result);
1148 * * ScissorArrayv, ScissorIndexed, ScissorIndexedv and Scissor generate
1149 * INVALID_VALUE when <width> or <height> values are negative;
1152 gl.scissor(0, 0, -1, 1);
1153 checkGLError(GL_INVALID_VALUE, "scissor, negative width", test_result);
1155 gl.scissor(0, 0, 1, -1);
1156 checkGLError(GL_INVALID_VALUE, "scissor, negative height", test_result);
1158 for (GLint i = 0; i < max_viewports; ++i)
1160 std::vector<GLint> data;
1161 data.resize(max_viewports * 4 /* x + y + w + h */);
1163 for (GLint j = 0; j < max_viewports; ++j)
1165 data[j * 4 + 0] = 0;
1166 data[j * 4 + 1] = 0;
1167 data[j * 4 + 2] = 1;
1168 data[j * 4 + 3] = 1;
1171 /* Set width to -1 */
1172 data[i * 4 + 2] = -1;
1174 gl.scissorArrayv(0, max_viewports, &data[0]);
1175 checkGLError(GL_INVALID_VALUE, "scissorArrayv, negative width", test_result);
1177 gl.scissorIndexed(i /* index */, 0, 0, -1, 1);
1178 checkGLError(GL_INVALID_VALUE, "scissorIndexed, negative width", test_result);
1180 gl.scissorIndexedv(i /* index */, &data[i * 4]);
1181 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, negative width", test_result);
1183 /* Set width to 1 and height to -1*/
1184 data[i * 4 + 2] = 1;
1185 data[i * 4 + 3] = -1;
1187 gl.scissorArrayv(0, max_viewports, &data[0]);
1188 checkGLError(GL_INVALID_VALUE, "scissorArrayv, negative height", test_result);
1190 gl.scissorIndexed(i /* index */, 0, 0, 1, -1);
1191 checkGLError(GL_INVALID_VALUE, "scissorIndexed, negative height", test_result);
1193 gl.scissorIndexedv(i /* index */, &data[i * 4]);
1194 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, negative height", test_result);
1199 * * Disablei, Enablei and IsEnabledi generate INVALID_VALUE when <cap> is
1200 * SCISSOR_TEST and <index> is greater than or equal to the
1201 * value of MAX_VIEWPORTS;
1204 gl.disablei(GL_SCISSOR_TEST, max_viewports - 1);
1205 checkGLError(GL_NO_ERROR, "disablei, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1207 gl.disablei(GL_SCISSOR_TEST, max_viewports);
1208 checkGLError(GL_INVALID_VALUE, "disablei, <index> == GL_MAX_VIEWPORTS", test_result);
1210 gl.enablei(GL_SCISSOR_TEST, max_viewports - 1);
1211 checkGLError(GL_NO_ERROR, "enablei, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1213 gl.enablei(GL_SCISSOR_TEST, max_viewports);
1214 checkGLError(GL_INVALID_VALUE, "enablei, <index> == GL_MAX_VIEWPORTS", test_result);
1216 gl.isEnabledi(GL_SCISSOR_TEST, max_viewports - 1);
1217 checkGLError(GL_NO_ERROR, "isEnabledi, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1219 gl.isEnabledi(GL_SCISSOR_TEST, max_viewports);
1220 checkGLError(GL_INVALID_VALUE, "isEnabledi, <index> == GL_MAX_VIEWPORTS", test_result);
1224 * * GetIntegeri_v generates INVALID_VALUE when <target> is SCISSOR_BOX and
1225 * <index> is greater than or equal to the value of MAX_VIEWPORTS;
1230 gl.getIntegeri_v(GL_SCISSOR_BOX, max_viewports - 1, data);
1231 checkGLError(GL_NO_ERROR, "getIntegeri_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1233 gl.getIntegeri_v(GL_SCISSOR_BOX, max_viewports, data);
1234 checkGLError(GL_INVALID_VALUE, "getIntegeri_v, <index> == GL_MAX_VIEWPORTS", test_result);
1238 * * GetFloati_v generates INVALID_VALUE when <target> is VIEWPORT and <index>
1239 * is greater than or equal to the value of MAX_VIEWPORTS;
1244 gl.getFloati_v(GL_VIEWPORT, max_viewports - 1, data);
1245 checkGLError(GL_NO_ERROR, "getFloati_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1247 gl.getFloati_v(GL_VIEWPORT, max_viewports, data);
1248 checkGLError(GL_INVALID_VALUE, "getFloati_v, <index> == GL_MAX_VIEWPORTS", test_result);
1252 * * GetDoublei_v generates INVALID_VALUE when <target> is DEPTH_RANGE and
1253 * <index> is greater than or equal to the value of MAX_VIEWPORTS;
1258 gl.getDoublei_v(GL_DEPTH_RANGE, max_viewports - 1, data);
1259 checkGLError(GL_NO_ERROR, "getDoublei_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1261 gl.getDoublei_v(GL_DEPTH_RANGE, max_viewports, data);
1262 checkGLError(GL_INVALID_VALUE, "getDoublei_v, <index> == GL_MAX_VIEWPORTS", test_result);
1266 if (true == test_result)
1268 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1272 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1276 return tcu::TestNode::STOP;
1279 /** Check if glGetError returns expected error
1281 * @param expected_error Expected error code
1282 * @param description Description of test case
1283 * @param out_result Set to false if the current error is not equal to expected one
1285 void APIErrors::checkGLError(GLenum expected_error, const GLchar* description, bool& out_result)
1287 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1289 GLenum error = gl.getError();
1291 if (expected_error != error)
1293 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case fail. Description: " << description
1294 << " Invalid error: " << glu::getErrorStr(error)
1295 << " expected: " << glu::getErrorStr(expected_error)
1296 << tcu::TestLog::EndMessage;
1304 * @param context Test context
1306 Queries::Queries(deqp::Context& context, const glcts::ExtParameters& extParams)
1307 : TestCaseBase(context, extParams, "queries", "Test verifies initial state of API")
1309 /* Nothing to be done here */
1314 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1316 tcu::TestNode::IterateResult Queries::iterate()
1318 /* GL entry points */
1319 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1322 bool test_result = true;
1324 GLint layer_provoking_vertex = 0;
1325 GLint max_viewports = 0;
1326 GLfloat max_renderbuffer_size = 0.0f;
1327 GLfloat max_viewport_dims[2] = { 0.0f, 0.0f };
1328 GLfloat viewport_bounds_range[2] = { 0.0, 0.0f };
1329 GLint viewport_provoking_vertex = 0;
1330 GLint viewport_subpixel_bits = -1;
1332 gl.getIntegerv(GL_LAYER_PROVOKING_VERTEX, &layer_provoking_vertex);
1333 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1335 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1336 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1338 gl.getFloatv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
1339 GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");
1341 gl.getFloatv(GL_MAX_VIEWPORT_DIMS, max_viewport_dims);
1342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloatv");
1344 gl.getFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewport_bounds_range);
1345 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloatv");
1347 gl.getIntegerv(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, &viewport_provoking_vertex);
1348 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1350 gl.getIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &viewport_subpixel_bits);
1351 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1353 const GLint window_width = m_context.getRenderContext().getRenderTarget().getWidth();
1354 const GLint window_height = m_context.getRenderContext().getRenderTarget().getHeight();
1357 * * Initial dimensions of VIEWPORT returned by GetFloati_v match dimensions of
1358 * the window into which GL is rendering;
1361 std::vector<GLfloat> data;
1362 data.resize(max_viewports * 4 /* x + y + w+ h */);
1364 for (GLint i = 0; i < max_viewports; ++i)
1366 gl.getFloati_v(GL_VIEWPORT, i, &data[i * 4]);
1367 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloati_v");
1370 for (GLint i = 0; i < max_viewports; ++i)
1372 GLint viewport_width = (GLint)data[4 * i + 2];
1373 GLint viewport_height = (GLint)data[4 * i + 3];
1375 if ((window_width != viewport_width) || (window_height != viewport_height))
1377 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial viewport [" << i
1378 << "] dimennsions: " << viewport_width << " x " << viewport_height
1379 << " expected: " << window_width << " x " << window_height
1380 << tcu::TestLog::EndMessage;
1382 test_result = false;
1389 * * Initial values of DEPTH_RANGE returned by GetDoublei_v are [0, 1];
1392 std::vector<GLdouble> data;
1393 data.resize(max_viewports * 2 /* near + far */);
1395 for (GLint i = 0; i < max_viewports; ++i)
1397 gl.getDoublei_v(GL_DEPTH_RANGE, i, &data[i * 2]);
1398 GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublei_v");
1401 for (GLint i = 0; i < max_viewports; ++i)
1403 GLint near = (GLint)data[2 * i + 0];
1404 GLint far = (GLint)data[2 * i + 1];
1406 if ((0.0 != near) || (1.0 != far))
1408 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial depth range [" << i
1409 << "]: " << near << " : " << far << " expected: 0.0 : 1.0"
1410 << tcu::TestLog::EndMessage;
1412 test_result = false;
1419 * * Initial state of SCISSOR_TEST returned by IsEnabledi is FALSE;
1422 for (GLint i = 0; i < max_viewports; ++i)
1424 if (GL_FALSE != gl.isEnabledi(GL_SCISSOR_TEST, i))
1426 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Scissor test is enabled at " << i
1427 << ". Expected disabled." << tcu::TestLog::EndMessage;
1429 test_result = false;
1436 * * Initial dimensions of SCISSOR_BOX returned by GetIntegeri_v are either
1437 * zeros or match dimensions of the window into which GL is rendering;
1440 std::vector<GLint> data;
1441 data.resize(max_viewports * 4 /* x + y + w+ h */);
1443 for (GLint i = 0; i < max_viewports; ++i)
1445 gl.getIntegeri_v(GL_SCISSOR_BOX, i, &data[i * 4]);
1446 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegeri_v");
1449 for (GLint i = 0; i < max_viewports; ++i)
1451 GLint scissor_width = data[4 * i + 2];
1452 GLint scissor_height = data[4 * i + 3];
1454 if ((window_width != scissor_width) || (window_height != scissor_height))
1456 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial scissor box [" << i
1457 << "] dimennsions: " << scissor_width << " x " << scissor_height
1458 << " expected: " << window_width << " x " << window_height
1459 << tcu::TestLog::EndMessage;
1461 test_result = false;
1468 * * Dimensions of MAX_VIEWPORT_DIMS returned by GetFloati_v are at least
1469 * as big as supported dimensions of render buffers, see MAX_RENDERBUFFER_SIZE;
1472 if ((max_viewport_dims[0] < max_renderbuffer_size) || (max_viewport_dims[1] < max_renderbuffer_size))
1474 m_context.getTestContext().getLog()
1475 << tcu::TestLog::Message << "Invalid MAX_VIEWPORT_DIMS: " << max_viewport_dims[0] << " x "
1476 << max_viewport_dims[1] << " expected: " << max_renderbuffer_size << " x " << max_renderbuffer_size
1477 << tcu::TestLog::EndMessage;
1479 test_result = false;
1484 * * Value of MAX_VIEWPORTS returned by GetIntegeri_v is at least 16;
1487 if (16 > max_viewports)
1489 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid MAX_VIEWPORTS: " << max_viewports
1490 << " expected at least 16." << tcu::TestLog::EndMessage;
1492 test_result = false;
1497 * * Value of VIEWPORT_SUBPIXEL_BITS returned by GetIntegeri_v is at least 0;
1500 if (0 > viewport_subpixel_bits)
1502 m_context.getTestContext().getLog() << tcu::TestLog::Message
1503 << "Invalid VIEWPORT_SUBPIXEL_BITS: " << viewport_subpixel_bits
1504 << " expected at least 0." << tcu::TestLog::EndMessage;
1506 test_result = false;
1511 * * Values of VIEWPORT_BOUNDS_RANGE returned by GetFloatv are
1512 * at least [-32768, 32767];
1515 if ((-32768.0f < viewport_bounds_range[0]) || (32767.0f > viewport_bounds_range[1]))
1517 m_context.getTestContext().getLog()
1518 << tcu::TestLog::Message << "Invalid VIEWPORT_BOUNDS_RANGE: " << viewport_bounds_range[0] << " : "
1519 << viewport_bounds_range[1] << " expected at least: -32768.0f : 32767.0f" << tcu::TestLog::EndMessage;
1521 test_result = false;
1526 * * Values of LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
1527 * returned by GetIntegerv are located in the following set
1528 * { FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, PROVOKING_VERTEX,
1529 * UNDEFINED_VERTEX };
1532 switch (layer_provoking_vertex)
1534 case GL_FIRST_VERTEX_CONVENTION:
1535 case GL_LAST_VERTEX_CONVENTION:
1536 case GL_PROVOKING_VERTEX:
1537 case GL_UNDEFINED_VERTEX:
1540 m_context.getTestContext().getLog() << tcu::TestLog::Message
1541 << "Invalid LAYER_PROVOKING_VERTEX: " << layer_provoking_vertex
1542 << tcu::TestLog::EndMessage;
1544 test_result = false;
1547 switch (viewport_provoking_vertex)
1549 case GL_FIRST_VERTEX_CONVENTION:
1550 case GL_LAST_VERTEX_CONVENTION:
1551 case GL_PROVOKING_VERTEX:
1552 case GL_UNDEFINED_VERTEX:
1555 m_context.getTestContext().getLog() << tcu::TestLog::Message
1556 << "Invalid LAYER_PROVOKING_VERTEX: " << layer_provoking_vertex
1557 << tcu::TestLog::EndMessage;
1559 test_result = false;
1564 if (true == test_result)
1566 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1570 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1574 return tcu::TestNode::STOP;
1577 /* Constants used by ViewportAPI */
1578 const GLuint ViewportAPI::m_n_elements = 4;
1582 * @param context Test context
1584 ViewportAPI::ViewportAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
1585 : TestCaseBase(context, extParams, "viewport_api", "Test verifies that \viewport api\" works as expected")
1587 /* Nothing to be done here */
1592 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1594 tcu::TestNode::IterateResult ViewportAPI::iterate()
1596 /* GL entry points */
1597 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1600 bool test_result = true;
1602 GLint max_viewports = 0;
1604 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1605 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1607 std::vector<GLfloat> scissor_box_data_a;
1608 std::vector<GLfloat> scissor_box_data_b;
1610 scissor_box_data_a.resize(max_viewports * m_n_elements);
1611 scissor_box_data_b.resize(max_viewports * m_n_elements);
1614 * - get initial dimensions of VIEWPORT for all MAX_VIEWPORTS indices;
1615 * - change location and dimensions of all indices at once with
1617 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1619 getViewports(max_viewports, scissor_box_data_a);
1621 for (GLint i = 0; i < max_viewports; ++i)
1623 scissor_box_data_a[i * m_n_elements + 0] += 0.125f;
1624 scissor_box_data_a[i * m_n_elements + 1] += 0.125f;
1625 scissor_box_data_a[i * m_n_elements + 2] -= 0.125f;
1626 scissor_box_data_a[i * m_n_elements + 3] -= 0.125f;
1629 gl.viewportArrayv(0, max_viewports, &scissor_box_data_a[0]);
1630 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportArrayv");
1632 getViewports(max_viewports, scissor_box_data_b);
1633 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportArrayv", test_result);
1637 * * modify with ViewportIndexedf,
1638 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1640 for (GLint i = 0; i < max_viewports; ++i)
1642 scissor_box_data_b[i * m_n_elements + 0] = 0.25f;
1643 scissor_box_data_b[i * m_n_elements + 1] = 0.25f;
1644 scissor_box_data_b[i * m_n_elements + 2] = 0.75f;
1645 scissor_box_data_b[i * m_n_elements + 3] = 0.75f;
1647 gl.viewportIndexedf(i, 0.25f, 0.25f, 0.75f, 0.75f);
1648 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportIndexedf");
1650 getViewports(max_viewports, scissor_box_data_a);
1651 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportIndexedf", test_result);
1656 * * modify with ViewportIndexedfv,
1657 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1659 for (GLint i = 0; i < max_viewports; ++i)
1661 scissor_box_data_a[i * m_n_elements + 0] = 0.375f;
1662 scissor_box_data_a[i * m_n_elements + 1] = 0.375f;
1663 scissor_box_data_a[i * m_n_elements + 2] = 0.625f;
1664 scissor_box_data_a[i * m_n_elements + 3] = 0.625f;
1666 gl.viewportIndexedfv(i, &scissor_box_data_a[i * m_n_elements]);
1667 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportIndexedfv");
1669 getViewports(max_viewports, scissor_box_data_b);
1670 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportIndexedfv", test_result);
1675 * * modify all indices before and after current one with ViewportArrayv,
1676 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1678 for (GLint i = 0; i < max_viewports; ++i)
1680 const GLfloat value = (0 == i % 2) ? 1.0f : 0.25f;
1682 for (GLint j = 0; j < i; ++j)
1684 scissor_box_data_b[j * m_n_elements + 0] = value;
1685 scissor_box_data_b[j * m_n_elements + 1] = value;
1686 scissor_box_data_b[j * m_n_elements + 2] = value;
1687 scissor_box_data_b[j * m_n_elements + 3] = value;
1690 for (GLint j = i + 1; j < max_viewports; ++j)
1692 scissor_box_data_b[j * m_n_elements + 0] = value;
1693 scissor_box_data_b[j * m_n_elements + 1] = value;
1694 scissor_box_data_b[j * m_n_elements + 2] = value;
1695 scissor_box_data_b[j * m_n_elements + 3] = value;
1698 gl.viewportArrayv(0, max_viewports, &scissor_box_data_b[0]);
1699 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportArrayv");
1701 getViewports(max_viewports, scissor_box_data_a);
1702 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportArrayv", test_result);
1706 * - change location and dimensions of all indices at once with Viewport;
1707 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1709 for (GLint i = 0; i < max_viewports; ++i)
1711 scissor_box_data_a[i * m_n_elements + 0] = 0.0f;
1712 scissor_box_data_a[i * m_n_elements + 1] = 0.0f;
1713 scissor_box_data_a[i * m_n_elements + 2] = 1.0f;
1714 scissor_box_data_a[i * m_n_elements + 3] = 1.0f;
1717 gl.viewport(0, 0, 1, 1);
1718 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1720 getViewports(max_viewports, scissor_box_data_b);
1721 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewport", test_result);
1724 if (true == test_result)
1726 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1730 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1734 return tcu::TestNode::STOP;
1737 /** Compare two sets of viewport data (simple vector comparison)
1739 * @param left Left set
1740 * @param right Right set
1741 * @param description Test case description
1742 * @param out_result Set to false if sets are different, not modified otherwise
1744 void ViewportAPI::compareViewports(std::vector<GLfloat>& left, std::vector<GLfloat>& right, const GLchar* description,
1747 for (size_t i = 0; i < left.size(); ++i)
1749 if (left[i] != right[i])
1751 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
1752 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
1753 << tcu::TestLog::EndMessage;
1760 /** Get position of all viewports
1762 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
1763 * @param data Memory buffer prepared for captured data
1765 void ViewportAPI::getViewports(GLint max_viewports, std::vector<GLfloat>& out_data)
1767 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1769 for (GLint i = 0; i < max_viewports; ++i)
1771 gl.getFloati_v(GL_VIEWPORT, i, &out_data[i * 4]);
1772 GLU_EXPECT_NO_ERROR(gl.getError(), "getFloati_v");
1776 /* Constants used by ScissorAPI */
1777 const GLuint ScissorAPI::m_n_elements = 4;
1781 * @param context Test context
1783 ScissorAPI::ScissorAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
1784 : TestCaseBase(context, extParams, "scissor_api", "Test verifies that \"scissor api\" works as expected")
1786 /* Nothing to be done here */
1791 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1793 tcu::TestNode::IterateResult ScissorAPI::iterate()
1795 /* GL entry points */
1796 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1799 bool test_result = true;
1801 GLint max_viewports = 0;
1803 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1804 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1806 std::vector<GLint> scissor_box_data_a;
1807 std::vector<GLint> scissor_box_data_b;
1809 scissor_box_data_a.resize(max_viewports * m_n_elements);
1810 scissor_box_data_b.resize(max_viewports * m_n_elements);
1813 * - get initial dimensions of SCISSOR_BOX for all MAX_VIEWPORTS indices;
1814 * - change location and dimensions of all indices at once with
1816 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1818 getScissorBoxes(max_viewports, scissor_box_data_a);
1820 for (GLint i = 0; i < max_viewports; ++i)
1822 scissor_box_data_a[i * m_n_elements + 0] += 1;
1823 scissor_box_data_a[i * m_n_elements + 1] += 1;
1824 scissor_box_data_a[i * m_n_elements + 2] -= 1;
1825 scissor_box_data_a[i * m_n_elements + 3] -= 1;
1828 gl.scissorArrayv(0, max_viewports, &scissor_box_data_a[0]);
1829 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorArrayv");
1831 getScissorBoxes(max_viewports, scissor_box_data_b);
1832 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorArrayv", test_result);
1836 * * modify with ScissorIndexed,
1837 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1839 for (GLint i = 0; i < max_viewports; ++i)
1841 scissor_box_data_b[i * m_n_elements + 0] = 4;
1842 scissor_box_data_b[i * m_n_elements + 1] = 4;
1843 scissor_box_data_b[i * m_n_elements + 2] = 8;
1844 scissor_box_data_b[i * m_n_elements + 3] = 8;
1846 gl.scissorIndexed(i, 4, 4, 8, 8);
1847 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorIndexed");
1849 getScissorBoxes(max_viewports, scissor_box_data_a);
1850 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorIndexed", test_result);
1855 * * modify with ScissorIndexedv,
1856 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1858 for (GLint i = 0; i < max_viewports; ++i)
1860 scissor_box_data_a[i * m_n_elements + 0] = 8;
1861 scissor_box_data_a[i * m_n_elements + 1] = 8;
1862 scissor_box_data_a[i * m_n_elements + 2] = 12;
1863 scissor_box_data_a[i * m_n_elements + 3] = 12;
1865 gl.scissorIndexedv(i, &scissor_box_data_a[i * m_n_elements]);
1866 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorIndexedv");
1868 getScissorBoxes(max_viewports, scissor_box_data_b);
1869 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorIndexedv", test_result);
1874 * * modify all indices before and after current one with ScissorArrayv,
1875 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1877 for (GLint i = 0; i < max_viewports; ++i)
1879 const GLint value = (0 == i % 2) ? 1 : 4;
1881 for (GLint j = 0; j < i; ++j)
1883 scissor_box_data_b[j * m_n_elements + 0] = value;
1884 scissor_box_data_b[j * m_n_elements + 1] = value;
1885 scissor_box_data_b[j * m_n_elements + 2] = value;
1886 scissor_box_data_b[j * m_n_elements + 3] = value;
1889 for (GLint j = i + 1; j < max_viewports; ++j)
1891 scissor_box_data_b[j * m_n_elements + 0] = value;
1892 scissor_box_data_b[j * m_n_elements + 1] = value;
1893 scissor_box_data_b[j * m_n_elements + 2] = value;
1894 scissor_box_data_b[j * m_n_elements + 3] = value;
1897 gl.scissorArrayv(0, max_viewports, &scissor_box_data_b[0]);
1898 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorArrayv");
1900 getScissorBoxes(max_viewports, scissor_box_data_a);
1901 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorArrayv", test_result);
1905 * - change location and dimensions of all indices at once with Scissor;
1906 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1908 for (GLint i = 0; i < max_viewports; ++i)
1910 scissor_box_data_a[i * m_n_elements + 0] = 0;
1911 scissor_box_data_a[i * m_n_elements + 1] = 0;
1912 scissor_box_data_a[i * m_n_elements + 2] = 1;
1913 scissor_box_data_a[i * m_n_elements + 3] = 1;
1916 gl.scissor(0, 0, 1, 1);
1917 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
1919 getScissorBoxes(max_viewports, scissor_box_data_b);
1920 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissor", test_result);
1923 if (true == test_result)
1925 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1929 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1933 return tcu::TestNode::STOP;
1936 /** Compare two sets of scissor box data (simple vector comparison)
1938 * @param left Left set
1939 * @param right Right set
1940 * @param description Test case description
1941 * @param out_result Set to false if sets are different, not modified otherwise
1943 void ScissorAPI::compareScissorBoxes(std::vector<GLint>& left, std::vector<GLint>& right, const GLchar* description,
1946 for (size_t i = 0; i < left.size(); ++i)
1948 if (left[i] != right[i])
1950 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
1951 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
1952 << tcu::TestLog::EndMessage;
1959 /** Get position of all scissor boxes
1961 * @param max_viewports Number of scissor boxes to capture, MAX_VIEWPORTS
1962 * @param data Memory buffer prepared for captured data
1964 void ScissorAPI::getScissorBoxes(GLint max_viewports, std::vector<GLint>& out_data)
1966 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1968 for (GLint i = 0; i < max_viewports; ++i)
1970 gl.getIntegeri_v(GL_SCISSOR_BOX, i, &out_data[i * 4]);
1971 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegeri_v");
1975 /* Constants used by DepthRangeAPI */
1976 const GLuint DepthRangeAPI::m_n_elements = 2 /* near + far */;
1980 * @param context Test context
1982 DepthRangeAPI::DepthRangeAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
1983 : TestCaseBase(context, extParams, "depth_range_api", "Test verifies that \"depth range api\" works as expected")
1985 /* Nothing to be done here */
1990 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1992 tcu::TestNode::IterateResult DepthRangeAPI::iterate()
1994 /* GL entry points */
1995 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1998 bool test_result = true;
2000 GLint max_viewports = 0;
2002 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
2003 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
2005 std::vector<GLdouble> depth_range_data_a;
2006 std::vector<GLdouble> depth_range_data_b;
2008 depth_range_data_a.resize(max_viewports * m_n_elements);
2009 depth_range_data_b.resize(max_viewports * m_n_elements);
2012 * - get initial values of DEPTH_RANGE for all MAX_VIEWPORTS indices;
2013 * - change values of all indices at once with DepthRangeArrayv;
2014 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2016 getDepthRanges(max_viewports, depth_range_data_a);
2018 for (GLint i = 0; i < max_viewports; ++i)
2020 depth_range_data_a[i * m_n_elements + 0] += 0.125;
2021 depth_range_data_a[i * m_n_elements + 1] -= 0.125;
2024 gl.depthRangeArrayv(0, max_viewports, &depth_range_data_a[0]);
2025 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeArrayv");
2027 getDepthRanges(max_viewports, depth_range_data_b);
2028 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeArrayv", test_result);
2032 * * modify with DepthRangeIndexed,
2033 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2035 for (GLint i = 0; i < max_viewports; ++i)
2037 depth_range_data_b[i * m_n_elements + 0] = 0.25;
2038 depth_range_data_b[i * m_n_elements + 1] = 0.75;
2040 gl.depthRangeIndexed(i, 0.25f, 0.75f);
2041 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeIndexed");
2043 getDepthRanges(max_viewports, depth_range_data_a);
2044 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeIndexed", test_result);
2049 * * modify all indices before and after current one with DepthRangeArrayv,
2050 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2052 for (GLint i = 0; i < max_viewports; ++i)
2054 const GLdouble value = (0 == i % 2) ? 1.0 : 0.25;
2056 for (GLint j = 0; j < i; ++j)
2058 depth_range_data_b[j * m_n_elements + 0] = value;
2059 depth_range_data_b[j * m_n_elements + 1] = value;
2062 for (GLint j = i + 1; j < max_viewports; ++j)
2064 depth_range_data_b[j * m_n_elements + 0] = value;
2065 depth_range_data_b[j * m_n_elements + 1] = value;
2068 gl.depthRangeArrayv(0, max_viewports, &depth_range_data_b[0]);
2069 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeArrayv");
2071 getDepthRanges(max_viewports, depth_range_data_a);
2072 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeArrayv", test_result);
2076 * - change values of all indices at once with DepthRange;
2077 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2079 for (GLint i = 0; i < max_viewports; ++i)
2081 depth_range_data_a[i * m_n_elements + 0] = 0.0f;
2082 depth_range_data_a[i * m_n_elements + 1] = 1.0f;
2085 gl.depthRange(0.0, 1.0);
2086 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRange");
2088 getDepthRanges(max_viewports, depth_range_data_b);
2089 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRange", test_result);
2092 if (true == test_result)
2094 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2098 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2102 return tcu::TestNode::STOP;
2105 /** Compare two sets of depth range data (simple vector comparison)
2107 * @param left Left set
2108 * @param right Right set
2109 * @param description Test case description
2110 * @param out_result Set to false if sets are different, not modified otherwise
2112 void DepthRangeAPI::compareDepthRanges(std::vector<GLdouble>& left, std::vector<GLdouble>& right,
2113 const GLchar* description, bool& out_result)
2115 for (size_t i = 0; i < left.size(); ++i)
2117 if (left[i] != right[i])
2119 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
2120 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
2121 << tcu::TestLog::EndMessage;
2128 /** Get all depth ranges
2130 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
2131 * @param data Memory buffer prepared for captured data
2133 void DepthRangeAPI::getDepthRanges(GLint max_viewports, std::vector<GLdouble>& out_data)
2135 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2137 for (GLint i = 0; i < max_viewports; ++i)
2139 gl.getDoublei_v(GL_DEPTH_RANGE, i, &out_data[i * m_n_elements]);
2140 GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublei_v");
2146 * @param context Test context
2148 ScissorTestStateAPI::ScissorTestStateAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
2149 : TestCaseBase(context, extParams, "scissor_test_state_api",
2150 "Test verifies that \"enable/disable api\" works as expected for scissor test")
2152 /* Nothing to be done here */
2157 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
2159 tcu::TestNode::IterateResult ScissorTestStateAPI::iterate()
2161 /* GL entry points */
2162 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2165 bool test_result = true;
2167 GLint max_viewports = 0;
2169 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
2170 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
2172 std::vector<GLboolean> scissor_test_states_a;
2173 std::vector<GLboolean> scissor_test_states_b;
2175 scissor_test_states_a.resize(max_viewports);
2176 scissor_test_states_b.resize(max_viewports);
2179 * - get initial state of SCISSOR_TEST for all MAX_VIEWPORTS indices;
2181 * * toggle SCISSOR_TEST,
2182 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2184 * * toggle SCISSOR_TEST,
2185 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2187 getScissorTestStates(max_viewports, scissor_test_states_a);
2189 for (GLint i = 0; i < max_viewports; ++i)
2191 if (GL_FALSE == scissor_test_states_a[i])
2193 gl.enablei(GL_SCISSOR_TEST, i);
2194 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
2196 scissor_test_states_a[i] = GL_TRUE;
2200 gl.disablei(GL_SCISSOR_TEST, i);
2201 GLU_EXPECT_NO_ERROR(gl.getError(), "Disablei");
2203 scissor_test_states_a[i] = GL_FALSE;
2206 getScissorTestStates(max_viewports, scissor_test_states_b);
2207 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "1st toggle", test_result);
2210 for (GLint i = 0; i < max_viewports; ++i)
2212 if (GL_FALSE == scissor_test_states_a[i])
2214 gl.enablei(GL_SCISSOR_TEST, i);
2215 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
2217 scissor_test_states_a[i] = GL_TRUE;
2221 gl.disablei(GL_SCISSOR_TEST, i);
2222 GLU_EXPECT_NO_ERROR(gl.getError(), "Disablei");
2224 scissor_test_states_a[i] = GL_FALSE;
2227 getScissorTestStates(max_viewports, scissor_test_states_b);
2228 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "2nd toggle", test_result);
2232 * - enable SCISSOR_TEST for all indices at once with Enable;
2233 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2235 for (GLint i = 0; i < max_viewports; ++i)
2237 scissor_test_states_a[i] = GL_TRUE;
2240 gl.enable(GL_SCISSOR_TEST);
2241 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
2243 getScissorTestStates(max_viewports, scissor_test_states_b);
2244 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "1st enable all", test_result);
2247 * - disable SCISSOR_TEST for all indices at once with Disable;
2248 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2250 for (GLint i = 0; i < max_viewports; ++i)
2252 scissor_test_states_a[i] = GL_FALSE;
2255 gl.disable(GL_SCISSOR_TEST);
2256 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
2258 getScissorTestStates(max_viewports, scissor_test_states_b);
2259 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "Disable all", test_result);
2262 * - enable SCISSOR_TEST for all indices at once with Enable;
2263 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2265 for (GLint i = 0; i < max_viewports; ++i)
2267 scissor_test_states_a[i] = GL_TRUE;
2270 gl.enable(GL_SCISSOR_TEST);
2271 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
2273 getScissorTestStates(max_viewports, scissor_test_states_b);
2274 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "2nd enable all", test_result);
2277 if (true == test_result)
2279 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2283 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2287 return tcu::TestNode::STOP;
2290 /** Compare two sets of depth range data (simple vector comparison)
2292 * @param left Left set
2293 * @param right Right set
2294 * @param description Test case description
2295 * @param out_result Set to false if sets are different, not modified otherwise
2297 void ScissorTestStateAPI::compareScissorTestStates(std::vector<GLboolean>& left, std::vector<GLboolean>& right,
2298 const GLchar* description, bool& out_result)
2300 for (size_t i = 0; i < left.size(); ++i)
2302 if (left[i] != right[i])
2304 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
2305 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
2306 << tcu::TestLog::EndMessage;
2313 /** Get all depth ranges
2315 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
2316 * @param data Memory buffer prepared for captured data
2318 void ScissorTestStateAPI::getScissorTestStates(GLint max_viewports, std::vector<GLboolean>& out_data)
2320 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2322 for (GLint i = 0; i < max_viewports; ++i)
2324 out_data[i] = gl.isEnabledi(GL_SCISSOR_TEST, i);
2325 GLU_EXPECT_NO_ERROR(gl.getError(), "isEnabledi");
2329 /* Constants used by DrawTestBase */
2330 const GLuint DrawTestBase::m_depth = 16;
2331 const GLuint DrawTestBase::m_height = 128;
2332 const GLuint DrawTestBase::m_width = 128;
2333 const GLuint DrawTestBase::m_r32f_height = 2;
2334 const GLuint DrawTestBase::m_r32f_width = 16;
2335 const GLuint DrawTestBase::m_r32ix4_depth = 4;
2339 * @param context Test context
2340 * @param test_name Test name
2341 * @param test_description Test description
2343 DrawTestBase::DrawTestBase(deqp::Context& context, const glcts::ExtParameters& extParams, const GLchar* test_name,
2344 const GLchar* test_description)
2345 : TestCaseBase(context, extParams, test_name, test_description)
2347 /* Nothing to be done here */
2352 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
2354 tcu::TestNode::IterateResult DrawTestBase::iterate()
2356 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2359 bool test_result = true;
2361 /* Get type of test */
2362 const TEST_TYPE test_type = getTestType();
2364 GLuint n_draw_calls = getDrawCallsNumber();
2365 GLuint n_iterations = 0;
2377 TCU_FAIL("Invalid enum");
2380 /* Get shader sources */
2381 const std::string& fragment = getFragmentShader();
2382 const std::string& geometry = getGeometryShader();
2383 const std::string& vertex = getVertexShader();
2385 /* Prepare program */
2386 Utils::program program(m_context);
2390 program.build(0 /* compute */, fragment.c_str(), geometry.c_str(), 0 /* tess ctrl */, 0 /* tess eval */,
2391 vertex.c_str(), 0 /* varying names */, 0 /* n_varyings */);
2393 catch (Utils::shaderCompilationException& exc)
2395 /* Something wrong with compilation, test case failed */
2396 tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
2398 message << "Shader compilation failed. Error message: " << exc.m_error_message;
2400 Utils::program::printShaderSource(exc.m_shader_source.c_str(), message);
2402 message << tcu::TestLog::EndMessage;
2404 TCU_FAIL("Shader compilation failed");
2406 catch (Utils::programLinkageException& exc)
2408 /* Something wrong with linking, test case failed */
2409 m_context.getTestContext().getLog() << tcu::TestLog::Message
2410 << "Program linking failed. Error message: " << exc.m_error_message
2411 << tcu::TestLog::EndMessage;
2412 TCU_FAIL("Program linking failed");
2418 Utils::vertexArray vao(m_context);
2422 /* For each iteration from test type */
2423 for (GLuint i = 0; i < n_iterations; ++i)
2425 /* Prepare textures */
2426 Utils::texture texture_0(m_context);
2427 Utils::texture texture_1(m_context);
2429 prepareTextures(texture_0, texture_1);
2431 /* Prepare framebuffer */
2432 Utils::framebuffer framebuffer(m_context);
2433 framebuffer.generate();
2434 setupFramebuffer(framebuffer, texture_0, texture_1);
2437 /* Set up viewports */
2438 setupViewports(test_type, i);
2440 if (false == isClearTest())
2442 /* For each draw call */
2443 for (GLuint draw_call = 0; draw_call < n_draw_calls; ++draw_call)
2445 prepareUniforms(program, draw_call);
2448 GLdouble depth_value;
2450 getClearSettings(is_clear, draw_call, depth_value);
2452 if (true == is_clear)
2454 gl.clearDepth(depth_value);
2455 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearDepth");
2457 gl.clear(GL_DEPTH_BUFFER_BIT);
2458 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2461 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
2462 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2464 bool result = checkResults(texture_0, texture_1, draw_call);
2466 if (false == result)
2468 test_result = false;
2475 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
2476 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2478 gl.clear(GL_COLOR_BUFFER_BIT);
2479 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2481 bool result = checkResults(texture_0, texture_1, 0);
2483 if (false == result)
2485 test_result = false;
2493 if (true == test_result)
2495 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2499 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2503 return tcu::TestNode::STOP;
2506 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
2508 * @param texture_0 Verified texture
2512 * @return True if texture_0 is filled with expected pattern
2514 bool DrawTestBase::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
2516 bool check_result = true;
2519 std::vector<GLint> texture_data;
2520 texture_data.resize(m_width * m_height);
2521 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
2523 for (GLuint y = 0; y < 4; ++y)
2525 for (GLuint x = 0; x < 4; ++x)
2527 bool result = checkRegionR32I(x, y, index, &texture_data[0]);
2529 if (false == result)
2531 check_result = false;
2540 return check_result;
2543 /** Get settings of clear operation
2545 * @param clear_depth_before_draw Selects if clear depth should be executed before draw.
2549 void DrawTestBase::getClearSettings(bool& clear_depth_before_draw, GLuint /* iteration_index */,
2550 GLdouble& /* depth_value */)
2552 clear_depth_before_draw = false;
2555 /** Get number of draw call to be executed during test
2559 GLuint DrawTestBase::getDrawCallsNumber()
2568 DrawTestBase::TEST_TYPE DrawTestBase::getTestType()
2573 /** Selects if test should do draw or clear operation
2575 * @return false - draw operation
2577 bool DrawTestBase::isClearTest()
2582 /** Prepare textures used as framebuffer's attachments for current draw call
2584 * @param texture_0 R32I texture
2587 void DrawTestBase::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
2589 prepareTextureR32I(texture_0);
2592 /** Prepare uniforms for given draw call
2597 void DrawTestBase::prepareUniforms(Utils::program& /* program */, GLuint /* draw_call_index */)
2602 /** Attach textures to framebuffer
2604 * @param framebuffer Framebuffer instance
2605 * @param texture_0 Texture attached as color 0
2608 void DrawTestBase::setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
2609 Utils::texture& /* texture_1 */)
2611 framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, texture_0.m_id, m_width, m_height);
2614 /** Check if region specified with <x and <y> is filled with expected value.
2615 * Note: there is assumption that there are 4x4 regions
2617 * @param x X coordinate of region
2618 * @param y Y coordinate of region
2619 * @param expected_value Expected value
2620 * @param data Texture data (not region, but whole texture)
2622 * @return True if region is filled with <expected_value>, false otherwise
2624 bool DrawTestBase::checkRegionR32I(GLuint x, GLuint y, GLint expected_value, GLint* data)
2626 static GLuint width = m_width / 4;
2627 static GLuint height = m_height / 4;
2629 return checkRegionR32I(x, y, width, height, expected_value, data);
2632 /** Check if region specified with <x and <y> is filled with expected value.
2633 * Note: there is assumption that there are 4x4 regions
2635 * @param x X coordinate of region
2636 * @param y Y coordinate of region
2637 * @param width Width of region
2638 * @param height Height of region
2639 * @param expected_value Expected value
2640 * @param data Texture data (not region, but whole texture)
2642 * @return True if region is filled with <expected_value>, false otherwise
2644 bool DrawTestBase::checkRegionR32I(GLuint x, GLuint y, GLuint width, GLuint height, GLint expected_value, GLint* data)
2648 const GLuint offset = (y * height * m_width) + (x * width);
2650 for (GLuint line = 0; line < height; ++line)
2652 const GLuint line_offset = offset + line * m_width;
2654 for (GLuint texel = 0; texel < width; ++texel)
2656 const GLuint texel_offset = line_offset + texel;
2658 const GLint value = data[texel_offset];
2660 if (expected_value != value)
2662 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid result. Region (" << x << "x"
2663 << y << "). Expected: " << expected_value << " got " << value
2664 << tcu::TestLog::EndMessage;
2676 /** Return boiler-plate vertex shader
2678 * @return Source code of vertex shader
2680 std::string DrawTestBase::getVertexShader()
2682 static const GLchar* source = "#version 410 core\n"
2690 std::string result = source;
2695 /** Set up viewports
2697 * @param type Type of test
2698 * @param iteration_index Index of iteration for given test type
2700 void DrawTestBase::setupViewports(TEST_TYPE type, GLuint iteration_index)
2706 VIEWPORT_METHOD method;
2707 switch (iteration_index)
2712 method = (VIEWPORT_METHOD)iteration_index;
2715 TCU_FAIL("Invalid value");
2717 setup4x4Viewport(method);
2722 SCISSOR_METHOD method;
2723 switch (iteration_index)
2728 method = (SCISSOR_METHOD)iteration_index;
2731 TCU_FAIL("Invalid value");
2733 setup4x4Scissor(method, false /* set_zeros */);
2738 DEPTH_RANGE_METHOD method;
2739 switch (iteration_index)
2743 method = (DEPTH_RANGE_METHOD)iteration_index;
2746 TCU_FAIL("Invalid value");
2748 setup16x2Depths(method);
2753 PROVOKING_VERTEX provoking;
2754 switch (iteration_index)
2758 provoking = (PROVOKING_VERTEX)iteration_index;
2761 TCU_FAIL("Invalid value");
2763 setup2x2Viewport(provoking);
2767 TCU_FAIL("Invalid enum");
2771 /** Prepare R32I texture filled with value -1
2773 * @param texture Texture instance
2775 void DrawTestBase::prepareTextureR32I(Utils::texture& texture)
2777 static const GLuint size = m_width * m_height;
2780 for (GLuint i = 0; i < size; ++i)
2785 texture.create(m_width, m_height, GL_R32I);
2786 texture.update(m_width, m_height, 0 /* depth */, GL_RED_INTEGER, GL_INT, data);
2789 /** Prepare R32I array texture filled with value -1, 4 layers
2791 * @param texture Texture instance
2793 void DrawTestBase::prepareTextureR32Ix4(Utils::texture& texture)
2795 static const GLuint size = m_width * m_height * m_r32ix4_depth;
2797 std::vector<GLint> data;
2800 for (GLuint i = 0; i < size; ++i)
2805 texture.create(m_width, m_height, m_r32ix4_depth, GL_R32I);
2806 texture.update(m_width, m_height, m_r32ix4_depth, GL_RED_INTEGER, GL_INT, &data[0]);
2809 /** Prepare R32I array texture filled with value -1
2811 * @param texture Texture instance
2813 void DrawTestBase::prepareTextureArrayR32I(Utils::texture& texture)
2815 static const GLuint size = m_width * m_height * m_depth;
2817 std::vector<GLint> data;
2820 for (GLuint i = 0; i < size; ++i)
2825 texture.create(m_width, m_height, m_depth, GL_R32I);
2826 texture.update(m_width, m_height, m_depth, GL_RED_INTEGER, GL_INT, &data[0]);
2829 /** Prepare R32F texture filled with value -1
2831 * @param texture Texture instance
2833 void DrawTestBase::prepareTextureR32F(Utils::texture& texture)
2835 static const GLuint size = m_r32f_width * m_r32f_height;
2838 for (GLuint i = 0; i < size; ++i)
2843 texture.create(m_r32f_width, m_r32f_height, GL_R32F);
2844 texture.update(m_r32f_width, m_r32f_height, 0 /* depth */, GL_RED, GL_FLOAT, data);
2847 /** Prepare D32F texture filled with value -1
2849 * @param texture Texture instance
2851 void DrawTestBase::prepareTextureD32F(Utils::texture& texture)
2853 static const GLuint size = m_width * m_height;
2856 for (GLuint i = 0; i < size; ++i)
2861 texture.create(m_width, m_height, GL_DEPTH_COMPONENT32F);
2862 texture.update(m_width, m_height, 0 /* depth */, GL_DEPTH_COMPONENT, GL_FLOAT, data);
2865 /** Set up 16 viewports and depth ranges horizontally
2867 * @param method Method used to set depth ranges
2869 void DrawTestBase::setup16x2Depths(DEPTH_RANGE_METHOD method)
2871 static const GLdouble step = 1.0 / 16.0;
2873 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2875 GLdouble depth_data[16 * 2];
2876 GLfloat viewport_data[16 * 4];
2878 for (GLuint i = 0; i < 16; ++i)
2880 const GLdouble near = step * (GLdouble)i;
2882 depth_data[i * 2 + 0] = near;
2883 depth_data[i * 2 + 1] = 1.0 - near;
2885 viewport_data[i * 4 + 0] = (GLfloat)i;
2886 viewport_data[i * 4 + 1] = 0.0f;
2887 viewport_data[i * 4 + 2] = 1.0f;
2888 viewport_data[i * 4 + 3] = 2.0f;
2891 gl.viewportArrayv(0 /* first */, 16 /* count */, viewport_data);
2892 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
2896 case DEPTHRANGEINDEXED:
2897 for (GLuint i = 0; i < 16; ++i)
2899 gl.depthRangeIndexed(i, depth_data[i * 2 + 0], depth_data[i * 2 + 1]);
2900 GLU_EXPECT_NO_ERROR(gl.getError(), "DepthRangeIndexed");
2904 case DEPTHRANGEARRAYV:
2905 gl.depthRangeArrayv(0 /* first */, 16 /* count */, depth_data);
2906 GLU_EXPECT_NO_ERROR(gl.getError(), "DepthRangeArrayv");
2910 TCU_FAIL("Invalid enum");
2914 /** Set up 4x4 scissor boxes with enabled test
2916 * @param method Method used to set scissor boxes
2917 * @param set_zeros Select if width and height should be 0 or image_dim / 4
2919 void DrawTestBase::setup4x4Scissor(SCISSOR_METHOD method, bool set_zeros)
2921 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2923 for (GLuint i = 0; i < 16; ++i)
2925 gl.enablei(GL_SCISSOR_TEST, i);
2926 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
2930 GLint data[16 * 4 /* 4x4 * (x + y + w + h) */];
2932 GLint width = m_width / 4;
2933 GLint height = m_height / 4;
2935 for (GLuint y = 0; y < 4; ++y)
2937 for (GLuint x = 0; x < 4; ++x)
2939 data[index * 4 + 0] = x * width;
2940 data[index * 4 + 1] = y * height;
2941 if (false == set_zeros)
2943 data[index * 4 + 2] = width;
2944 data[index * 4 + 3] = height;
2948 data[index * 4 + 2] = 0;
2949 data[index * 4 + 3] = 0;
2959 gl.scissorArrayv(0 /* first */, 16 /*count */, data);
2960 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorArrayv");
2962 case SCISSORINDEXEDF:
2963 for (GLuint i = 0; i < 16; ++i)
2965 const GLint x = data[i * 4 + 0];
2966 const GLint y = data[i * 4 + 1];
2967 const GLint w = data[i * 4 + 2];
2968 const GLint h = data[i * 4 + 3];
2970 gl.scissorIndexed(i, x, y, w, h);
2971 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorIndexed");
2974 case SCISSORINDEXEDF_V:
2975 for (GLuint i = 0; i < 16; ++i)
2977 gl.scissorIndexedv(i, &data[i * 4]);
2978 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorIndexedv");
2982 TCU_FAIL("Invalid enum");
2986 /** Set up 4x4 viewports
2988 * @param method Method used to set viewports
2990 void DrawTestBase::setup4x4Viewport(VIEWPORT_METHOD method)
2992 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2995 GLfloat data[16 * 4 /* 4x4 * (x + y + w + h) */];
2997 GLfloat width = (GLfloat)(m_width / 4);
2998 GLfloat height = (GLfloat)(m_height / 4);
3000 for (GLuint y = 0; y < 4; ++y)
3002 for (GLuint x = 0; x < 4; ++x)
3004 data[index * 4 + 0] = (GLfloat)((GLfloat)x * width);
3005 data[index * 4 + 1] = (GLfloat)((GLfloat)y * height);
3006 data[index * 4 + 2] = width;
3007 data[index * 4 + 3] = height;
3015 case VIEWPORTARRAYV:
3016 gl.viewportArrayv(0 /* first */, 16 /*count */, data);
3017 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3019 case VIEWPORTINDEXEDF:
3020 for (GLuint i = 0; i < 16; ++i)
3022 const GLfloat x = data[i * 4 + 0];
3023 const GLfloat y = data[i * 4 + 1];
3024 const GLfloat w = data[i * 4 + 2];
3025 const GLfloat h = data[i * 4 + 3];
3027 gl.viewportIndexedf(i, x, y, w, h);
3028 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3031 case VIEWPORTINDEXEDF_V:
3032 for (GLuint i = 0; i < 16; ++i)
3034 gl.viewportIndexedfv(i, &data[i * 4]);
3035 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3039 TCU_FAIL("Invalid enum");
3043 /** Set up 4x4 viewports
3045 * @param method Method used to set viewports
3047 void DrawTestBase::setup2x2Viewport(PROVOKING_VERTEX provoking)
3049 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3052 GLfloat data[4 * 4 /* 4x4 * (x + y + w + h) */];
3054 GLfloat width = (GLfloat)(m_width / 2);
3055 GLfloat height = (GLfloat)(m_height / 2);
3057 for (GLuint y = 0; y < 2; ++y)
3059 for (GLuint x = 0; x < 2; ++x)
3061 data[index * 4 + 0] = (GLfloat)((GLfloat)x * width);
3062 data[index * 4 + 1] = (GLfloat)((GLfloat)y * height);
3063 data[index * 4 + 2] = width;
3064 data[index * 4 + 3] = height;
3070 gl.viewportArrayv(0 /* first */, 4 /*count */, data);
3071 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3077 mode = GL_FIRST_VERTEX_CONVENTION;
3080 mode = GL_LAST_VERTEX_CONVENTION;
3083 TCU_FAIL("Invalid enum");
3086 gl.provokingVertex(mode);
3087 GLU_EXPECT_NO_ERROR(gl.getError(), "ProvokingVertex");
3092 * @param context Test context
3094 DrawToSingleLayerWithMultipleViewports::DrawToSingleLayerWithMultipleViewports(deqp::Context& context,
3095 const glcts::ExtParameters& extParams)
3096 : DrawTestBase(context, extParams, "draw_to_single_layer_with_multiple_viewports",
3097 "Test verifies that multiple viewports can be used to draw to single layer")
3099 /* Nothing to be done here */
3102 /** Get string with fragment shader source code
3104 * @return Fragment shader source
3106 std::string DrawToSingleLayerWithMultipleViewports::getFragmentShader()
3108 static const GLchar* source = "#version 410 core\n"
3110 "flat in int gs_fs_color;\n"
3111 " out int fs_out_color;\n"
3115 " fs_out_color = gs_fs_color;\n"
3119 std::string result = source;
3124 /** Get string with geometry shader source code
3126 * @return Geometry shader source
3128 std::string DrawToSingleLayerWithMultipleViewports::getGeometryShader()
3130 static const GLchar* source = "#version 410 core\n"
3132 "layout(points, invocations = 16) in;\n"
3133 "layout(triangle_strip, max_vertices = 4) out;\n"
3135 "flat out int gs_fs_color;\n"
3139 " gs_fs_color = gl_InvocationID;\n"
3140 " gl_ViewportIndex = gl_InvocationID;\n"
3141 " gl_Position = vec4(-1, -1, 0, 1);\n"
3143 " gs_fs_color = gl_InvocationID;\n"
3144 " gl_ViewportIndex = gl_InvocationID;\n"
3145 " gl_Position = vec4(-1, 1, 0, 1);\n"
3147 " gs_fs_color = gl_InvocationID;\n"
3148 " gl_ViewportIndex = gl_InvocationID;\n"
3149 " gl_Position = vec4(1, -1, 0, 1);\n"
3151 " gs_fs_color = gl_InvocationID;\n"
3152 " gl_ViewportIndex = gl_InvocationID;\n"
3153 " gl_Position = vec4(1, 1, 0, 1);\n"
3158 std::string result = source;
3165 * @param context Test context
3167 DynamicViewportIndex::DynamicViewportIndex(deqp::Context& context, const glcts::ExtParameters& extParams)
3168 : DrawTestBase(context, extParams, "dynamic_viewport_index",
3169 "Test verifies that gl_ViewportIndex can be assigned with dynamic value")
3171 /* Nothing to be done here */
3174 /** Get string with fragment shader source code
3176 * @return Fragment shader source
3178 std::string DynamicViewportIndex::getFragmentShader()
3180 static const GLchar* source = "#version 410 core\n"
3182 "flat in int gs_fs_color;\n"
3183 " out int fs_out_color;\n"
3187 " fs_out_color = gs_fs_color;\n"
3191 std::string result = source;
3196 /** Get string with geometry shader source code
3198 * @return Geometry shader source
3200 std::string DynamicViewportIndex::getGeometryShader()
3202 static const GLchar* source = "#version 410 core\n"
3204 "layout(points, invocations = 1) in;\n"
3205 "layout(triangle_strip, max_vertices = 4) out;\n"
3207 "uniform int uni_index;\n"
3209 "flat out int gs_fs_color;\n"
3213 " gs_fs_color = uni_index;\n"
3214 " gl_ViewportIndex = uni_index;\n"
3215 " gl_Position = vec4(-1, -1, 0, 1);\n"
3217 " gs_fs_color = uni_index;\n"
3218 " gl_ViewportIndex = uni_index;\n"
3219 " gl_Position = vec4(-1, 1, 0, 1);\n"
3221 " gs_fs_color = uni_index;\n"
3222 " gl_ViewportIndex = uni_index;\n"
3223 " gl_Position = vec4(1, -1, 0, 1);\n"
3225 " gs_fs_color = uni_index;\n"
3226 " gl_ViewportIndex = uni_index;\n"
3227 " gl_Position = vec4(1, 1, 0, 1);\n"
3232 std::string result = source;
3237 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3239 * @param texture_0 Verified texture
3241 * @param draw_call_index Draw call that was executed
3243 * @return True if texture_0 is filled with expected pattern
3245 bool DynamicViewportIndex::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3246 GLuint draw_call_index)
3248 bool check_result = true;
3251 std::vector<GLint> texture_data;
3252 texture_data.resize(m_width * m_height);
3253 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3255 for (GLuint y = 0; y < 4; ++y)
3257 for (GLuint x = 0; x < 4; ++x)
3259 GLint expected_value = -1;
3260 if (index <= draw_call_index)
3262 expected_value = index;
3265 bool result = checkRegionR32I(x, y, expected_value, &texture_data[0]);
3267 if (false == result)
3269 check_result = false;
3278 return check_result;
3281 /** Get number of draw call to be executed during test
3285 GLuint DynamicViewportIndex::getDrawCallsNumber()
3290 /** Prepare uniforms for given draw call
3292 * @param program Program object
3293 * @param draw_call_index Index of draw call to be executed
3295 void DynamicViewportIndex::prepareUniforms(Utils::program& program, GLuint draw_call_index)
3297 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3299 GLint location = program.getUniformLocation("uni_index");
3301 gl.uniform1i(location, (GLint)draw_call_index);
3302 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3307 * @param context Test context
3309 DrawMulitpleViewportsWithSingleInvocation::DrawMulitpleViewportsWithSingleInvocation(
3310 deqp::Context& context, const glcts::ExtParameters& extParams)
3311 : DrawTestBase(context, extParams, "draw_mulitple_viewports_with_single_invocation",
3312 "Test verifies that single invocation can output to multiple viewports")
3314 /* Nothing to be done here */
3317 /** Get string with fragment shader source code
3319 * @return Fragment shader source
3321 std::string DrawMulitpleViewportsWithSingleInvocation::getFragmentShader()
3323 static const GLchar* source = "#version 410 core\n"
3325 "flat in int gs_fs_color;\n"
3326 " out int fs_out_color;\n"
3330 " fs_out_color = gs_fs_color;\n"
3334 std::string result = source;
3339 /** Get string with geometry shader source code
3341 * @return Geometry shader source
3343 std::string DrawMulitpleViewportsWithSingleInvocation::getGeometryShader()
3345 static const GLchar* source = "#version 410 core\n"
3347 "layout(points, invocations = 1) in;\n"
3348 "layout(triangle_strip, max_vertices = 64) out;\n"
3350 "flat out int gs_fs_color;\n"
3352 "void routine(int index)\n"
3354 " gs_fs_color = index;\n"
3355 " gl_ViewportIndex = index;\n"
3356 " gl_Position = vec4(-1, -1, 0, 1);\n"
3358 " gs_fs_color = index;\n"
3359 " gl_ViewportIndex = index;\n"
3360 " gl_Position = vec4(-1, 1, 0, 1);\n"
3362 " gs_fs_color = index;\n"
3363 " gl_ViewportIndex = index;\n"
3364 " gl_Position = vec4(1, -1, 0, 1);\n"
3366 " gs_fs_color = index;\n"
3367 " gl_ViewportIndex = index;\n"
3368 " gl_Position = vec4(1, 1, 0, 1);\n"
3370 " EndPrimitive();\n"
3375 " for(int i = 0; i < 16; ++i)\n"
3382 std::string result = source;
3389 * @param context Test context
3391 ViewportIndexSubroutine::ViewportIndexSubroutine(deqp::Context& context, const glcts::ExtParameters& extParams)
3392 : DrawTestBase(context, extParams, "viewport_index_subroutine",
3393 "Test verifies subroutines can be used to output data to specific viewport")
3395 /* Nothing to be done here */
3398 /** Get string with fragment shader source code
3400 * @return Fragment shader source
3402 std::string ViewportIndexSubroutine::getFragmentShader()
3404 static const GLchar* source = "#version 410 core\n"
3406 "flat in int gs_fs_color;\n"
3407 " out int fs_out_color;\n"
3411 " fs_out_color = gs_fs_color;\n"
3415 std::string result = source;
3420 /** Get string with geometry shader source code
3422 * @return Geometry shader source
3424 std::string ViewportIndexSubroutine::getGeometryShader()
3426 static const GLchar* source = "#version 410 core\n"
3428 "layout(points, invocations = 1) in;\n"
3429 "layout(triangle_strip, max_vertices = 4) out;\n"
3431 "flat out int gs_fs_color;\n"
3433 "subroutine void indexSetter(void);\n"
3435 "subroutine(indexSetter) void four()\n"
3437 " gs_fs_color = 4;\n"
3438 " gl_ViewportIndex = 4;\n"
3441 "subroutine(indexSetter) void five()\n"
3443 " gs_fs_color = 5;\n"
3444 " gl_ViewportIndex = 5;\n"
3447 "subroutine uniform indexSetter routine;\n"
3452 " gl_Position = vec4(-1, -1, 0, 1);\n"
3455 " gl_Position = vec4(-1, 1, 0, 1);\n"
3458 " gl_Position = vec4(1, -1, 0, 1);\n"
3461 " gl_Position = vec4(1, 1, 0, 1);\n"
3466 std::string result = source;
3471 /** Check if R32I texture is filled with two halves, left is 4, right is either -1 or 5
3473 * @param texture_0 Verified texture
3475 * @param draw_call_index Draw call that was executed
3477 * @return True if texture_0 is filled with expected pattern
3479 bool ViewportIndexSubroutine::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3480 GLuint draw_call_index)
3482 bool check_result = true;
3484 std::vector<GLint> texture_data;
3485 texture_data.resize(m_width * m_height);
3486 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3488 /* Left is 4 and right is -1, or left is 4 and right is 5 */
3489 GLint expected_left = 4;
3490 GLint expected_right = (1 == draw_call_index) ? 5 : -1;
3492 for (GLuint y = 0; y < 4; ++y)
3494 for (GLuint x = 0; x < 2; ++x)
3496 bool result = checkRegionR32I(x, y, expected_left, &texture_data[0]);
3498 if (false == result)
3500 check_result = false;
3506 for (GLuint y = 0; y < 4; ++y)
3508 for (GLuint x = 2; x < 4; ++x)
3510 bool result = checkRegionR32I(x, y, expected_right, &texture_data[0]);
3512 if (false == result)
3514 check_result = false;
3521 return check_result;
3524 /** Get number of draw call to be executed during test
3528 GLuint ViewportIndexSubroutine::getDrawCallsNumber()
3533 /** Prepare uniforms for given draw call
3535 * @param program Program object
3536 * @param draw_call_index Index of draw call to be executed
3538 void ViewportIndexSubroutine::prepareUniforms(Utils::program& program, GLuint draw_call_index)
3540 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3542 const GLchar* subroutine_name = (0 == draw_call_index) ? "four" : "five";
3544 GLint location = program.getSubroutineUniformLocation("routine", GL_GEOMETRY_SHADER);
3545 GLuint index = program.getSubroutineIndex(subroutine_name, GL_GEOMETRY_SHADER);
3549 TCU_FAIL("Something wrong, subroutine uniform location is not 0. Mistake in geometry shader?");
3552 gl.uniformSubroutinesuiv(GL_GEOMETRY_SHADER, 1, &index);
3553 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
3556 /** Set 4th viewport on left half and 5 on right half of framebuffer. Rest span over whole image.
3559 * @param iteration_index Index of iteration, used to select "viewport" method
3561 void ViewportIndexSubroutine::setupViewports(TEST_TYPE /* type */, glw::GLuint iteration_index)
3563 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3565 GLfloat data[2 * 4] = { 0.0f, 0.0f, 64.0f, 128.0f, 64.0f, 0.0f, 64.0f, 128.0f };
3567 gl.viewport(0, 0, m_width, m_height);
3568 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3570 switch (iteration_index)
3574 gl.viewportArrayv(4, 2, data);
3575 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3581 gl.viewportIndexedf(4, data[0], data[1], data[2], data[3]);
3582 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3584 gl.viewportIndexedf(5, data[4], data[5], data[6], data[7]);
3585 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3591 gl.viewportIndexedfv(4, &data[0]);
3592 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3594 gl.viewportIndexedfv(5, &data[4]);
3595 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3600 TCU_FAIL("Invalid value");
3606 * @param context Test context
3608 DrawMultipleLayers::DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams)
3609 : DrawTestBase(context, extParams, "draw_multiple_layers",
3610 "Test verifies that single viewport affects multiple layers in the same way")
3612 /* Nothing to be done here */
3617 * @param context Test context
3618 * @param test_name Test name
3619 * @param test_description Test description
3621 DrawMultipleLayers::DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams,
3622 const GLchar* test_name, const GLchar* test_description)
3623 : DrawTestBase(context, extParams, test_name, test_description)
3625 /* Nothing to be done here */
3628 /** Get string with fragment shader source code
3630 * @return Fragment shader source
3632 std::string DrawMultipleLayers::getFragmentShader()
3634 static const GLchar* source = "#version 410 core\n"
3636 "flat in int gs_fs_color;\n"
3637 " out int fs_out_color;\n"
3641 " fs_out_color = gs_fs_color;\n"
3645 std::string result = source;
3650 /** Get string with geometry shader source code
3652 * @return Geometry shader source
3654 std::string DrawMultipleLayers::getGeometryShader()
3656 static const GLchar* source = "#version 410 core\n"
3658 "layout(points, invocations = 16) in;\n"
3659 "layout(triangle_strip, max_vertices = 4) out;\n"
3661 "flat out int gs_fs_color;\n"
3665 " gs_fs_color = gl_InvocationID;\n"
3666 " gl_ViewportIndex = gl_InvocationID;\n"
3667 " gl_Layer = gl_InvocationID;\n"
3668 " gl_Position = vec4(-1, -1, 0, 1);\n"
3670 " gs_fs_color = gl_InvocationID;\n"
3671 " gl_ViewportIndex = gl_InvocationID;\n"
3672 " gl_Layer = gl_InvocationID;\n"
3673 " gl_Position = vec4(-1, 1, 0, 1);\n"
3675 " gs_fs_color = gl_InvocationID;\n"
3676 " gl_ViewportIndex = gl_InvocationID;\n"
3677 " gl_Layer = gl_InvocationID;\n"
3678 " gl_Position = vec4(1, -1, 0, 1);\n"
3680 " gs_fs_color = gl_InvocationID;\n"
3681 " gl_ViewportIndex = gl_InvocationID;\n"
3682 " gl_Layer = gl_InvocationID;\n"
3683 " gl_Position = vec4(1, 1, 0, 1);\n"
3688 std::string result = source;
3693 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3695 * @param texture_0 Verified texture
3699 * @return True if texture_0 is filled with expected pattern
3701 bool DrawMultipleLayers::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3702 GLuint /* draw_call_index */)
3704 static const GLuint layer_size = m_width * m_height;
3706 bool check_result = true;
3708 std::vector<GLint> texture_data;
3709 texture_data.resize(layer_size * m_depth);
3710 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3712 /* 16 layers, only region corresponding with layer index should be modified */
3713 for (GLuint layer = 0; layer < m_depth; ++layer)
3717 for (GLuint y = 0; y < 4; ++y)
3719 for (GLuint x = 0; x < 4; ++x)
3721 GLint* layer_data = &texture_data[layer * layer_size];
3723 GLint expected_value = -1;
3726 expected_value = index;
3729 bool result = checkRegionR32I(x, y, expected_value, layer_data);
3731 if (false == result)
3733 check_result = false;
3743 return check_result;
3746 /** Prepare textures used as framebuffer's attachments for current draw call
3748 * @param texture_0 R32I texture
3751 void DrawMultipleLayers::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
3753 prepareTextureArrayR32I(texture_0);
3758 * @param context Test context
3759 * @param test_name Test name
3760 * @param test_description Test description
3762 Scissor::Scissor(deqp::Context& context, const glcts::ExtParameters& extParams)
3763 : DrawMultipleLayers(context, extParams, "scissor", "Test verifies that scissor test is applied as expected")
3765 /* Nothing to be done here */
3772 DrawTestBase::TEST_TYPE Scissor::getTestType()
3779 * @param context Test context
3780 * @param test_name Test name
3781 * @param test_description Test description
3783 ScissorZeroDimension::ScissorZeroDimension(deqp::Context& context, const glcts::ExtParameters& extParams)
3784 : DrawMultipleLayers(context, extParams, "scissor_zero_dimension",
3785 "Test verifies that scissor test discard all fragments when width and height is set to zero")
3787 /* Nothing to be done here */
3790 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3792 * @param texture_0 Verified texture
3796 * @return True if texture_0 is filled with expected pattern
3798 bool ScissorZeroDimension::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3799 GLuint /* draw_call_index */)
3801 static const GLuint layer_size = m_width * m_height;
3803 bool check_result = true;
3805 std::vector<GLint> texture_data;
3806 texture_data.resize(layer_size * m_depth);
3807 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3809 /* 16 layers, all regions were not modified */
3810 for (GLuint layer = 0; layer < m_depth; ++layer)
3812 for (GLuint y = 0; y < 4; ++y)
3814 for (GLuint x = 0; x < 4; ++x)
3816 GLint* layer_data = &texture_data[layer * layer_size];
3818 GLint expected_value = -1;
3820 bool result = checkRegionR32I(x, y, expected_value, layer_data);
3822 if (false == result)
3824 check_result = false;
3832 return check_result;
3839 DrawTestBase::TEST_TYPE ScissorZeroDimension::getTestType()
3844 /** Set up viewports
3847 * @param iteration_index Index of iteration for given test type
3849 void ScissorZeroDimension::setupViewports(TEST_TYPE /* type */, GLuint iteration_index)
3851 SCISSOR_METHOD method;
3852 switch (iteration_index)
3857 method = (SCISSOR_METHOD)iteration_index;
3860 TCU_FAIL("Invalid value");
3863 setup4x4Scissor(method, true /* set_zeros */);
3868 * @param context Test context
3869 * @param test_name Test name
3870 * @param test_description Test description
3872 ScissorClear::ScissorClear(deqp::Context& context, const glcts::ExtParameters& extParams)
3873 : DrawMultipleLayers(context, extParams, "scissor_clear",
3874 "Test verifies that Clear is affected only by settings of scissor test in first viewport")
3876 /* Nothing to be done here */
3879 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3881 * @param texture_0 Verified texture
3885 * @return True if texture_0 is filled with expected pattern
3887 bool ScissorClear::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
3889 static const GLuint layer_size = m_width * m_height;
3891 bool check_result = true;
3893 std::vector<GLint> texture_data;
3894 texture_data.resize(layer_size * m_depth);
3895 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3897 /* 16 layers, only region corresponding with scissor box 0 should be modified */
3898 for (GLuint layer = 0; layer < m_depth; ++layer)
3900 for (GLuint y = 0; y < 4; ++y)
3902 for (GLuint x = 0; x < 4; ++x)
3904 GLint* layer_data = &texture_data[layer * layer_size];
3906 GLint expected_value = -1;
3907 if ((0 == x) && (0 == y))
3912 bool result = checkRegionR32I(x, y, expected_value, layer_data);
3914 if (false == result)
3916 check_result = false;
3924 return check_result;
3931 DrawTestBase::TEST_TYPE ScissorClear::getTestType()
3936 /** Selects if test should do draw or clear operation
3938 * @return true - clear operation
3940 bool ScissorClear::isClearTest()
3947 * @param context Test context
3948 * @param test_name Test name
3949 * @param test_description Test description
3951 DepthRange::DepthRange(deqp::Context& context, const glcts::ExtParameters& extParams)
3952 : DrawTestBase(context, extParams, "depth_range", "Test verifies that depth range is applied as expected")
3954 /* Nothing to be done here */
3957 /** Check if R32F texture is filled with two rows, top with decreasing values, bottom with incresing values
3959 * @param texture_0 Verified texture
3963 * @return True if texture_0 is filled with expected pattern
3965 bool DepthRange::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
3967 static const GLfloat step = 1.0f / 16.0f;
3969 bool check_result = true;
3971 std::vector<GLfloat> texture_data;
3972 texture_data.resize(m_r32f_width * m_r32f_height);
3973 texture_0.get(GL_RED, GL_FLOAT, &texture_data[0]);
3975 GLfloat depth_data[16 * 2];
3977 for (GLuint i = 0; i < 16; ++i)
3979 const GLfloat near = step * (GLfloat)i;
3981 depth_data[i * 2 + 0] = near;
3982 depth_data[i * 2 + 1] = 1.0f - near;
3985 for (GLuint i = 0; i < 16; ++i)
3987 const GLfloat expected_near = depth_data[i * 2 + 0];
3988 const GLfloat expected_far = depth_data[i * 2 + 1];
3990 /* Bottom row should contain near values, top one should contain far values */
3991 const GLfloat near = texture_data[i];
3992 const GLfloat far = texture_data[i + 16];
3994 if ((expected_near != near) || (expected_far != far))
3996 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid values at " << i << " expected ["
3997 << expected_near << ", " << expected_far << "] got [" << near << ", "
3998 << far << "]" << tcu::TestLog::EndMessage;
4000 check_result = false;
4005 return check_result;
4008 /** Get string with fragment shader source code
4010 * @return Fragment shader source
4012 std::string DepthRange::getFragmentShader()
4014 static const GLchar* source = "#version 410 core\n"
4016 "out float fs_out_color;\n"
4020 " fs_out_color = gl_FragCoord.z;\n"
4024 std::string result = source;
4029 /** Get string with geometry shader source code
4031 * @return Geometry shader source
4033 std::string DepthRange::getGeometryShader()
4035 static const GLchar* source = "#version 410 core\n"
4037 "layout(points, invocations = 16) in;\n"
4038 "layout(triangle_strip, max_vertices = 8) out;\n"
4042 " const float top_z = 1.0;\n"
4043 " const float bottom_z = -1.0;\n"
4046 " gl_ViewportIndex = gl_InvocationID;\n"
4047 " gl_Position = vec4(-1, -1, bottom_z, 1);\n"
4049 " gl_ViewportIndex = gl_InvocationID;\n"
4050 " gl_Position = vec4(-1, 0, bottom_z, 1);\n"
4052 " gl_ViewportIndex = gl_InvocationID;\n"
4053 " gl_Position = vec4(1, -1, bottom_z, 1);\n"
4055 " gl_ViewportIndex = gl_InvocationID;\n"
4056 " gl_Position = vec4(1, 0, bottom_z, 1);\n"
4058 " EndPrimitive();\n"
4061 " gl_ViewportIndex = gl_InvocationID;\n"
4062 " gl_Position = vec4(-1, 0, top_z, 1);\n"
4064 " gl_ViewportIndex = gl_InvocationID;\n"
4065 " gl_Position = vec4(-1, 1, top_z, 1);\n"
4067 " gl_ViewportIndex = gl_InvocationID;\n"
4068 " gl_Position = vec4(1, 0, top_z, 1);\n"
4070 " gl_ViewportIndex = gl_InvocationID;\n"
4071 " gl_Position = vec4(1, 1, top_z, 1);\n"
4073 " EndPrimitive();\n"
4077 std::string result = source;
4084 * @return DEPTHRANGE
4086 DrawTestBase::TEST_TYPE DepthRange::getTestType()
4091 /** Prepare textures used as framebuffer's attachments for current draw call
4093 * @param texture_0 R32F texture
4096 void DepthRange::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
4098 prepareTextureR32F(texture_0);
4103 * @param context Test context
4104 * @param test_name Test name
4105 * @param test_description Test description
4107 DepthRangeDepthTest::DepthRangeDepthTest(deqp::Context& context, const glcts::ExtParameters& extParams)
4108 : DrawTestBase(context, extParams, "depth_range_depth_test",
4109 "Test verifies that depth test work as expected with multiple viewports")
4111 /* Nothing to be done here */
4114 /** Check if R32F texture is filled with two rows of values less than expected depth
4116 * @param texture_0 Verified texture
4118 * @param draw_call_index Index of draw call
4120 * @return True if texture_0 is filled with expected pattern
4122 bool DepthRangeDepthTest::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
4123 GLuint draw_call_index)
4125 static const GLfloat step = 1.0f / 16.0f;
4127 const GLfloat depth_value = step * (GLfloat)draw_call_index;
4129 bool check_result = true;
4131 std::vector<GLfloat> texture_data;
4132 texture_data.resize(m_r32f_width * m_r32f_height);
4133 texture_0.get(GL_RED, GL_FLOAT, &texture_data[0]);
4135 for (GLuint i = 0; i < 16; ++i)
4137 /* Bottom row should contain near values, top one should contain far values */
4138 const GLfloat near = texture_data[i];
4139 const GLfloat far = texture_data[i + 16];
4141 if ((depth_value <= near) || (depth_value <= far))
4143 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid values at " << i << " depth value "
4144 << depth_value << " got [" << near << ", " << far << "]"
4145 << tcu::TestLog::EndMessage;
4147 check_result = false;
4152 return check_result;
4155 /** Get settings of clear operation
4157 * @param clear_depth_before_draw Selects if clear should be executed before draw.
4158 * @param iteration_index Index of draw call
4159 * @param depth_value Value that will be used to clear depth buffer
4161 void DepthRangeDepthTest::getClearSettings(bool& clear_depth_before_draw, GLuint iteration_index, GLdouble& depth_value)
4163 static const GLdouble step = 1.0 / 16.0;
4165 clear_depth_before_draw = true;
4167 depth_value = step * (GLdouble)iteration_index;
4170 /** Get number of draw call to be executed during test
4174 GLuint DepthRangeDepthTest::getDrawCallsNumber()
4179 /** Get string with fragment shader source code
4181 * @return Fragment shader source
4183 std::string DepthRangeDepthTest::getFragmentShader()
4185 static const GLchar* source = "#version 410 core\n"
4187 "out float fs_out_color;\n"
4191 " fs_out_color = gl_FragCoord.z;\n"
4195 std::string result = source;
4200 /** Get string with geometry shader source code
4202 * @return Geometry shader source
4204 std::string DepthRangeDepthTest::getGeometryShader()
4206 static const GLchar* source = "#version 410 core\n"
4208 "layout(points, invocations = 16) in;\n"
4209 "layout(triangle_strip, max_vertices = 8) out;\n"
4213 " const float top_z = 1.0;\n"
4214 " const float bottom_z = -1.0;\n"
4217 " gl_ViewportIndex = gl_InvocationID;\n"
4218 " gl_Position = vec4(-1, -1, bottom_z, 1);\n"
4220 " gl_ViewportIndex = gl_InvocationID;\n"
4221 " gl_Position = vec4(-1, 0, bottom_z, 1);\n"
4223 " gl_ViewportIndex = gl_InvocationID;\n"
4224 " gl_Position = vec4(1, -1, bottom_z, 1);\n"
4226 " gl_ViewportIndex = gl_InvocationID;\n"
4227 " gl_Position = vec4(1, 0, bottom_z, 1);\n"
4231 " gl_ViewportIndex = gl_InvocationID;\n"
4232 " gl_Position = vec4(-1, 0, top_z, 1);\n"
4234 " gl_ViewportIndex = gl_InvocationID;\n"
4235 " gl_Position = vec4(-1, 1, top_z, 1);\n"
4237 " gl_ViewportIndex = gl_InvocationID;\n"
4238 " gl_Position = vec4(1, 0, top_z, 1);\n"
4240 " gl_ViewportIndex = gl_InvocationID;\n"
4241 " gl_Position = vec4(1, 1, top_z, 1);\n"
4243 " EndPrimitive();\n"
4247 std::string result = source;
4254 * @return DEPTHRANGE
4256 DrawTestBase::TEST_TYPE DepthRangeDepthTest::getTestType()
4261 /** Prepare textures used as framebuffer's attachments for current draw call
4263 * @param texture_0 R32F texture
4264 * @param texture_1 D32F texture
4266 void DepthRangeDepthTest::prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1)
4268 prepareTextureR32F(texture_0);
4269 prepareTextureD32F(texture_1);
4272 /** Attach textures to framebuffer
4274 * @param framebuffer Framebuffer instance
4275 * @param texture_0 Texture attached as color 0
4276 * @param texture_1 Texture attached as depth
4278 void DepthRangeDepthTest::setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
4279 Utils::texture& texture_1)
4281 framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, texture_0.m_id, m_width, m_height);
4282 framebuffer.attachTexture(GL_DEPTH_ATTACHMENT, texture_1.m_id, m_width, m_height);
4285 /** Set up viewports
4288 * @param iteration_index Index of iteration for given test type
4290 void DepthRangeDepthTest::setupViewports(TEST_TYPE /* type */, GLuint iteration_index)
4292 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4294 DEPTH_RANGE_METHOD method;
4295 switch (iteration_index)
4299 method = (DEPTH_RANGE_METHOD)iteration_index;
4302 TCU_FAIL("Invalid value");
4304 setup16x2Depths(method);
4306 gl.enable(GL_DEPTH_TEST);
4307 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
4312 * @param context Test context
4313 * @param test_name Test name
4314 * @param test_description Test description
4316 ProvokingVertex::ProvokingVertex(deqp::Context& context, const glcts::ExtParameters& extParams)
4317 : DrawTestBase(context, extParams, "provoking_vertex", "Test verifies that provoking vertex work as expected")
4319 /* Nothing to be done here */
4322 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
4324 * @param texture_0 Verified texture
4328 * @return True if texture_0 is filled with expected pattern
4330 bool ProvokingVertex::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
4331 GLuint /*draw_call_index */)
4333 static const GLuint layer_size = m_width * m_height;
4335 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4337 GLint layer_mode = 0;
4338 GLint viewport_mode = 0;
4339 gl.getIntegerv(GL_LAYER_PROVOKING_VERTEX, &layer_mode);
4340 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4341 gl.getIntegerv(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, &viewport_mode);
4342 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4344 if ((GL_UNDEFINED_VERTEX == layer_mode) || (GL_UNDEFINED_VERTEX == viewport_mode))
4346 /* Results are undefined, therefore it does not make sense to verify them */
4350 bool check_result = true;
4351 GLint provoking = 0;
4353 std::vector<GLint> texture_data;
4354 texture_data.resize(layer_size * m_r32ix4_depth);
4355 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
4357 gl.getIntegerv(GL_PROVOKING_VERTEX, &provoking);
4358 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4360 GLuint expected_layer = 0;
4361 GLint expected_viewport = 0;
4363 /* Mode is 1st, or mode is provoking and provoking is 1st */
4364 if ((GL_FIRST_VERTEX_CONVENTION == layer_mode) ||
4365 ((GL_PROVOKING_VERTEX == layer_mode) && (GL_FIRST_VERTEX_CONVENTION == provoking)))
4374 if ((GL_FIRST_VERTEX_CONVENTION == viewport_mode) ||
4375 ((GL_PROVOKING_VERTEX == viewport_mode) && (GL_FIRST_VERTEX_CONVENTION == provoking)))
4377 expected_viewport = 0;
4381 expected_viewport = 2;
4384 for (GLuint layer = 0; layer < m_r32ix4_depth; ++layer)
4386 GLint* layer_data = &texture_data[layer * layer_size];
4389 for (GLuint y = 0; y < 2; ++y)
4391 for (GLuint x = 0; x < 2; ++x)
4393 /* If layer and viewport are expected ones, than result shall be 1, otherwise -1. */
4394 const GLint expected_value = ((expected_viewport == viewport) && (expected_layer == layer)) ? 1 : -1;
4396 bool result = checkRegionR32I(x, y, m_width / 2, m_height / 2, expected_value, layer_data);
4398 if (false == result)
4400 check_result = false;
4410 return check_result;
4413 /** Get string with fragment shader source code
4415 * @return Fragment shader source
4417 std::string ProvokingVertex::getFragmentShader()
4419 static const GLchar* source = "#version 410 core\n"
4421 "flat in int gs_fs_color;\n"
4422 " out int fs_out_color;\n"
4426 " fs_out_color = gs_fs_color;\n"
4430 std::string result = source;
4435 /** Get string with geometry shader source code
4437 * @return Geometry shader source
4439 std::string ProvokingVertex::getGeometryShader()
4441 static const GLchar* source = "#version 410 core\n"
4443 "layout(points, invocations = 1) in;\n"
4444 "layout(triangle_strip, max_vertices = 6) out;\n"
4446 "flat out int gs_fs_color;\n"
4450 " /* Left-bottom half */\n"
4451 " gs_fs_color = 1;\n"
4452 " gl_ViewportIndex = 0;\n"
4454 " gl_Position = vec4(-1, -1, 0, 1);\n"
4456 " gs_fs_color = 1;\n"
4457 " gl_ViewportIndex = 1;\n"
4459 " gl_Position = vec4(-1, 1, 0, 1);\n"
4461 " gs_fs_color = 1;\n"
4462 " gl_ViewportIndex = 2;\n"
4464 " gl_Position = vec4(1, -1, 0, 1);\n"
4466 " EndPrimitive();\n"
4468 " /* Right-top half */\n"
4469 " gs_fs_color = 1;\n"
4470 " gl_ViewportIndex = 0;\n"
4472 " gl_Position = vec4(-1, 1, 0, 1);\n"
4474 " gs_fs_color = 1;\n"
4475 " gl_ViewportIndex = 1;\n"
4477 " gl_Position = vec4(1, 1, 0, 1);\n"
4479 " gs_fs_color = 1;\n"
4480 " gl_ViewportIndex = 2;\n"
4482 " gl_Position = vec4(1, -1, 0, 1);\n"
4484 " EndPrimitive();\n"
4488 std::string result = source;
4497 DrawTestBase::TEST_TYPE ProvokingVertex::getTestType()
4502 /** Prepare textures used as framebuffer's attachments for current draw call
4504 * @param texture_0 R32I texture
4507 void ProvokingVertex::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
4509 prepareTextureR32Ix4(texture_0);
4512 } /* ViewportArray namespace */
4516 * @param context Rendering context.
4518 ViewportArrayTests::ViewportArrayTests(deqp::Context& context, const glcts::ExtParameters& extParams)
4519 : TestCaseGroupBase(context, extParams, "viewport_array", "Verifies \"viewport_array\" functionality")
4521 /* Left blank on purpose */
4524 /** Initializes a texture_storage_multisample test group.
4527 void ViewportArrayTests::init(void)
4529 addChild(new ViewportArray::APIErrors(m_context, m_extParams));
4530 addChild(new ViewportArray::Queries(m_context, m_extParams));
4531 addChild(new ViewportArray::ViewportAPI(m_context, m_extParams));
4532 addChild(new ViewportArray::ScissorAPI(m_context, m_extParams));
4533 addChild(new ViewportArray::DepthRangeAPI(m_context, m_extParams));
4534 addChild(new ViewportArray::ScissorTestStateAPI(m_context, m_extParams));
4535 addChild(new ViewportArray::DrawToSingleLayerWithMultipleViewports(m_context, m_extParams));
4536 addChild(new ViewportArray::DynamicViewportIndex(m_context, m_extParams));
4537 addChild(new ViewportArray::DrawMulitpleViewportsWithSingleInvocation(m_context, m_extParams));
4538 addChild(new ViewportArray::ViewportIndexSubroutine(m_context, m_extParams));
4539 addChild(new ViewportArray::DrawMultipleLayers(m_context, m_extParams));
4540 addChild(new ViewportArray::Scissor(m_context, m_extParams));
4541 addChild(new ViewportArray::ScissorZeroDimension(m_context, m_extParams));
4542 addChild(new ViewportArray::ScissorClear(m_context, m_extParams));
4543 addChild(new ViewportArray::DepthRange(m_context, m_extParams));
4544 addChild(new ViewportArray::DepthRangeDepthTest(m_context, m_extParams));
4545 addChild(new ViewportArray::ProvokingVertex(m_context, m_extParams));
4548 } /* glcts namespace */