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
51 /** Check if extension is supported
53 * @param context Test context
54 * @param extension_name Name of extension
56 * @return true if extension is supported, false otherwise
58 bool Utils::isExtensionSupported(deqp::Context& context, const GLchar* extension_name)
60 const std::vector<std::string>& extensions = context.getContextInfo().getExtensions();
62 if (std::find(extensions.begin(), extensions.end(), extension_name) == extensions.end())
70 /** Check if GL context meets version requirements
73 * @param required_major Minimum required MAJOR_VERSION
74 * @param required_minor Minimum required MINOR_VERSION
76 * @return true if GL context version is at least as requested, false otherwise
78 bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor)
83 gl.getIntegerv(GL_MAJOR_VERSION, &major);
84 gl.getIntegerv(GL_MINOR_VERSION, &minor);
86 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
88 if (major > required_major)
90 /* Major is higher than required one */
93 else if (major == required_major)
95 if (minor >= required_minor)
97 /* Major is equal to required one */
98 /* Minor is higher than or equal to required one */
103 /* Major is equal to required one */
104 /* Minor is lower than required one */
110 /* Major is lower than required one */
115 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
117 * @param token Token string
118 * @param search_position Position at which find will start, it is updated to position at which replaced text ends
119 * @param text String that will be used as replacement for <token>
120 * @param string String to work on
122 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
125 const size_t text_length = strlen(text);
126 const size_t token_length = strlen(token);
127 const size_t token_position = string.find(token, search_position);
129 string.replace(token_position, token_length, text, text_length);
131 search_position = token_position + text_length;
134 /** Replace all occurances of <token> with <text> in <string>
136 * @param token Token string
137 * @param text String that will be used as replacement for <token>
138 * @param string String to work on
140 void Utils::replaceAllTokens(const glw::GLchar* token, const glw::GLchar* text, std::string& string)
142 const size_t text_length = strlen(text);
143 const size_t token_length = strlen(token);
145 size_t search_position = 0;
149 const size_t token_position = string.find(token, search_position);
151 if (std::string::npos == token_position)
156 search_position = token_position + text_length;
158 string.replace(token_position, token_length, text, text_length);
164 * @param context CTS context.
166 Utils::buffer::buffer(deqp::Context& context) : m_id(0), m_context(context), m_target(0)
173 Utils::buffer::~buffer()
177 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
179 gl.deleteBuffers(1, &m_id);
184 /** Execute BindBuffer
187 void Utils::buffer::bind() const
189 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
191 gl.bindBuffer(m_target, m_id);
192 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer");
195 /** Execute BindBufferRange
197 * @param index <index> parameter
198 * @param offset <offset> parameter
199 * @param size <size> parameter
201 void Utils::buffer::bindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size)
203 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
205 gl.bindBufferRange(m_target, index, m_id, offset, size);
206 GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange");
209 /** Execute GenBuffer
211 * @param target Target that will be used by this buffer
213 void Utils::buffer::generate(glw::GLenum target)
215 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
219 gl.genBuffers(1, &m_id);
220 GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers");
223 /** Maps buffer content
225 * @param access Access rights for mapped region
227 * @return Mapped memory
229 void* Utils::buffer::map(GLenum access) const
231 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
233 gl.bindBuffer(m_target, m_id);
234 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
236 void* result = gl.mapBuffer(m_target, access);
237 GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer");
245 void Utils::buffer::unmap() const
247 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
249 gl.bindBuffer(m_target, m_id);
250 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
252 gl.unmapBuffer(m_target);
253 GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer");
256 /** Execute BufferData
258 * @param size <size> parameter
259 * @param data <data> parameter
260 * @param usage <usage> parameter
262 void Utils::buffer::update(glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage)
264 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
266 gl.bindBuffer(m_target, m_id);
267 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBuffer");
269 gl.bufferData(m_target, size, data, usage);
270 GLU_EXPECT_NO_ERROR(gl.getError(), "bufferData");
275 * @param context CTS context
277 Utils::framebuffer::framebuffer(deqp::Context& context) : m_id(0), m_context(context)
279 /* Nothing to be done here */
285 Utils::framebuffer::~framebuffer()
289 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
291 gl.deleteFramebuffers(1, &m_id);
296 /** Attach texture to specified attachment
298 * @param attachment Attachment
299 * @param texture_id Texture id
300 * @param width Texture width
301 * @param height Texture height
303 void Utils::framebuffer::attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width,
306 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
310 gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, attachment, texture_id, 0 /* level */);
311 GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture");
313 gl.viewport(0 /* x */, 0 /* y */, width, height);
314 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
317 /** Binds framebuffer to DRAW_FRAMEBUFFER
320 void Utils::framebuffer::bind()
322 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
324 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_id);
325 GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
328 /** Clear framebuffer
330 * @param mask <mask> parameter of glClear. Decides which shall be cleared
332 void Utils::framebuffer::clear(glw::GLenum mask)
334 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
337 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
340 /** Specifies clear color
342 * @param red Red channel
343 * @param green Green channel
344 * @param blue Blue channel
345 * @param alpha Alpha channel
347 void Utils::framebuffer::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
349 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
351 gl.clearColor(red, green, blue, alpha);
352 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
355 /** Generate framebuffer
358 void Utils::framebuffer::generate()
360 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
362 gl.genFramebuffers(1, &m_id);
363 GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
366 Utils::shaderCompilationException::shaderCompilationException(const glw::GLchar* source, const glw::GLchar* message)
367 : m_shader_source(source), m_error_message(message)
369 /* Nothing to be done */
372 const char* Utils::shaderCompilationException::what() const throw()
374 return "Shader compilation failed";
377 Utils::programLinkageException::programLinkageException(const glw::GLchar* message) : m_error_message(message)
379 /* Nothing to be done */
382 const char* Utils::programLinkageException::what() const throw()
384 return "Program linking failed";
387 const glw::GLenum Utils::program::ARB_COMPUTE_SHADER = 0x91B9;
391 * @param context CTS context.
393 Utils::program::program(deqp::Context& context)
394 : m_compute_shader_id(0)
395 , m_fragment_shader_id(0)
396 , m_geometry_shader_id(0)
397 , m_program_object_id(0)
398 , m_tesselation_control_shader_id(0)
399 , m_tesselation_evaluation_shader_id(0)
400 , m_vertex_shader_id(0)
403 /* Nothing to be done here */
409 Utils::program::~program()
416 * @param compute_shader_code Compute shader source code
417 * @param fragment_shader_code Fragment shader source code
418 * @param geometry_shader_code Geometry shader source code
419 * @param tesselation_control_shader_code Tesselation control shader source code
420 * @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
421 * @param vertex_shader_code Vertex shader source code
422 * @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback
423 * @param n_varying_names Number of varyings to be captured with transfrom feedback
424 * @param is_separable Selects if monolithis or separable program should be built. Defaults to false
426 void Utils::program::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
427 const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code,
428 const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code,
429 const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable)
431 /* GL entry points */
432 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
434 /* Create shader objects and compile */
435 if (0 != compute_shader_code)
437 m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
438 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
440 compile(m_compute_shader_id, compute_shader_code);
443 if (0 != fragment_shader_code)
445 m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
446 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
448 compile(m_fragment_shader_id, fragment_shader_code);
451 if (0 != geometry_shader_code)
453 m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
454 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
456 compile(m_geometry_shader_id, geometry_shader_code);
459 if (0 != tesselation_control_shader_code)
461 m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
462 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
464 compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
467 if (0 != tesselation_evaluation_shader_code)
469 m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
470 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
472 compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
475 if (0 != vertex_shader_code)
477 m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
478 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
480 compile(m_vertex_shader_id, vertex_shader_code);
483 /* Create program object */
484 m_program_object_id = gl.createProgram();
485 GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
487 /* Set up captyured varyings' names */
488 if (0 != n_varying_names)
490 gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
491 GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
494 /* Set separable parameter */
495 if (true == is_separable)
497 gl.programParameteri(m_program_object_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
498 GLU_EXPECT_NO_ERROR(gl.getError(), "ProgramParameteri");
505 void Utils::program::compile(GLuint shader_id, const GLchar* source) const
507 /* GL entry points */
508 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
510 /* Compilation status */
511 glw::GLint status = GL_FALSE;
513 /* Set source code */
514 gl.shaderSource(shader_id, 1 /* count */, &source, 0 /* lengths */);
515 GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
518 gl.compileShader(shader_id);
519 GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
521 /* Get compilation status */
522 gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
523 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
525 /* Log compilation error */
526 if (GL_TRUE != status)
528 glw::GLint length = 0;
529 std::vector<glw::GLchar> message;
531 /* Error log length */
532 gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
533 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
535 /* Prepare storage */
536 message.resize(length);
539 gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
540 GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
542 throw shaderCompilationException(source, &message[0]);
546 glw::GLint Utils::program::getAttribLocation(const glw::GLchar* name) const
548 /* GL entry points */
549 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
551 GLint location = gl.getAttribLocation(m_program_object_id, name);
552 GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation");
557 /** Get subroutine index
559 * @param subroutine_name Subroutine name
561 * @return Index of subroutine
563 GLuint Utils::program::getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const
565 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
568 index = gl.getSubroutineIndex(m_program_object_id, shader_stage, subroutine_name);
569 GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineIndex");
571 if (GL_INVALID_INDEX == index)
573 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine: " << subroutine_name
574 << " is not available" << tcu::TestLog::EndMessage;
576 TCU_FAIL("Subroutine is not available");
582 /** Get subroutine uniform location
584 * @param uniform_name Subroutine uniform name
586 * @return Location of subroutine uniform
588 GLint Utils::program::getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const
590 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
593 location = gl.getSubroutineUniformLocation(m_program_object_id, shader_stage, uniform_name);
594 GLU_EXPECT_NO_ERROR(gl.getError(), "GetSubroutineUniformLocation");
598 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Subroutine uniform: " << uniform_name
599 << " is not available" << tcu::TestLog::EndMessage;
601 TCU_FAIL("Subroutine uniform is not available");
607 /** Get uniform location
609 * @param uniform_name Subroutine uniform name
611 * @return Location of uniform
613 GLint Utils::program::getUniformLocation(const glw::GLchar* uniform_name) const
615 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
618 location = gl.getUniformLocation(m_program_object_id, uniform_name);
619 GLU_EXPECT_NO_ERROR(gl.getError(), "GetUniformLocation");
623 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Uniform: " << uniform_name
624 << " is not available" << tcu::TestLog::EndMessage;
626 TCU_FAIL("Uniform is not available");
632 /** Attach shaders and link program
635 void Utils::program::link() const
637 /* GL entry points */
638 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
641 glw::GLint status = GL_FALSE;
644 if (0 != m_compute_shader_id)
646 gl.attachShader(m_program_object_id, m_compute_shader_id);
647 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
650 if (0 != m_fragment_shader_id)
652 gl.attachShader(m_program_object_id, m_fragment_shader_id);
653 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
656 if (0 != m_geometry_shader_id)
658 gl.attachShader(m_program_object_id, m_geometry_shader_id);
659 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
662 if (0 != m_tesselation_control_shader_id)
664 gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
665 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
668 if (0 != m_tesselation_evaluation_shader_id)
670 gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
671 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
674 if (0 != m_vertex_shader_id)
676 gl.attachShader(m_program_object_id, m_vertex_shader_id);
677 GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
681 gl.linkProgram(m_program_object_id);
682 GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
684 /* Get link status */
685 gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
686 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
689 if (GL_TRUE != status)
691 glw::GLint length = 0;
692 std::vector<glw::GLchar> message;
694 /* Get error log length */
695 gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
696 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
698 message.resize(length);
701 gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
702 GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
704 throw programLinkageException(&message[0]);
708 /** Delete program object and all attached shaders
711 void Utils::program::remove()
713 /* GL entry points */
714 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
716 /* Make sure program object is no longer used by GL */
719 /* Clean program object */
720 if (0 != m_program_object_id)
722 gl.deleteProgram(m_program_object_id);
723 m_program_object_id = 0;
727 if (0 != m_compute_shader_id)
729 gl.deleteShader(m_compute_shader_id);
730 m_compute_shader_id = 0;
733 if (0 != m_fragment_shader_id)
735 gl.deleteShader(m_fragment_shader_id);
736 m_fragment_shader_id = 0;
739 if (0 != m_geometry_shader_id)
741 gl.deleteShader(m_geometry_shader_id);
742 m_geometry_shader_id = 0;
745 if (0 != m_tesselation_control_shader_id)
747 gl.deleteShader(m_tesselation_control_shader_id);
748 m_tesselation_control_shader_id = 0;
751 if (0 != m_tesselation_evaluation_shader_id)
753 gl.deleteShader(m_tesselation_evaluation_shader_id);
754 m_tesselation_evaluation_shader_id = 0;
757 if (0 != m_vertex_shader_id)
759 gl.deleteShader(m_vertex_shader_id);
760 m_vertex_shader_id = 0;
764 /** Execute UseProgram
767 void Utils::program::use() const
769 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
771 gl.useProgram(m_program_object_id);
772 GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
775 void Utils::program::printShaderSource(const GLchar* source, tcu::MessageBuilder& log)
777 GLuint line_number = 0;
779 log << "Shader source.";
781 log << "\nLine||Source\n";
786 const GLchar* next_line = strchr(source, '\n');
791 line.assign(source, next_line - source);
800 log << std::setw(4) << line_number << "||" << line;
810 * @param context CTS context.
812 Utils::texture::texture(deqp::Context& context) : m_id(0), m_context(context), m_is_array(false)
814 /* Nothing to done here */
820 Utils::texture::~texture()
825 /** Bind texture to GL_TEXTURE_2D
828 void Utils::texture::bind() const
830 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
832 if (false == m_is_array)
834 gl.bindTexture(GL_TEXTURE_2D, m_id);
835 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
839 gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_id);
840 GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
844 /** Create 2d texture
846 * @param width Width of texture
847 * @param height Height of texture
848 * @param internal_format Internal format of texture
850 void Utils::texture::create(GLuint width, GLuint height, GLenum internal_format)
852 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
858 gl.genTextures(1, &m_id);
859 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
863 gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, internal_format, width, height);
864 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
867 /** Create 2d texture array
869 * @param width Width of texture
870 * @param height Height of texture
871 * @param depth Depth of texture
872 * @param internal_format Internal format of texture
874 void Utils::texture::create(GLuint width, GLuint height, GLuint depth, GLenum internal_format)
876 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
882 gl.genTextures(1, &m_id);
883 GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
887 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, internal_format, width, height, depth);
888 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D");
891 /** Get contents of texture
893 * @param format Format of image
894 * @param type Type of image
895 * @param out_data Buffer for image
897 void Utils::texture::get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data) const
899 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
903 GLenum textarget = GL_TEXTURE_2D;
905 if (true == m_is_array)
907 textarget = GL_TEXTURE_2D_ARRAY;
910 gl.getTexImage(textarget, 0 /* level */, format, type, out_data);
911 GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage");
917 void Utils::texture::release()
921 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
923 gl.deleteTextures(1, &m_id);
928 /** Update contents of texture
930 * @param width Width of texture
931 * @param height Height of texture
932 * @param depth Depth of texture
933 * @param format Format of data
934 * @param type Type of data
935 * @param data Buffer with image
937 void Utils::texture::update(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format,
938 glw::GLenum type, glw::GLvoid* data)
940 static const GLuint level = 0;
942 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
946 if (false == m_is_array)
948 gl.texSubImage2D(GL_TEXTURE_2D, level, 0 /* x */, 0 /* y */, width, height, format, type, data);
949 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
953 gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, level, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, format,
955 GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
961 * @param context CTS context.
963 Utils::vertexArray::vertexArray(deqp::Context& context) : m_id(0), m_context(context)
970 Utils::vertexArray::~vertexArray()
974 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
976 gl.deleteVertexArrays(1, &m_id);
982 /** Execute BindVertexArray
985 void Utils::vertexArray::bind()
987 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
989 gl.bindVertexArray(m_id);
990 GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray");
993 /** Execute GenVertexArrays
996 void Utils::vertexArray::generate()
998 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1000 gl.genVertexArrays(1, &m_id);
1001 GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays");
1006 * @param context Test context
1008 APIErrors::APIErrors(deqp::Context& context, const glcts::ExtParameters& extParams)
1009 : TestCaseBase(context, extParams, "api_errors", "Test verifies error generated by API")
1011 /* Nothing to be done here */
1016 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1018 tcu::TestNode::IterateResult APIErrors::iterate()
1020 /* GL entry points */
1021 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1024 bool test_result = true;
1026 GLint max_viewports = 0;
1027 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1028 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1031 * * DepthRangeArrayv generates INVALID_VALUE when <first> + <count> is greater
1032 * than or equal to the value of MAX_VIEWPORTS;
1035 std::vector<GLdouble> data;
1036 data.resize(max_viewports * 2 /* near + far */);
1038 for (GLint i = 0; i < max_viewports; ++i)
1041 data[i * 2 + 1] = 1.0;
1044 gl.depthRangeArrayv(0, max_viewports - 1, &data[0]);
1045 checkGLError(GL_NO_ERROR, "depthRangeArrayv, correct parameters", test_result);
1047 gl.depthRangeArrayv(max_viewports, 1, &data[0]);
1048 checkGLError(GL_INVALID_VALUE, "depthRangeArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
1050 gl.depthRangeArrayv(1, max_viewports - 1, &data[0]);
1051 checkGLError(GL_NO_ERROR, "depthRangeArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
1053 gl.depthRangeArrayv(1, max_viewports, &data[0]);
1054 checkGLError(GL_INVALID_VALUE, "depthRangeArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
1058 * * DepthRangeIndexed generates INVALID_VALUE when <index> is greater than or
1059 * equal to the value of MAX_VIEWPORTS;
1062 gl.depthRangeIndexed(0 /* index */, 0.0, 1.0);
1063 checkGLError(GL_NO_ERROR, "depthRangeIndexed, <index> == 0", test_result);
1065 gl.depthRangeIndexed(max_viewports - 1 /* index */, 0.0, 1.0);
1066 checkGLError(GL_NO_ERROR, "depthRangeIndexed, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1068 gl.depthRangeIndexed(max_viewports /* index */, 0.0, 1.0);
1069 checkGLError(GL_INVALID_VALUE, "depthRangeIndexed, <index> == GL_MAX_VIEWPORTS", test_result);
1071 gl.depthRangeIndexed(max_viewports + 1 /* index */, 0.0, 1.0);
1072 checkGLError(GL_INVALID_VALUE, "depthRangeIndexed, <index> > GL_MAX_VIEWPORTS", test_result);
1076 * * ViewportArrayv generates INVALID_VALUE when <first> + <count> is greater
1077 * than or equal to the value of MAX_VIEWPORTS;
1080 std::vector<GLfloat> data;
1081 data.resize(max_viewports * 4 /* x + y + w + h */);
1083 for (GLint i = 0; i < max_viewports; ++i)
1085 data[i * 4 + 0] = 0.0f;
1086 data[i * 4 + 1] = 0.0f;
1087 data[i * 4 + 2] = 1.0f;
1088 data[i * 4 + 3] = 1.0f;
1091 gl.viewportArrayv(0, max_viewports - 1, &data[0]);
1092 checkGLError(GL_NO_ERROR, "viewportArrayv, correct parameters", test_result);
1094 gl.viewportArrayv(max_viewports, 1, &data[0]);
1095 checkGLError(GL_INVALID_VALUE, "viewportArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
1097 gl.viewportArrayv(1, max_viewports - 1, &data[0]);
1098 checkGLError(GL_NO_ERROR, "viewportArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
1100 gl.viewportArrayv(1, max_viewports, &data[0]);
1101 checkGLError(GL_INVALID_VALUE, "viewportArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
1105 * * ViewportIndexedf and ViewportIndexedfv generate INVALID_VALUE when <index>
1106 * is greater than or equal to the value of MAX_VIEWPORTS;
1109 GLfloat data[4 /* x + y + w + h */];
1116 gl.viewportIndexedf(0 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1117 checkGLError(GL_NO_ERROR, "viewportIndexedf, <index> == 0", test_result);
1119 gl.viewportIndexedf(max_viewports - 1 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1120 checkGLError(GL_NO_ERROR, "viewportIndexedf, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1122 gl.viewportIndexedf(max_viewports /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1123 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, <index> == GL_MAX_VIEWPORTS", test_result);
1125 gl.viewportIndexedf(max_viewports + 1 /* index */, 0.0f, 0.0f, 1.0f, 1.0f);
1126 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, <index> > GL_MAX_VIEWPORTS", test_result);
1128 gl.viewportIndexedfv(0 /* index */, data);
1129 checkGLError(GL_NO_ERROR, "viewportIndexedfv, <index> == 0", test_result);
1131 gl.viewportIndexedfv(max_viewports - 1 /* index */, data);
1132 checkGLError(GL_NO_ERROR, "viewportIndexedfv, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1134 gl.viewportIndexedfv(max_viewports /* index */, data);
1135 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, <index> == GL_MAX_VIEWPORTS", test_result);
1137 gl.viewportIndexedfv(max_viewports + 1 /* index */, data);
1138 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, <index> > GL_MAX_VIEWPORTS", test_result);
1142 * * ViewportArrayv, Viewport, ViewportIndexedf and ViewportIndexedfv generate
1143 * INVALID_VALUE when <w> or <h> values are negative;
1146 gl.viewport(0, 0, -1, 1);
1147 checkGLError(GL_INVALID_VALUE, "viewport, negative width", test_result);
1149 gl.viewport(0, 0, 1, -1);
1150 checkGLError(GL_INVALID_VALUE, "viewport, negative height", test_result);
1152 for (GLint i = 0; i < max_viewports; ++i)
1154 std::vector<GLfloat> data;
1155 data.resize(max_viewports * 4 /* x + y + w + h */);
1157 for (GLint j = 0; j < max_viewports; ++j)
1159 data[j * 4 + 0] = 0.0f;
1160 data[j * 4 + 1] = 0.0f;
1161 data[j * 4 + 2] = 1.0f;
1162 data[j * 4 + 3] = 1.0f;
1165 /* Set width to -1 */
1166 data[i * 4 + 2] = -1.0f;
1168 gl.viewportArrayv(0, max_viewports, &data[0]);
1169 checkGLError(GL_INVALID_VALUE, "viewportArrayv, negative width", test_result);
1171 gl.viewportIndexedf(i /* index */, 0.0f, 0.0f, -1.0f, 1.0f);
1172 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, negative width", test_result);
1174 gl.viewportIndexedfv(i /* index */, &data[i * 4]);
1175 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, negative width", test_result);
1177 /* Set width to 1 and height to -1*/
1178 data[i * 4 + 2] = 1.0f;
1179 data[i * 4 + 3] = -1.0f;
1181 gl.viewportArrayv(0, max_viewports, &data[0]);
1182 checkGLError(GL_INVALID_VALUE, "viewportArrayv, negative height", test_result);
1184 gl.viewportIndexedf(i /* index */, 0.0f, 0.0f, 1.0f, -1.0f);
1185 checkGLError(GL_INVALID_VALUE, "viewportIndexedf, negative height", test_result);
1187 gl.viewportIndexedfv(i /* index */, &data[i * 4]);
1188 checkGLError(GL_INVALID_VALUE, "viewportIndexedfv, negative height", test_result);
1193 * * ScissorArrayv generates INVALID_VALUE when <first> + <count> is greater
1194 * than or equal to the value of MAX_VIEWPORTS;
1197 std::vector<GLint> data;
1198 data.resize(max_viewports * 4 /* x + y + w + h */);
1200 for (GLint i = 0; i < max_viewports; ++i)
1202 data[i * 4 + 0] = 0;
1203 data[i * 4 + 1] = 0;
1204 data[i * 4 + 2] = 1;
1205 data[i * 4 + 3] = 1;
1208 gl.scissorArrayv(0, max_viewports - 1, &data[0]);
1209 checkGLError(GL_NO_ERROR, "scissorArrayv, correct parameters", test_result);
1211 gl.scissorArrayv(max_viewports, 1, &data[0]);
1212 checkGLError(GL_INVALID_VALUE, "scissorArrayv, <first> == GL_MAX_VIEWPORTS", test_result);
1214 gl.scissorArrayv(1, max_viewports - 1, &data[0]);
1215 checkGLError(GL_NO_ERROR, "scissorArrayv, <first> + <count> == GL_MAX_VIEWPORTS", test_result);
1217 gl.scissorArrayv(1, max_viewports, &data[0]);
1218 checkGLError(GL_INVALID_VALUE, "scissorArrayv, <first> + <count> > GL_MAX_VIEWPORTS", test_result);
1222 * * ScissorIndexed and ScissorIndexedv generate INVALID_VALUE when <index> is
1223 * greater than or equal to the value of MAX_VIEWPORTS;
1226 GLint data[4 /* x + y + w + h */];
1233 gl.scissorIndexed(0 /* index */, 0, 0, 1, 1);
1234 checkGLError(GL_NO_ERROR, "scissorIndexed, <index> == 0", test_result);
1236 gl.scissorIndexed(max_viewports - 1 /* index */, 0, 0, 1, 1);
1237 checkGLError(GL_NO_ERROR, "scissorIndexed, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1239 gl.scissorIndexed(max_viewports /* index */, 0, 0, 1, 1);
1240 checkGLError(GL_INVALID_VALUE, "scissorIndexed, <index> == GL_MAX_VIEWPORTS", test_result);
1242 gl.scissorIndexed(max_viewports + 1 /* index */, 0, 0, 1, 1);
1243 checkGLError(GL_INVALID_VALUE, "scissorIndexed, <index> > GL_MAX_VIEWPORTS", test_result);
1245 gl.scissorIndexedv(0 /* index */, data);
1246 checkGLError(GL_NO_ERROR, "scissorIndexedv, <index> == 0", test_result);
1248 gl.scissorIndexedv(max_viewports - 1 /* index */, data);
1249 checkGLError(GL_NO_ERROR, "scissorIndexedv, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1251 gl.scissorIndexedv(max_viewports /* index */, data);
1252 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, <index> == GL_MAX_VIEWPORTS", test_result);
1254 gl.scissorIndexedv(max_viewports + 1 /* index */, data);
1255 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, <index> > GL_MAX_VIEWPORTS", test_result);
1259 * * ScissorArrayv, ScissorIndexed, ScissorIndexedv and Scissor generate
1260 * INVALID_VALUE when <width> or <height> values are negative;
1263 gl.scissor(0, 0, -1, 1);
1264 checkGLError(GL_INVALID_VALUE, "scissor, negative width", test_result);
1266 gl.scissor(0, 0, 1, -1);
1267 checkGLError(GL_INVALID_VALUE, "scissor, negative height", test_result);
1269 for (GLint i = 0; i < max_viewports; ++i)
1271 std::vector<GLint> data;
1272 data.resize(max_viewports * 4 /* x + y + w + h */);
1274 for (GLint j = 0; j < max_viewports; ++j)
1276 data[j * 4 + 0] = 0;
1277 data[j * 4 + 1] = 0;
1278 data[j * 4 + 2] = 1;
1279 data[j * 4 + 3] = 1;
1282 /* Set width to -1 */
1283 data[i * 4 + 2] = -1;
1285 gl.scissorArrayv(0, max_viewports, &data[0]);
1286 checkGLError(GL_INVALID_VALUE, "scissorArrayv, negative width", test_result);
1288 gl.scissorIndexed(i /* index */, 0, 0, -1, 1);
1289 checkGLError(GL_INVALID_VALUE, "scissorIndexed, negative width", test_result);
1291 gl.scissorIndexedv(i /* index */, &data[i * 4]);
1292 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, negative width", test_result);
1294 /* Set width to 1 and height to -1*/
1295 data[i * 4 + 2] = 1;
1296 data[i * 4 + 3] = -1;
1298 gl.scissorArrayv(0, max_viewports, &data[0]);
1299 checkGLError(GL_INVALID_VALUE, "scissorArrayv, negative height", test_result);
1301 gl.scissorIndexed(i /* index */, 0, 0, 1, -1);
1302 checkGLError(GL_INVALID_VALUE, "scissorIndexed, negative height", test_result);
1304 gl.scissorIndexedv(i /* index */, &data[i * 4]);
1305 checkGLError(GL_INVALID_VALUE, "scissorIndexedv, negative height", test_result);
1310 * * Disablei, Enablei and IsEnabledi generate INVALID_VALUE when <cap> is
1311 * SCISSOR_TEST and <index> is greater than or equal to the
1312 * value of MAX_VIEWPORTS;
1315 gl.disablei(GL_SCISSOR_TEST, max_viewports - 1);
1316 checkGLError(GL_NO_ERROR, "disablei, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1318 gl.disablei(GL_SCISSOR_TEST, max_viewports);
1319 checkGLError(GL_INVALID_VALUE, "disablei, <index> == GL_MAX_VIEWPORTS", test_result);
1321 gl.enablei(GL_SCISSOR_TEST, max_viewports - 1);
1322 checkGLError(GL_NO_ERROR, "enablei, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1324 gl.enablei(GL_SCISSOR_TEST, max_viewports);
1325 checkGLError(GL_INVALID_VALUE, "enablei, <index> == GL_MAX_VIEWPORTS", test_result);
1327 gl.isEnabledi(GL_SCISSOR_TEST, max_viewports - 1);
1328 checkGLError(GL_NO_ERROR, "isEnabledi, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1330 gl.isEnabledi(GL_SCISSOR_TEST, max_viewports);
1331 checkGLError(GL_INVALID_VALUE, "isEnabledi, <index> == GL_MAX_VIEWPORTS", test_result);
1335 * * GetIntegeri_v generates INVALID_VALUE when <target> is SCISSOR_BOX and
1336 * <index> is greater than or equal to the value of MAX_VIEWPORTS;
1341 gl.getIntegeri_v(GL_SCISSOR_BOX, max_viewports - 1, data);
1342 checkGLError(GL_NO_ERROR, "getIntegeri_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1344 gl.getIntegeri_v(GL_SCISSOR_BOX, max_viewports, data);
1345 checkGLError(GL_INVALID_VALUE, "getIntegeri_v, <index> == GL_MAX_VIEWPORTS", test_result);
1349 * * GetFloati_v generates INVALID_VALUE when <target> is VIEWPORT and <index>
1350 * is greater than or equal to the value of MAX_VIEWPORTS;
1355 gl.getFloati_v(GL_VIEWPORT, max_viewports - 1, data);
1356 checkGLError(GL_NO_ERROR, "getFloati_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1358 gl.getFloati_v(GL_VIEWPORT, max_viewports, data);
1359 checkGLError(GL_INVALID_VALUE, "getFloati_v, <index> == GL_MAX_VIEWPORTS", test_result);
1363 * * GetDoublei_v generates INVALID_VALUE when <target> is DEPTH_RANGE and
1364 * <index> is greater than or equal to the value of MAX_VIEWPORTS;
1369 gl.getDoublei_v(GL_DEPTH_RANGE, max_viewports - 1, data);
1370 checkGLError(GL_NO_ERROR, "getDoublei_v, <index> == GL_MAX_VIEWPORTS - 1", test_result);
1372 gl.getDoublei_v(GL_DEPTH_RANGE, max_viewports, data);
1373 checkGLError(GL_INVALID_VALUE, "getDoublei_v, <index> == GL_MAX_VIEWPORTS", test_result);
1377 if (true == test_result)
1379 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1383 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1387 return tcu::TestNode::STOP;
1390 /** Check if glGetError returns expected error
1392 * @param expected_error Expected error code
1393 * @param description Description of test case
1394 * @param out_result Set to false if the current error is not equal to expected one
1396 void APIErrors::checkGLError(GLenum expected_error, const GLchar* description, bool& out_result)
1398 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1400 GLenum error = gl.getError();
1402 if (expected_error != error)
1404 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case fail. Description: " << description
1405 << " Invalid error: " << glu::getErrorStr(error)
1406 << " expected: " << glu::getErrorStr(expected_error)
1407 << tcu::TestLog::EndMessage;
1415 * @param context Test context
1417 Queries::Queries(deqp::Context& context, const glcts::ExtParameters& extParams)
1418 : TestCaseBase(context, extParams, "queries", "Test verifies initial state of API")
1420 /* Nothing to be done here */
1425 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1427 tcu::TestNode::IterateResult Queries::iterate()
1429 /* GL entry points */
1430 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1433 bool test_result = true;
1435 GLint layer_provoking_vertex = 0;
1436 GLint max_viewports = 0;
1437 GLfloat max_renderbuffer_size = 0.0f;
1438 GLfloat max_viewport_dims[2] = { 0.0f, 0.0f };
1439 GLfloat viewport_bounds_range[2] = { 0.0, 0.0f };
1440 GLint viewport_provoking_vertex = 0;
1441 GLint viewport_subpixel_bits = -1;
1443 gl.getIntegerv(GL_LAYER_PROVOKING_VERTEX, &layer_provoking_vertex);
1444 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1446 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1447 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1449 gl.getFloatv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
1450 GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");
1452 gl.getFloatv(GL_MAX_VIEWPORT_DIMS, max_viewport_dims);
1453 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloatv");
1455 gl.getFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewport_bounds_range);
1456 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloatv");
1458 gl.getIntegerv(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, &viewport_provoking_vertex);
1459 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1461 gl.getIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &viewport_subpixel_bits);
1462 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1464 const GLint window_width = m_context.getRenderContext().getRenderTarget().getWidth();
1465 const GLint window_height = m_context.getRenderContext().getRenderTarget().getHeight();
1468 * * Initial dimensions of VIEWPORT returned by GetFloati_v match dimensions of
1469 * the window into which GL is rendering;
1472 std::vector<GLfloat> data;
1473 data.resize(max_viewports * 4 /* x + y + w+ h */);
1475 for (GLint i = 0; i < max_viewports; ++i)
1477 gl.getFloati_v(GL_VIEWPORT, i, &data[i * 4]);
1478 GLU_EXPECT_NO_ERROR(gl.getError(), "GetFloati_v");
1481 for (GLint i = 0; i < max_viewports; ++i)
1483 GLint viewport_width = (GLint)data[4 * i + 2];
1484 GLint viewport_height = (GLint)data[4 * i + 3];
1486 if ((window_width != viewport_width) || (window_height != viewport_height))
1488 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial viewport [" << i
1489 << "] dimennsions: " << viewport_width << " x " << viewport_height
1490 << " expected: " << window_width << " x " << window_height
1491 << tcu::TestLog::EndMessage;
1493 test_result = false;
1500 * * Initial values of DEPTH_RANGE returned by GetDoublei_v are [0, 1];
1503 std::vector<GLdouble> data;
1504 data.resize(max_viewports * 2 /* near + far */);
1506 for (GLint i = 0; i < max_viewports; ++i)
1508 gl.getDoublei_v(GL_DEPTH_RANGE, i, &data[i * 2]);
1509 GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublei_v");
1512 for (GLint i = 0; i < max_viewports; ++i)
1514 GLint near = (GLint)data[2 * i + 0];
1515 GLint far = (GLint)data[2 * i + 1];
1517 if ((0.0 != near) || (1.0 != far))
1519 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial depth range [" << i
1520 << "]: " << near << " : " << far << " expected: 0.0 : 1.0"
1521 << tcu::TestLog::EndMessage;
1523 test_result = false;
1530 * * Initial state of SCISSOR_TEST returned by IsEnabledi is FALSE;
1533 for (GLint i = 0; i < max_viewports; ++i)
1535 if (GL_FALSE != gl.isEnabledi(GL_SCISSOR_TEST, i))
1537 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Scissor test is enabled at " << i
1538 << ". Expected disabled." << tcu::TestLog::EndMessage;
1540 test_result = false;
1547 * * Initial dimensions of SCISSOR_BOX returned by GetIntegeri_v are either
1548 * zeros or match dimensions of the window into which GL is rendering;
1551 std::vector<GLint> data;
1552 data.resize(max_viewports * 4 /* x + y + w+ h */);
1554 for (GLint i = 0; i < max_viewports; ++i)
1556 gl.getIntegeri_v(GL_VIEWPORT, i, &data[i * 4]);
1557 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegeri_v");
1560 for (GLint i = 0; i < max_viewports; ++i)
1562 GLint scissor_width = data[4 * i + 2];
1563 GLint scissor_height = data[4 * i + 3];
1565 if ((window_width != scissor_width) || (window_height != scissor_height))
1567 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid initial scissor box [" << i
1568 << "] dimennsions: " << scissor_width << " x " << scissor_height
1569 << " expected: " << window_width << " x " << window_height
1570 << tcu::TestLog::EndMessage;
1572 test_result = false;
1579 * * Dimensions of MAX_VIEWPORT_DIMS returned by GetFloati_v are at least
1580 * as big as supported dimensions of render buffers, see MAX_RENDERBUFFER_SIZE;
1583 if ((max_viewport_dims[0] < max_renderbuffer_size) || (max_viewport_dims[1] < max_renderbuffer_size))
1585 m_context.getTestContext().getLog()
1586 << tcu::TestLog::Message << "Invalid MAX_VIEWPORT_DIMS: " << max_viewport_dims[0] << " x "
1587 << max_viewport_dims[1] << " expected: " << max_renderbuffer_size << " x " << max_renderbuffer_size
1588 << tcu::TestLog::EndMessage;
1590 test_result = false;
1595 * * Value of MAX_VIEWPORTS returned by GetIntegeri_v is at least 16;
1598 if (16 > max_viewports)
1600 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid MAX_VIEWPORTS: " << max_viewports
1601 << " expected at least 16." << tcu::TestLog::EndMessage;
1603 test_result = false;
1608 * * Value of VIEWPORT_SUBPIXEL_BITS returned by GetIntegeri_v is at least 0;
1611 if (0 > viewport_subpixel_bits)
1613 m_context.getTestContext().getLog() << tcu::TestLog::Message
1614 << "Invalid VIEWPORT_SUBPIXEL_BITS: " << viewport_subpixel_bits
1615 << " expected at least 0." << tcu::TestLog::EndMessage;
1617 test_result = false;
1622 * * Values of VIEWPORT_BOUNDS_RANGE returned by GetFloatv are
1623 * at least [-32768, 32767];
1626 if ((-32768.0f < viewport_bounds_range[0]) || (32768.0f > viewport_bounds_range[1]))
1628 m_context.getTestContext().getLog()
1629 << tcu::TestLog::Message << "Invalid VIEWPORT_BOUNDS_RANGE: " << viewport_bounds_range[0] << " : "
1630 << viewport_bounds_range[1] << " expected at least: -32768.0f : 32768.0f" << tcu::TestLog::EndMessage;
1632 test_result = false;
1637 * * Values of LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
1638 * returned by GetIntegerv are located in the following set
1639 * { FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, PROVOKING_VERTEX,
1640 * UNDEFINED_VERTEX };
1643 switch (layer_provoking_vertex)
1645 case GL_FIRST_VERTEX_CONVENTION:
1646 case GL_LAST_VERTEX_CONVENTION:
1647 case GL_PROVOKING_VERTEX:
1648 case GL_UNDEFINED_VERTEX:
1651 m_context.getTestContext().getLog() << tcu::TestLog::Message
1652 << "Invalid LAYER_PROVOKING_VERTEX: " << layer_provoking_vertex
1653 << tcu::TestLog::EndMessage;
1655 test_result = false;
1658 switch (viewport_provoking_vertex)
1660 case GL_FIRST_VERTEX_CONVENTION:
1661 case GL_LAST_VERTEX_CONVENTION:
1662 case GL_PROVOKING_VERTEX:
1663 case GL_UNDEFINED_VERTEX:
1666 m_context.getTestContext().getLog() << tcu::TestLog::Message
1667 << "Invalid LAYER_PROVOKING_VERTEX: " << layer_provoking_vertex
1668 << tcu::TestLog::EndMessage;
1670 test_result = false;
1675 if (true == test_result)
1677 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1681 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1685 return tcu::TestNode::STOP;
1688 /* Constants used by ViewportAPI */
1689 const GLuint ViewportAPI::m_n_elements = 4;
1693 * @param context Test context
1695 ViewportAPI::ViewportAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
1696 : TestCaseBase(context, extParams, "viewport_api", "Test verifies that \viewport api\" works as expected")
1698 /* Nothing to be done here */
1703 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1705 tcu::TestNode::IterateResult ViewportAPI::iterate()
1707 /* GL entry points */
1708 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1711 bool test_result = true;
1713 GLint max_viewports = 0;
1715 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1716 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1718 std::vector<GLfloat> scissor_box_data_a;
1719 std::vector<GLfloat> scissor_box_data_b;
1721 scissor_box_data_a.resize(max_viewports * m_n_elements);
1722 scissor_box_data_b.resize(max_viewports * m_n_elements);
1725 * - get initial dimensions of VIEWPORT for all MAX_VIEWPORTS indices;
1726 * - change location and dimensions of all indices at once with
1728 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1730 getViewports(max_viewports, scissor_box_data_a);
1732 for (GLint i = 0; i < max_viewports; ++i)
1734 scissor_box_data_a[i * m_n_elements + 0] += 0.125f;
1735 scissor_box_data_a[i * m_n_elements + 1] += 0.125f;
1736 scissor_box_data_a[i * m_n_elements + 2] -= 0.125f;
1737 scissor_box_data_a[i * m_n_elements + 3] -= 0.125f;
1740 gl.viewportArrayv(0, max_viewports, &scissor_box_data_a[0]);
1741 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportArrayv");
1743 getViewports(max_viewports, scissor_box_data_b);
1744 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportArrayv", test_result);
1748 * * modify with ViewportIndexedf,
1749 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1751 for (GLint i = 0; i < max_viewports; ++i)
1753 scissor_box_data_b[i * m_n_elements + 0] = 0.25f;
1754 scissor_box_data_b[i * m_n_elements + 1] = 0.25f;
1755 scissor_box_data_b[i * m_n_elements + 2] = 0.75f;
1756 scissor_box_data_b[i * m_n_elements + 3] = 0.75f;
1758 gl.viewportIndexedf(i, 0.25f, 0.25f, 0.75f, 0.75f);
1759 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportIndexedf");
1761 getViewports(max_viewports, scissor_box_data_a);
1762 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportIndexedf", test_result);
1767 * * modify with ViewportIndexedfv,
1768 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1770 for (GLint i = 0; i < max_viewports; ++i)
1772 scissor_box_data_a[i * m_n_elements + 0] = 0.375f;
1773 scissor_box_data_a[i * m_n_elements + 1] = 0.375f;
1774 scissor_box_data_a[i * m_n_elements + 2] = 0.625f;
1775 scissor_box_data_a[i * m_n_elements + 3] = 0.625f;
1777 gl.viewportIndexedfv(i, &scissor_box_data_a[i * m_n_elements]);
1778 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportIndexedfv");
1780 getViewports(max_viewports, scissor_box_data_b);
1781 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportIndexedfv", test_result);
1786 * * modify all indices before and after current one with ViewportArrayv,
1787 * * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1789 for (GLint i = 0; i < max_viewports; ++i)
1791 const GLfloat value = (0 == i % 2) ? 1.0f : 0.25f;
1793 for (GLint j = 0; j < i; ++j)
1795 scissor_box_data_b[j * m_n_elements + 0] = value;
1796 scissor_box_data_b[j * m_n_elements + 1] = value;
1797 scissor_box_data_b[j * m_n_elements + 2] = value;
1798 scissor_box_data_b[j * m_n_elements + 3] = value;
1801 for (GLint j = i + 1; j < max_viewports; ++j)
1803 scissor_box_data_b[j * m_n_elements + 0] = value;
1804 scissor_box_data_b[j * m_n_elements + 1] = value;
1805 scissor_box_data_b[j * m_n_elements + 2] = value;
1806 scissor_box_data_b[j * m_n_elements + 3] = value;
1809 gl.viewportArrayv(0, max_viewports, &scissor_box_data_b[0]);
1810 GLU_EXPECT_NO_ERROR(gl.getError(), "viewportArrayv");
1812 getViewports(max_viewports, scissor_box_data_a);
1813 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewportArrayv", test_result);
1817 * - change location and dimensions of all indices at once with Viewport;
1818 * - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
1820 for (GLint i = 0; i < max_viewports; ++i)
1822 scissor_box_data_a[i * m_n_elements + 0] = 0.0f;
1823 scissor_box_data_a[i * m_n_elements + 1] = 0.0f;
1824 scissor_box_data_a[i * m_n_elements + 2] = 1.0f;
1825 scissor_box_data_a[i * m_n_elements + 3] = 1.0f;
1828 gl.viewport(0, 0, 1, 1);
1829 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
1831 getViewports(max_viewports, scissor_box_data_b);
1832 compareViewports(scissor_box_data_a, scissor_box_data_b, "viewport", test_result);
1835 if (true == test_result)
1837 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1841 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1845 return tcu::TestNode::STOP;
1848 /** Compare two sets of viewport data (simple vector comparison)
1850 * @param left Left set
1851 * @param right Right set
1852 * @param description Test case description
1853 * @param out_result Set to false if sets are different, not modified otherwise
1855 void ViewportAPI::compareViewports(std::vector<GLfloat>& left, std::vector<GLfloat>& right, const GLchar* description,
1858 for (size_t i = 0; i < left.size(); ++i)
1860 if (left[i] != right[i])
1862 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
1863 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
1864 << tcu::TestLog::EndMessage;
1871 /** Get position of all viewports
1873 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
1874 * @param data Memory buffer prepared for captured data
1876 void ViewportAPI::getViewports(GLint max_viewports, std::vector<GLfloat>& out_data)
1878 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1880 for (GLint i = 0; i < max_viewports; ++i)
1882 gl.getFloati_v(GL_VIEWPORT, i, &out_data[i * 4]);
1883 GLU_EXPECT_NO_ERROR(gl.getError(), "getFloati_v");
1887 /* Constants used by ScissorAPI */
1888 const GLuint ScissorAPI::m_n_elements = 4;
1892 * @param context Test context
1894 ScissorAPI::ScissorAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
1895 : TestCaseBase(context, extParams, "scissor_api", "Test verifies that \"scissor api\" works as expected")
1897 /* Nothing to be done here */
1902 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
1904 tcu::TestNode::IterateResult ScissorAPI::iterate()
1906 /* GL entry points */
1907 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1910 bool test_result = true;
1912 GLint max_viewports = 0;
1914 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
1915 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
1917 std::vector<GLint> scissor_box_data_a;
1918 std::vector<GLint> scissor_box_data_b;
1920 scissor_box_data_a.resize(max_viewports * m_n_elements);
1921 scissor_box_data_b.resize(max_viewports * m_n_elements);
1924 * - get initial dimensions of SCISSOR_BOX for all MAX_VIEWPORTS indices;
1925 * - change location and dimensions of all indices at once with
1927 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1929 getScissorBoxes(max_viewports, scissor_box_data_a);
1931 for (GLint i = 0; i < max_viewports; ++i)
1933 scissor_box_data_a[i * m_n_elements + 0] += 1;
1934 scissor_box_data_a[i * m_n_elements + 1] += 1;
1935 scissor_box_data_a[i * m_n_elements + 2] -= 1;
1936 scissor_box_data_a[i * m_n_elements + 3] -= 1;
1939 gl.scissorArrayv(0, max_viewports, &scissor_box_data_a[0]);
1940 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorArrayv");
1942 getScissorBoxes(max_viewports, scissor_box_data_b);
1943 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorArrayv", test_result);
1947 * * modify with ScissorIndexed,
1948 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1950 for (GLint i = 0; i < max_viewports; ++i)
1952 scissor_box_data_b[i * m_n_elements + 0] = 4;
1953 scissor_box_data_b[i * m_n_elements + 1] = 4;
1954 scissor_box_data_b[i * m_n_elements + 2] = 8;
1955 scissor_box_data_b[i * m_n_elements + 3] = 8;
1957 gl.scissorIndexed(i, 4, 4, 8, 8);
1958 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorIndexed");
1960 getScissorBoxes(max_viewports, scissor_box_data_a);
1961 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorIndexed", test_result);
1966 * * modify with ScissorIndexedv,
1967 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1969 for (GLint i = 0; i < max_viewports; ++i)
1971 scissor_box_data_a[i * m_n_elements + 0] = 8;
1972 scissor_box_data_a[i * m_n_elements + 1] = 8;
1973 scissor_box_data_a[i * m_n_elements + 2] = 12;
1974 scissor_box_data_a[i * m_n_elements + 3] = 12;
1976 gl.scissorIndexedv(i, &scissor_box_data_a[i * m_n_elements]);
1977 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorIndexedv");
1979 getScissorBoxes(max_viewports, scissor_box_data_b);
1980 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorIndexedv", test_result);
1985 * * modify all indices before and after current one with ScissorArrayv,
1986 * * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
1988 for (GLint i = 0; i < max_viewports; ++i)
1990 const GLint value = (0 == i % 2) ? 1 : 4;
1992 for (GLint j = 0; j < i; ++j)
1994 scissor_box_data_b[j * m_n_elements + 0] = value;
1995 scissor_box_data_b[j * m_n_elements + 1] = value;
1996 scissor_box_data_b[j * m_n_elements + 2] = value;
1997 scissor_box_data_b[j * m_n_elements + 3] = value;
2000 for (GLint j = i + 1; j < max_viewports; ++j)
2002 scissor_box_data_b[j * m_n_elements + 0] = value;
2003 scissor_box_data_b[j * m_n_elements + 1] = value;
2004 scissor_box_data_b[j * m_n_elements + 2] = value;
2005 scissor_box_data_b[j * m_n_elements + 3] = value;
2008 gl.scissorArrayv(0, max_viewports, &scissor_box_data_b[0]);
2009 GLU_EXPECT_NO_ERROR(gl.getError(), "scissorArrayv");
2011 getScissorBoxes(max_viewports, scissor_box_data_a);
2012 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissorArrayv", test_result);
2016 * - change location and dimensions of all indices at once with Scissor;
2017 * - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
2019 for (GLint i = 0; i < max_viewports; ++i)
2021 scissor_box_data_a[i * m_n_elements + 0] = 0;
2022 scissor_box_data_a[i * m_n_elements + 1] = 0;
2023 scissor_box_data_a[i * m_n_elements + 2] = 1;
2024 scissor_box_data_a[i * m_n_elements + 3] = 1;
2027 gl.scissor(0, 0, 1, 1);
2028 GLU_EXPECT_NO_ERROR(gl.getError(), "scissor");
2030 getScissorBoxes(max_viewports, scissor_box_data_b);
2031 compareScissorBoxes(scissor_box_data_a, scissor_box_data_b, "scissor", test_result);
2034 if (true == test_result)
2036 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2040 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2044 return tcu::TestNode::STOP;
2047 /** Compare two sets of scissor box data (simple vector comparison)
2049 * @param left Left set
2050 * @param right Right set
2051 * @param description Test case description
2052 * @param out_result Set to false if sets are different, not modified otherwise
2054 void ScissorAPI::compareScissorBoxes(std::vector<GLint>& left, std::vector<GLint>& right, const GLchar* description,
2057 for (size_t i = 0; i < left.size(); ++i)
2059 if (left[i] != right[i])
2061 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
2062 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
2063 << tcu::TestLog::EndMessage;
2070 /** Get position of all scissor boxes
2072 * @param max_viewports Number of scissor boxes to capture, MAX_VIEWPORTS
2073 * @param data Memory buffer prepared for captured data
2075 void ScissorAPI::getScissorBoxes(GLint max_viewports, std::vector<GLint>& out_data)
2077 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2079 for (GLint i = 0; i < max_viewports; ++i)
2081 gl.getIntegeri_v(GL_SCISSOR_BOX, i, &out_data[i * 4]);
2082 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegeri_v");
2086 /* Constants used by DepthRangeAPI */
2087 const GLuint DepthRangeAPI::m_n_elements = 2 /* near + far */;
2091 * @param context Test context
2093 DepthRangeAPI::DepthRangeAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
2094 : TestCaseBase(context, extParams, "depth_range_api", "Test verifies that \"depth range api\" works as expected")
2096 /* Nothing to be done here */
2101 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
2103 tcu::TestNode::IterateResult DepthRangeAPI::iterate()
2105 /* GL entry points */
2106 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2109 bool test_result = true;
2111 GLint max_viewports = 0;
2113 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
2114 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
2116 std::vector<GLdouble> depth_range_data_a;
2117 std::vector<GLdouble> depth_range_data_b;
2119 depth_range_data_a.resize(max_viewports * m_n_elements);
2120 depth_range_data_b.resize(max_viewports * m_n_elements);
2123 * - get initial values of DEPTH_RANGE for all MAX_VIEWPORTS indices;
2124 * - change values of all indices at once with DepthRangeArrayv;
2125 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2127 getDepthRanges(max_viewports, depth_range_data_a);
2129 for (GLint i = 0; i < max_viewports; ++i)
2131 depth_range_data_a[i * m_n_elements + 0] += 0.125;
2132 depth_range_data_a[i * m_n_elements + 1] -= 0.125;
2135 gl.depthRangeArrayv(0, max_viewports, &depth_range_data_a[0]);
2136 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeArrayv");
2138 getDepthRanges(max_viewports, depth_range_data_b);
2139 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeArrayv", test_result);
2143 * * modify with DepthRangeIndexed,
2144 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2146 for (GLint i = 0; i < max_viewports; ++i)
2148 depth_range_data_b[i * m_n_elements + 0] = 0.25;
2149 depth_range_data_b[i * m_n_elements + 1] = 0.75;
2151 gl.depthRangeIndexed(i, 0.25f, 0.75f);
2152 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeIndexed");
2154 getDepthRanges(max_viewports, depth_range_data_a);
2155 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeIndexed", test_result);
2160 * * modify all indices before and after current one with DepthRangeArrayv,
2161 * * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2163 for (GLint i = 0; i < max_viewports; ++i)
2165 const GLdouble value = (0 == i % 2) ? 1.0 : 0.25;
2167 for (GLint j = 0; j < i; ++j)
2169 depth_range_data_b[j * m_n_elements + 0] = value;
2170 depth_range_data_b[j * m_n_elements + 1] = value;
2173 for (GLint j = i + 1; j < max_viewports; ++j)
2175 depth_range_data_b[j * m_n_elements + 0] = value;
2176 depth_range_data_b[j * m_n_elements + 1] = value;
2179 gl.depthRangeArrayv(0, max_viewports, &depth_range_data_b[0]);
2180 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRangeArrayv");
2182 getDepthRanges(max_viewports, depth_range_data_a);
2183 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRangeArrayv", test_result);
2187 * - change values of all indices at once with DepthRange;
2188 * - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
2190 for (GLint i = 0; i < max_viewports; ++i)
2192 depth_range_data_a[i * m_n_elements + 0] = 0.0f;
2193 depth_range_data_a[i * m_n_elements + 1] = 1.0f;
2196 gl.depthRange(0.0, 1.0);
2197 GLU_EXPECT_NO_ERROR(gl.getError(), "depthRange");
2199 getDepthRanges(max_viewports, depth_range_data_b);
2200 compareDepthRanges(depth_range_data_a, depth_range_data_b, "depthRange", test_result);
2203 if (true == test_result)
2205 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2209 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2213 return tcu::TestNode::STOP;
2216 /** Compare two sets of depth range data (simple vector comparison)
2218 * @param left Left set
2219 * @param right Right set
2220 * @param description Test case description
2221 * @param out_result Set to false if sets are different, not modified otherwise
2223 void DepthRangeAPI::compareDepthRanges(std::vector<GLdouble>& left, std::vector<GLdouble>& right,
2224 const GLchar* description, bool& out_result)
2226 for (size_t i = 0; i < left.size(); ++i)
2228 if (left[i] != right[i])
2230 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
2231 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
2232 << tcu::TestLog::EndMessage;
2239 /** Get all depth ranges
2241 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
2242 * @param data Memory buffer prepared for captured data
2244 void DepthRangeAPI::getDepthRanges(GLint max_viewports, std::vector<GLdouble>& out_data)
2246 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2248 for (GLint i = 0; i < max_viewports; ++i)
2250 gl.getDoublei_v(GL_DEPTH_RANGE, i, &out_data[i * m_n_elements]);
2251 GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublei_v");
2257 * @param context Test context
2259 ScissorTestStateAPI::ScissorTestStateAPI(deqp::Context& context, const glcts::ExtParameters& extParams)
2260 : TestCaseBase(context, extParams, "scissor_test_state_api",
2261 "Test verifies that \"enable/disable api\" works as expected for scissor test")
2263 /* Nothing to be done here */
2268 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
2270 tcu::TestNode::IterateResult ScissorTestStateAPI::iterate()
2272 /* GL entry points */
2273 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2276 bool test_result = true;
2278 GLint max_viewports = 0;
2280 gl.getIntegerv(GL_MAX_VIEWPORTS, &max_viewports);
2281 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
2283 std::vector<GLboolean> scissor_test_states_a;
2284 std::vector<GLboolean> scissor_test_states_b;
2286 scissor_test_states_a.resize(max_viewports);
2287 scissor_test_states_b.resize(max_viewports);
2290 * - get initial state of SCISSOR_TEST for all MAX_VIEWPORTS indices;
2292 * * toggle SCISSOR_TEST,
2293 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2295 * * toggle SCISSOR_TEST,
2296 * * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2298 getScissorTestStates(max_viewports, scissor_test_states_a);
2300 for (GLint i = 0; i < max_viewports; ++i)
2302 if (GL_FALSE == scissor_test_states_a[i])
2304 gl.enablei(GL_SCISSOR_TEST, i);
2305 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
2307 scissor_test_states_a[i] = GL_TRUE;
2311 gl.disablei(GL_SCISSOR_TEST, i);
2312 GLU_EXPECT_NO_ERROR(gl.getError(), "Disablei");
2314 scissor_test_states_a[i] = GL_FALSE;
2317 getScissorTestStates(max_viewports, scissor_test_states_b);
2318 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "1st toggle", test_result);
2321 for (GLint i = 0; i < max_viewports; ++i)
2323 if (GL_FALSE == scissor_test_states_a[i])
2325 gl.enablei(GL_SCISSOR_TEST, i);
2326 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
2328 scissor_test_states_a[i] = GL_TRUE;
2332 gl.disablei(GL_SCISSOR_TEST, i);
2333 GLU_EXPECT_NO_ERROR(gl.getError(), "Disablei");
2335 scissor_test_states_a[i] = GL_FALSE;
2338 getScissorTestStates(max_viewports, scissor_test_states_b);
2339 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "2nd toggle", test_result);
2343 * - enable SCISSOR_TEST for all indices at once with Enable;
2344 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2346 for (GLint i = 0; i < max_viewports; ++i)
2348 scissor_test_states_a[i] = GL_TRUE;
2351 gl.enable(GL_SCISSOR_TEST);
2352 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
2354 getScissorTestStates(max_viewports, scissor_test_states_b);
2355 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "1st enable all", test_result);
2358 * - disable SCISSOR_TEST for all indices at once with Disable;
2359 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2361 for (GLint i = 0; i < max_viewports; ++i)
2363 scissor_test_states_a[i] = GL_FALSE;
2366 gl.disable(GL_SCISSOR_TEST);
2367 GLU_EXPECT_NO_ERROR(gl.getError(), "Disable");
2369 getScissorTestStates(max_viewports, scissor_test_states_b);
2370 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "Disable all", test_result);
2373 * - enable SCISSOR_TEST for all indices at once with Enable;
2374 * - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
2376 for (GLint i = 0; i < max_viewports; ++i)
2378 scissor_test_states_a[i] = GL_TRUE;
2381 gl.enable(GL_SCISSOR_TEST);
2382 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
2384 getScissorTestStates(max_viewports, scissor_test_states_b);
2385 compareScissorTestStates(scissor_test_states_a, scissor_test_states_b, "2nd enable all", test_result);
2388 if (true == test_result)
2390 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2394 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2398 return tcu::TestNode::STOP;
2401 /** Compare two sets of depth range data (simple vector comparison)
2403 * @param left Left set
2404 * @param right Right set
2405 * @param description Test case description
2406 * @param out_result Set to false if sets are different, not modified otherwise
2408 void ScissorTestStateAPI::compareScissorTestStates(std::vector<GLboolean>& left, std::vector<GLboolean>& right,
2409 const GLchar* description, bool& out_result)
2411 for (size_t i = 0; i < left.size(); ++i)
2413 if (left[i] != right[i])
2415 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << description
2416 << " Invalid values [" << i << "] " << left[i] << " " << right[i]
2417 << tcu::TestLog::EndMessage;
2424 /** Get all depth ranges
2426 * @param max_viewports Number of viewports to capture, MAX_VIEWPORTS
2427 * @param data Memory buffer prepared for captured data
2429 void ScissorTestStateAPI::getScissorTestStates(GLint max_viewports, std::vector<GLboolean>& out_data)
2431 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2433 for (GLint i = 0; i < max_viewports; ++i)
2435 out_data[i] = gl.isEnabledi(GL_SCISSOR_TEST, i);
2436 GLU_EXPECT_NO_ERROR(gl.getError(), "isEnabledi");
2440 /* Constants used by DrawTestBase */
2441 const GLuint DrawTestBase::m_depth = 16;
2442 const GLuint DrawTestBase::m_height = 128;
2443 const GLuint DrawTestBase::m_width = 128;
2444 const GLuint DrawTestBase::m_r32f_height = 2;
2445 const GLuint DrawTestBase::m_r32f_width = 16;
2446 const GLuint DrawTestBase::m_r32ix4_depth = 4;
2450 * @param context Test context
2451 * @param test_name Test name
2452 * @param test_description Test description
2454 DrawTestBase::DrawTestBase(deqp::Context& context, const glcts::ExtParameters& extParams, const GLchar* test_name,
2455 const GLchar* test_description)
2456 : TestCaseBase(context, extParams, test_name, test_description)
2458 /* Nothing to be done here */
2463 * @return tcu::TestNode::CONTINUE after executing test case, tcu::TestNode::STOP otherwise
2465 tcu::TestNode::IterateResult DrawTestBase::iterate()
2467 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2470 bool test_result = true;
2472 /* Get type of test */
2473 const TEST_TYPE test_type = getTestType();
2475 GLuint n_draw_calls = getDrawCallsNumber();
2476 GLuint n_iterations = 0;
2488 TCU_FAIL("Invalid enum");
2491 /* Get shader sources */
2492 const std::string& fragment = getFragmentShader();
2493 const std::string& geometry = getGeometryShader();
2494 const std::string& vertex = getVertexShader();
2496 /* Prepare program */
2497 Utils::program program(m_context);
2501 program.build(0 /* compute */, fragment.c_str(), geometry.c_str(), 0 /* tess ctrl */, 0 /* tess eval */,
2502 vertex.c_str(), 0 /* varying names */, 0 /* n_varyings */);
2504 catch (Utils::shaderCompilationException& exc)
2506 /* Something wrong with compilation, test case failed */
2507 tcu::MessageBuilder message = m_context.getTestContext().getLog() << tcu::TestLog::Message;
2509 message << "Shader compilation failed. Error message: " << exc.m_error_message;
2511 Utils::program::printShaderSource(exc.m_shader_source.c_str(), message);
2513 message << tcu::TestLog::EndMessage;
2515 TCU_FAIL("Shader compilation failed");
2517 catch (Utils::programLinkageException& exc)
2519 /* Something wrong with linking, test case failed */
2520 m_context.getTestContext().getLog() << tcu::TestLog::Message
2521 << "Program linking failed. Error message: " << exc.m_error_message
2522 << tcu::TestLog::EndMessage;
2523 TCU_FAIL("Program linking failed");
2529 Utils::vertexArray vao(m_context);
2533 /* For each iteration from test type */
2534 for (GLuint i = 0; i < n_iterations; ++i)
2536 /* Prepare textures */
2537 Utils::texture texture_0(m_context);
2538 Utils::texture texture_1(m_context);
2540 prepareTextures(texture_0, texture_1);
2542 /* Prepare framebuffer */
2543 Utils::framebuffer framebuffer(m_context);
2544 framebuffer.generate();
2545 setupFramebuffer(framebuffer, texture_0, texture_1);
2548 /* Set up viewports */
2549 setupViewports(test_type, i);
2551 if (false == isClearTest())
2553 /* For each draw call */
2554 for (GLuint draw_call = 0; draw_call < n_draw_calls; ++draw_call)
2556 prepareUniforms(program, draw_call);
2559 GLdouble depth_value;
2561 getClearSettings(is_clear, draw_call, depth_value);
2563 if (true == is_clear)
2565 gl.clearDepth(depth_value);
2566 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearDepth");
2568 gl.clear(GL_DEPTH_BUFFER_BIT);
2569 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2572 gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
2573 GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
2575 bool result = checkResults(texture_0, texture_1, draw_call);
2577 if (false == result)
2579 test_result = false;
2586 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
2587 GLU_EXPECT_NO_ERROR(gl.getError(), "ClearColor");
2589 gl.clear(GL_COLOR_BUFFER_BIT);
2590 GLU_EXPECT_NO_ERROR(gl.getError(), "Clear");
2592 bool result = checkResults(texture_0, texture_1, 0);
2594 if (false == result)
2596 test_result = false;
2604 if (true == test_result)
2606 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
2610 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2614 return tcu::TestNode::STOP;
2617 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
2619 * @param texture_0 Verified texture
2623 * @return True if texture_0 is filled with expected pattern
2625 bool DrawTestBase::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
2627 bool check_result = true;
2630 std::vector<GLint> texture_data;
2631 texture_data.resize(m_width * m_height);
2632 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
2634 for (GLuint y = 0; y < 4; ++y)
2636 for (GLuint x = 0; x < 4; ++x)
2638 bool result = checkRegionR32I(x, y, index, &texture_data[0]);
2640 if (false == result)
2642 check_result = false;
2651 return check_result;
2654 /** Get settings of clear operation
2656 * @param clear_depth_before_draw Selects if clear depth should be executed before draw.
2660 void DrawTestBase::getClearSettings(bool& clear_depth_before_draw, GLuint /* iteration_index */,
2661 GLdouble& /* depth_value */)
2663 clear_depth_before_draw = false;
2666 /** Get number of draw call to be executed during test
2670 GLuint DrawTestBase::getDrawCallsNumber()
2679 DrawTestBase::TEST_TYPE DrawTestBase::getTestType()
2684 /** Selects if test should do draw or clear operation
2686 * @return false - draw operation
2688 bool DrawTestBase::isClearTest()
2693 /** Prepare textures used as framebuffer's attachments for current draw call
2695 * @param texture_0 R32I texture
2698 void DrawTestBase::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
2700 prepareTextureR32I(texture_0);
2703 /** Prepare uniforms for given draw call
2708 void DrawTestBase::prepareUniforms(Utils::program& /* program */, GLuint /* draw_call_index */)
2713 /** Attach textures to framebuffer
2715 * @param framebuffer Framebuffer instance
2716 * @param texture_0 Texture attached as color 0
2719 void DrawTestBase::setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
2720 Utils::texture& /* texture_1 */)
2722 framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, texture_0.m_id, m_width, m_height);
2725 /** Check if region specified with <x and <y> is filled with expected value.
2726 * Note: there is assumption that there are 4x4 regions
2728 * @param x X coordinate of region
2729 * @param y Y coordinate of region
2730 * @param expected_value Expected value
2731 * @param data Texture data (not region, but whole texture)
2733 * @return True if region is filled with <expected_value>, false otherwise
2735 bool DrawTestBase::checkRegionR32I(GLuint x, GLuint y, GLint expected_value, GLint* data)
2737 static GLuint width = m_width / 4;
2738 static GLuint height = m_height / 4;
2740 return checkRegionR32I(x, y, width, height, expected_value, data);
2743 /** Check if region specified with <x and <y> is filled with expected value.
2744 * Note: there is assumption that there are 4x4 regions
2746 * @param x X coordinate of region
2747 * @param y Y coordinate of region
2748 * @param width Width of region
2749 * @param height Height of region
2750 * @param expected_value Expected value
2751 * @param data Texture data (not region, but whole texture)
2753 * @return True if region is filled with <expected_value>, false otherwise
2755 bool DrawTestBase::checkRegionR32I(GLuint x, GLuint y, GLuint width, GLuint height, GLint expected_value, GLint* data)
2759 const GLuint offset = (y * height * m_width) + (x * width);
2761 for (GLuint line = 0; line < height; ++line)
2763 const GLuint line_offset = offset + line * m_width;
2765 for (GLuint texel = 0; texel < width; ++texel)
2767 const GLuint texel_offset = line_offset + texel;
2769 const GLint value = data[texel_offset];
2771 if (expected_value != value)
2773 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid result. Region (" << x << "x"
2774 << y << "). Expected: " << expected_value << " got " << value
2775 << tcu::TestLog::EndMessage;
2787 /** Return boiler-plate vertex shader
2789 * @return Source code of vertex shader
2791 std::string DrawTestBase::getVertexShader()
2793 static const GLchar* source = "#version 410 core\n"
2801 std::string result = source;
2806 /** Set up viewports
2808 * @param type Type of test
2809 * @param iteration_index Index of iteration for given test type
2811 void DrawTestBase::setupViewports(TEST_TYPE type, GLuint iteration_index)
2817 VIEWPORT_METHOD method;
2818 switch (iteration_index)
2823 method = (VIEWPORT_METHOD)iteration_index;
2826 TCU_FAIL("Invalid value");
2828 setup4x4Viewport(method);
2833 SCISSOR_METHOD method;
2834 switch (iteration_index)
2839 method = (SCISSOR_METHOD)iteration_index;
2842 TCU_FAIL("Invalid value");
2844 setup4x4Scissor(method, false /* set_zeros */);
2849 DEPTH_RANGE_METHOD method;
2850 switch (iteration_index)
2854 method = (DEPTH_RANGE_METHOD)iteration_index;
2857 TCU_FAIL("Invalid value");
2859 setup16x2Depths(method);
2864 PROVOKING_VERTEX provoking;
2865 switch (iteration_index)
2869 provoking = (PROVOKING_VERTEX)iteration_index;
2872 TCU_FAIL("Invalid value");
2874 setup2x2Viewport(provoking);
2878 TCU_FAIL("Invalid enum");
2882 /** Prepare R32I texture filled with value -1
2884 * @param texture Texture instance
2886 void DrawTestBase::prepareTextureR32I(Utils::texture& texture)
2888 static const GLuint size = m_width * m_height;
2891 for (GLuint i = 0; i < size; ++i)
2896 texture.create(m_width, m_height, GL_R32I);
2897 texture.update(m_width, m_height, 0 /* depth */, GL_RED_INTEGER, GL_INT, data);
2900 /** Prepare R32I array texture filled with value -1, 4 layers
2902 * @param texture Texture instance
2904 void DrawTestBase::prepareTextureR32Ix4(Utils::texture& texture)
2906 static const GLuint size = m_width * m_height * m_r32ix4_depth;
2908 std::vector<GLint> data;
2911 for (GLuint i = 0; i < size; ++i)
2916 texture.create(m_width, m_height, m_r32ix4_depth, GL_R32I);
2917 texture.update(m_width, m_height, m_r32ix4_depth, GL_RED_INTEGER, GL_INT, &data[0]);
2920 /** Prepare R32I array texture filled with value -1
2922 * @param texture Texture instance
2924 void DrawTestBase::prepareTextureArrayR32I(Utils::texture& texture)
2926 static const GLuint size = m_width * m_height * m_depth;
2928 std::vector<GLint> data;
2931 for (GLuint i = 0; i < size; ++i)
2936 texture.create(m_width, m_height, m_depth, GL_R32I);
2937 texture.update(m_width, m_height, m_depth, GL_RED_INTEGER, GL_INT, &data[0]);
2940 /** Prepare R32F texture filled with value -1
2942 * @param texture Texture instance
2944 void DrawTestBase::prepareTextureR32F(Utils::texture& texture)
2946 static const GLuint size = m_r32f_width * m_r32f_height;
2949 for (GLuint i = 0; i < size; ++i)
2954 texture.create(m_r32f_width, m_r32f_height, GL_R32F);
2955 texture.update(m_r32f_width, m_r32f_height, 0 /* depth */, GL_RED, GL_FLOAT, data);
2958 /** Prepare D32F texture filled with value -1
2960 * @param texture Texture instance
2962 void DrawTestBase::prepareTextureD32F(Utils::texture& texture)
2964 static const GLuint size = m_width * m_height;
2967 for (GLuint i = 0; i < size; ++i)
2972 texture.create(m_width, m_height, GL_DEPTH_COMPONENT32F);
2973 texture.update(m_width, m_height, 0 /* depth */, GL_DEPTH_COMPONENT, GL_FLOAT, data);
2976 /** Set up 16 viewports and depth ranges horizontally
2978 * @param method Method used to set depth ranges
2980 void DrawTestBase::setup16x2Depths(DEPTH_RANGE_METHOD method)
2982 static const GLdouble step = 1.0 / 16.0;
2984 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2986 GLdouble depth_data[16 * 2];
2987 GLfloat viewport_data[16 * 4];
2989 for (GLuint i = 0; i < 16; ++i)
2991 const GLdouble near = step * (GLdouble)i;
2993 depth_data[i * 2 + 0] = near;
2994 depth_data[i * 2 + 1] = 1.0 - near;
2996 viewport_data[i * 4 + 0] = (GLfloat)i;
2997 viewport_data[i * 4 + 1] = 0.0f;
2998 viewport_data[i * 4 + 2] = 1.0f;
2999 viewport_data[i * 4 + 3] = 2.0f;
3002 gl.viewportArrayv(0 /* first */, 16 /* count */, viewport_data);
3003 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3007 case DEPTHRANGEINDEXED:
3008 for (GLuint i = 0; i < 16; ++i)
3010 gl.depthRangeIndexed(i, depth_data[i * 2 + 0], depth_data[i * 2 + 1]);
3011 GLU_EXPECT_NO_ERROR(gl.getError(), "DepthRangeIndexed");
3015 case DEPTHRANGEARRAYV:
3016 gl.depthRangeArrayv(0 /* first */, 16 /* count */, depth_data);
3017 GLU_EXPECT_NO_ERROR(gl.getError(), "DepthRangeArrayv");
3021 TCU_FAIL("Invalid enum");
3025 /** Set up 4x4 scissor boxes with enabled test
3027 * @param method Method used to set scissor boxes
3028 * @param set_zeros Select if width and height should be 0 or image_dim / 4
3030 void DrawTestBase::setup4x4Scissor(SCISSOR_METHOD method, bool set_zeros)
3032 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3034 for (GLuint i = 0; i < 16; ++i)
3036 gl.enablei(GL_SCISSOR_TEST, i);
3037 GLU_EXPECT_NO_ERROR(gl.getError(), "Enablei");
3041 GLint data[16 * 4 /* 4x4 * (x + y + w + h) */];
3043 GLint width = m_width / 4;
3044 GLint height = m_height / 4;
3046 for (GLuint y = 0; y < 4; ++y)
3048 for (GLuint x = 0; x < 4; ++x)
3050 data[index * 4 + 0] = x * width;
3051 data[index * 4 + 1] = y * height;
3052 if (false == set_zeros)
3054 data[index * 4 + 2] = width;
3055 data[index * 4 + 3] = height;
3059 data[index * 4 + 2] = 0;
3060 data[index * 4 + 3] = 0;
3070 gl.scissorArrayv(0 /* first */, 16 /*count */, data);
3071 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorArrayv");
3073 case SCISSORINDEXEDF:
3074 for (GLuint i = 0; i < 16; ++i)
3076 const GLint x = data[i * 4 + 0];
3077 const GLint y = data[i * 4 + 1];
3078 const GLint w = data[i * 4 + 2];
3079 const GLint h = data[i * 4 + 3];
3081 gl.scissorIndexed(i, x, y, w, h);
3082 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorIndexed");
3085 case SCISSORINDEXEDF_V:
3086 for (GLuint i = 0; i < 16; ++i)
3088 gl.scissorIndexedv(i, &data[i * 4]);
3089 GLU_EXPECT_NO_ERROR(gl.getError(), "ScissorIndexedv");
3093 TCU_FAIL("Invalid enum");
3097 /** Set up 4x4 viewports
3099 * @param method Method used to set viewports
3101 void DrawTestBase::setup4x4Viewport(VIEWPORT_METHOD method)
3103 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3106 GLfloat data[16 * 4 /* 4x4 * (x + y + w + h) */];
3108 GLfloat width = (GLfloat)(m_width / 4);
3109 GLfloat height = (GLfloat)(m_height / 4);
3111 for (GLuint y = 0; y < 4; ++y)
3113 for (GLuint x = 0; x < 4; ++x)
3115 data[index * 4 + 0] = (GLfloat)((GLfloat)x * width);
3116 data[index * 4 + 1] = (GLfloat)((GLfloat)y * height);
3117 data[index * 4 + 2] = width;
3118 data[index * 4 + 3] = height;
3126 case VIEWPORTARRAYV:
3127 gl.viewportArrayv(0 /* first */, 16 /*count */, data);
3128 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3130 case VIEWPORTINDEXEDF:
3131 for (GLuint i = 0; i < 16; ++i)
3133 const GLfloat x = data[i * 4 + 0];
3134 const GLfloat y = data[i * 4 + 1];
3135 const GLfloat w = data[i * 4 + 2];
3136 const GLfloat h = data[i * 4 + 3];
3138 gl.viewportIndexedf(i, x, y, w, h);
3139 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3142 case VIEWPORTINDEXEDF_V:
3143 for (GLuint i = 0; i < 16; ++i)
3145 gl.viewportIndexedfv(i, &data[i * 4]);
3146 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3150 TCU_FAIL("Invalid enum");
3154 /** Set up 4x4 viewports
3156 * @param method Method used to set viewports
3158 void DrawTestBase::setup2x2Viewport(PROVOKING_VERTEX provoking)
3160 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3163 GLfloat data[4 * 4 /* 4x4 * (x + y + w + h) */];
3165 GLfloat width = (GLfloat)(m_width / 2);
3166 GLfloat height = (GLfloat)(m_height / 2);
3168 for (GLuint y = 0; y < 2; ++y)
3170 for (GLuint x = 0; x < 2; ++x)
3172 data[index * 4 + 0] = (GLfloat)((GLfloat)x * width);
3173 data[index * 4 + 1] = (GLfloat)((GLfloat)y * height);
3174 data[index * 4 + 2] = width;
3175 data[index * 4 + 3] = height;
3181 gl.viewportArrayv(0 /* first */, 4 /*count */, data);
3182 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3188 mode = GL_FIRST_VERTEX_CONVENTION;
3191 mode = GL_LAST_VERTEX_CONVENTION;
3194 TCU_FAIL("Invalid enum");
3197 gl.provokingVertex(mode);
3198 GLU_EXPECT_NO_ERROR(gl.getError(), "ProvokingVertex");
3203 * @param context Test context
3205 DrawToSingleLayerWithMultipleViewports::DrawToSingleLayerWithMultipleViewports(deqp::Context& context,
3206 const glcts::ExtParameters& extParams)
3207 : DrawTestBase(context, extParams, "draw_to_single_layer_with_multiple_viewports",
3208 "Test verifies that multiple viewports can be used to draw to single layer")
3210 /* Nothing to be done here */
3213 /** Get string with fragment shader source code
3215 * @return Fragment shader source
3217 std::string DrawToSingleLayerWithMultipleViewports::getFragmentShader()
3219 static const GLchar* source = "#version 410 core\n"
3221 "flat in int gs_fs_color;\n"
3222 " out int fs_out_color;\n"
3226 " fs_out_color = gs_fs_color;\n"
3230 std::string result = source;
3235 /** Get string with geometry shader source code
3237 * @return Geometry shader source
3239 std::string DrawToSingleLayerWithMultipleViewports::getGeometryShader()
3241 static const GLchar* source = "#version 410 core\n"
3243 "layout(points, invocations = 16) in;\n"
3244 "layout(triangle_strip, max_vertices = 4) out;\n"
3246 "flat out int gs_fs_color;\n"
3250 " gs_fs_color = gl_InvocationID;\n"
3251 " gl_ViewportIndex = gl_InvocationID;\n"
3252 " gl_Position = vec4(-1, -1, 0, 1);\n"
3254 " gs_fs_color = gl_InvocationID;\n"
3255 " gl_ViewportIndex = gl_InvocationID;\n"
3256 " gl_Position = vec4(-1, 1, 0, 1);\n"
3258 " gs_fs_color = gl_InvocationID;\n"
3259 " gl_ViewportIndex = gl_InvocationID;\n"
3260 " gl_Position = vec4(1, -1, 0, 1);\n"
3262 " gs_fs_color = gl_InvocationID;\n"
3263 " gl_ViewportIndex = gl_InvocationID;\n"
3264 " gl_Position = vec4(1, 1, 0, 1);\n"
3269 std::string result = source;
3276 * @param context Test context
3278 DynamicViewportIndex::DynamicViewportIndex(deqp::Context& context, const glcts::ExtParameters& extParams)
3279 : DrawTestBase(context, extParams, "dynamic_viewport_index",
3280 "Test verifies that gl_ViewportIndex can be assigned with dynamic value")
3282 /* Nothing to be done here */
3285 /** Get string with fragment shader source code
3287 * @return Fragment shader source
3289 std::string DynamicViewportIndex::getFragmentShader()
3291 static const GLchar* source = "#version 410 core\n"
3293 "flat in int gs_fs_color;\n"
3294 " out int fs_out_color;\n"
3298 " fs_out_color = gs_fs_color;\n"
3302 std::string result = source;
3307 /** Get string with geometry shader source code
3309 * @return Geometry shader source
3311 std::string DynamicViewportIndex::getGeometryShader()
3313 static const GLchar* source = "#version 410 core\n"
3315 "layout(points, invocations = 1) in;\n"
3316 "layout(triangle_strip, max_vertices = 4) out;\n"
3318 "uniform int uni_index;\n"
3320 "flat out int gs_fs_color;\n"
3324 " gs_fs_color = uni_index;\n"
3325 " gl_ViewportIndex = uni_index;\n"
3326 " gl_Position = vec4(-1, -1, 0, 1);\n"
3328 " gs_fs_color = uni_index;\n"
3329 " gl_ViewportIndex = uni_index;\n"
3330 " gl_Position = vec4(-1, 1, 0, 1);\n"
3332 " gs_fs_color = uni_index;\n"
3333 " gl_ViewportIndex = uni_index;\n"
3334 " gl_Position = vec4(1, -1, 0, 1);\n"
3336 " gs_fs_color = uni_index;\n"
3337 " gl_ViewportIndex = uni_index;\n"
3338 " gl_Position = vec4(1, 1, 0, 1);\n"
3343 std::string result = source;
3348 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3350 * @param texture_0 Verified texture
3352 * @param draw_call_index Draw call that was executed
3354 * @return True if texture_0 is filled with expected pattern
3356 bool DynamicViewportIndex::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3357 GLuint draw_call_index)
3359 bool check_result = true;
3362 std::vector<GLint> texture_data;
3363 texture_data.resize(m_width * m_height);
3364 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3366 for (GLuint y = 0; y < 4; ++y)
3368 for (GLuint x = 0; x < 4; ++x)
3370 GLint expected_value = -1;
3371 if (index <= draw_call_index)
3373 expected_value = index;
3376 bool result = checkRegionR32I(x, y, expected_value, &texture_data[0]);
3378 if (false == result)
3380 check_result = false;
3389 return check_result;
3392 /** Get number of draw call to be executed during test
3396 GLuint DynamicViewportIndex::getDrawCallsNumber()
3401 /** Prepare uniforms for given draw call
3403 * @param program Program object
3404 * @param draw_call_index Index of draw call to be executed
3406 void DynamicViewportIndex::prepareUniforms(Utils::program& program, GLuint draw_call_index)
3408 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3410 GLint location = program.getUniformLocation("uni_index");
3412 gl.uniform1i(location, (GLint)draw_call_index);
3413 GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
3418 * @param context Test context
3420 DrawMulitpleViewportsWithSingleInvocation::DrawMulitpleViewportsWithSingleInvocation(
3421 deqp::Context& context, const glcts::ExtParameters& extParams)
3422 : DrawTestBase(context, extParams, "draw_mulitple_viewports_with_single_invocation",
3423 "Test verifies that single invocation can output to multiple viewports")
3425 /* Nothing to be done here */
3428 /** Get string with fragment shader source code
3430 * @return Fragment shader source
3432 std::string DrawMulitpleViewportsWithSingleInvocation::getFragmentShader()
3434 static const GLchar* source = "#version 410 core\n"
3436 "flat in int gs_fs_color;\n"
3437 " out int fs_out_color;\n"
3441 " fs_out_color = gs_fs_color;\n"
3445 std::string result = source;
3450 /** Get string with geometry shader source code
3452 * @return Geometry shader source
3454 std::string DrawMulitpleViewportsWithSingleInvocation::getGeometryShader()
3456 static const GLchar* source = "#version 410 core\n"
3458 "layout(points, invocations = 1) in;\n"
3459 "layout(triangle_strip, max_vertices = 64) out;\n"
3461 "flat out int gs_fs_color;\n"
3463 "void routine(int index)\n"
3465 " gs_fs_color = index;\n"
3466 " gl_ViewportIndex = index;\n"
3467 " gl_Position = vec4(-1, -1, 0, 1);\n"
3469 " gs_fs_color = index;\n"
3470 " gl_ViewportIndex = index;\n"
3471 " gl_Position = vec4(-1, 1, 0, 1);\n"
3473 " gs_fs_color = index;\n"
3474 " gl_ViewportIndex = index;\n"
3475 " gl_Position = vec4(1, -1, 0, 1);\n"
3477 " gs_fs_color = index;\n"
3478 " gl_ViewportIndex = index;\n"
3479 " gl_Position = vec4(1, 1, 0, 1);\n"
3481 " EndPrimitive();\n"
3486 " for(int i = 0; i < 16; ++i)\n"
3493 std::string result = source;
3500 * @param context Test context
3502 ViewportIndexSubroutine::ViewportIndexSubroutine(deqp::Context& context, const glcts::ExtParameters& extParams)
3503 : DrawTestBase(context, extParams, "viewport_index_subroutine",
3504 "Test verifies subroutines can be used to output data to specific viewport")
3506 /* Nothing to be done here */
3509 /** Get string with fragment shader source code
3511 * @return Fragment shader source
3513 std::string ViewportIndexSubroutine::getFragmentShader()
3515 static const GLchar* source = "#version 410 core\n"
3517 "flat in int gs_fs_color;\n"
3518 " out int fs_out_color;\n"
3522 " fs_out_color = gs_fs_color;\n"
3526 std::string result = source;
3531 /** Get string with geometry shader source code
3533 * @return Geometry shader source
3535 std::string ViewportIndexSubroutine::getGeometryShader()
3537 static const GLchar* source = "#version 410 core\n"
3539 "layout(points, invocations = 1) in;\n"
3540 "layout(triangle_strip, max_vertices = 4) out;\n"
3542 "flat out int gs_fs_color;\n"
3544 "subroutine void indexSetter(void);\n"
3546 "subroutine(indexSetter) void four()\n"
3548 " gs_fs_color = 4;\n"
3549 " gl_ViewportIndex = 4;\n"
3552 "subroutine(indexSetter) void five()\n"
3554 " gs_fs_color = 5;\n"
3555 " gl_ViewportIndex = 5;\n"
3558 "subroutine uniform indexSetter routine;\n"
3563 " gl_Position = vec4(-1, -1, 0, 1);\n"
3566 " gl_Position = vec4(-1, 1, 0, 1);\n"
3569 " gl_Position = vec4(1, -1, 0, 1);\n"
3572 " gl_Position = vec4(1, 1, 0, 1);\n"
3577 std::string result = source;
3582 /** Check if R32I texture is filled with two halves, left is 4, right is either -1 or 5
3584 * @param texture_0 Verified texture
3586 * @param draw_call_index Draw call that was executed
3588 * @return True if texture_0 is filled with expected pattern
3590 bool ViewportIndexSubroutine::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3591 GLuint draw_call_index)
3593 bool check_result = true;
3595 std::vector<GLint> texture_data;
3596 texture_data.resize(m_width * m_height);
3597 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3599 /* Left is 4 and right is -1, or left is 4 and right is 5 */
3600 GLint expected_left = 4;
3601 GLint expected_right = (1 == draw_call_index) ? 5 : -1;
3603 for (GLuint y = 0; y < 4; ++y)
3605 for (GLuint x = 0; x < 2; ++x)
3607 bool result = checkRegionR32I(x, y, expected_left, &texture_data[0]);
3609 if (false == result)
3611 check_result = false;
3617 for (GLuint y = 0; y < 4; ++y)
3619 for (GLuint x = 2; x < 4; ++x)
3621 bool result = checkRegionR32I(x, y, expected_right, &texture_data[0]);
3623 if (false == result)
3625 check_result = false;
3632 return check_result;
3635 /** Get number of draw call to be executed during test
3639 GLuint ViewportIndexSubroutine::getDrawCallsNumber()
3644 /** Prepare uniforms for given draw call
3646 * @param program Program object
3647 * @param draw_call_index Index of draw call to be executed
3649 void ViewportIndexSubroutine::prepareUniforms(Utils::program& program, GLuint draw_call_index)
3651 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3653 const GLchar* subroutine_name = (0 == draw_call_index) ? "four" : "five";
3655 GLint location = program.getSubroutineUniformLocation("routine", GL_GEOMETRY_SHADER);
3656 GLuint index = program.getSubroutineIndex(subroutine_name, GL_GEOMETRY_SHADER);
3660 TCU_FAIL("Something wrong, subroutine uniform location is not 0. Mistake in geometry shader?");
3663 gl.uniformSubroutinesuiv(GL_GEOMETRY_SHADER, 1, &index);
3664 GLU_EXPECT_NO_ERROR(gl.getError(), "UniformSubroutinesuiv");
3667 /** Set 4th viewport on left half and 5 on right half of framebuffer. Rest span over whole image.
3670 * @param iteration_index Index of iteration, used to select "viewport" method
3672 void ViewportIndexSubroutine::setupViewports(TEST_TYPE /* type */, glw::GLuint iteration_index)
3674 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3676 GLfloat data[2 * 4] = { 0.0f, 0.0f, 64.0f, 128.0f, 64.0f, 0.0f, 64.0f, 128.0f };
3678 gl.viewport(0, 0, m_width, m_height);
3679 GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
3681 switch (iteration_index)
3685 gl.viewportArrayv(4, 2, data);
3686 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportArrayv");
3692 gl.viewportIndexedf(4, data[0], data[1], data[2], data[3]);
3693 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3695 gl.viewportIndexedf(5, data[4], data[5], data[6], data[7]);
3696 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedf");
3702 gl.viewportIndexedfv(4, &data[0]);
3703 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3705 gl.viewportIndexedfv(5, &data[4]);
3706 GLU_EXPECT_NO_ERROR(gl.getError(), "ViewportIndexedfv");
3711 TCU_FAIL("Invalid value");
3717 * @param context Test context
3719 DrawMultipleLayers::DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams)
3720 : DrawTestBase(context, extParams, "draw_multiple_layers",
3721 "Test verifies that single viewport affects multiple layers in the same way")
3723 /* Nothing to be done here */
3728 * @param context Test context
3729 * @param test_name Test name
3730 * @param test_description Test description
3732 DrawMultipleLayers::DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams,
3733 const GLchar* test_name, const GLchar* test_description)
3734 : DrawTestBase(context, extParams, test_name, test_description)
3736 /* Nothing to be done here */
3739 /** Get string with fragment shader source code
3741 * @return Fragment shader source
3743 std::string DrawMultipleLayers::getFragmentShader()
3745 static const GLchar* source = "#version 410 core\n"
3747 "flat in int gs_fs_color;\n"
3748 " out int fs_out_color;\n"
3752 " fs_out_color = gs_fs_color;\n"
3756 std::string result = source;
3761 /** Get string with geometry shader source code
3763 * @return Geometry shader source
3765 std::string DrawMultipleLayers::getGeometryShader()
3767 static const GLchar* source = "#version 410 core\n"
3769 "layout(points, invocations = 16) in;\n"
3770 "layout(triangle_strip, max_vertices = 4) out;\n"
3772 "flat out int gs_fs_color;\n"
3776 " gs_fs_color = gl_InvocationID;\n"
3777 " gl_ViewportIndex = gl_InvocationID;\n"
3778 " gl_Layer = gl_InvocationID;\n"
3779 " gl_Position = vec4(-1, -1, 0, 1);\n"
3781 " gs_fs_color = gl_InvocationID;\n"
3782 " gl_ViewportIndex = gl_InvocationID;\n"
3783 " gl_Layer = gl_InvocationID;\n"
3784 " gl_Position = vec4(-1, 1, 0, 1);\n"
3786 " gs_fs_color = gl_InvocationID;\n"
3787 " gl_ViewportIndex = gl_InvocationID;\n"
3788 " gl_Layer = gl_InvocationID;\n"
3789 " gl_Position = vec4(1, -1, 0, 1);\n"
3791 " gs_fs_color = gl_InvocationID;\n"
3792 " gl_ViewportIndex = gl_InvocationID;\n"
3793 " gl_Layer = gl_InvocationID;\n"
3794 " gl_Position = vec4(1, 1, 0, 1);\n"
3799 std::string result = source;
3804 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3806 * @param texture_0 Verified texture
3810 * @return True if texture_0 is filled with expected pattern
3812 bool DrawMultipleLayers::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3813 GLuint /* draw_call_index */)
3815 static const GLuint layer_size = m_width * m_height;
3817 bool check_result = true;
3819 std::vector<GLint> texture_data;
3820 texture_data.resize(layer_size * m_depth);
3821 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3823 /* 16 layers, only region corresponding with layer index should be modified */
3824 for (GLuint layer = 0; layer < m_depth; ++layer)
3828 for (GLuint y = 0; y < 4; ++y)
3830 for (GLuint x = 0; x < 4; ++x)
3832 GLint* layer_data = &texture_data[layer * layer_size];
3834 GLint expected_value = -1;
3837 expected_value = index;
3840 bool result = checkRegionR32I(x, y, expected_value, layer_data);
3842 if (false == result)
3844 check_result = false;
3854 return check_result;
3857 /** Prepare textures used as framebuffer's attachments for current draw call
3859 * @param texture_0 R32I texture
3862 void DrawMultipleLayers::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
3864 prepareTextureArrayR32I(texture_0);
3869 * @param context Test context
3870 * @param test_name Test name
3871 * @param test_description Test description
3873 Scissor::Scissor(deqp::Context& context, const glcts::ExtParameters& extParams)
3874 : DrawMultipleLayers(context, extParams, "scissor", "Test verifies that scissor test is applied as expected")
3876 /* Nothing to be done here */
3883 DrawTestBase::TEST_TYPE Scissor::getTestType()
3890 * @param context Test context
3891 * @param test_name Test name
3892 * @param test_description Test description
3894 ScissorZeroDimension::ScissorZeroDimension(deqp::Context& context, const glcts::ExtParameters& extParams)
3895 : DrawMultipleLayers(context, extParams, "scissor_zero_dimension",
3896 "Test verifies that scissor test discard all fragments when width and height is set to zero")
3898 /* Nothing to be done here */
3901 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3903 * @param texture_0 Verified texture
3907 * @return True if texture_0 is filled with expected pattern
3909 bool ScissorZeroDimension::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
3910 GLuint /* draw_call_index */)
3912 static const GLuint layer_size = m_width * m_height;
3914 bool check_result = true;
3916 std::vector<GLint> texture_data;
3917 texture_data.resize(layer_size * m_depth);
3918 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
3920 /* 16 layers, all regions were not modified */
3921 for (GLuint layer = 0; layer < m_depth; ++layer)
3923 for (GLuint y = 0; y < 4; ++y)
3925 for (GLuint x = 0; x < 4; ++x)
3927 GLint* layer_data = &texture_data[layer * layer_size];
3929 GLint expected_value = -1;
3931 bool result = checkRegionR32I(x, y, expected_value, layer_data);
3933 if (false == result)
3935 check_result = false;
3943 return check_result;
3950 DrawTestBase::TEST_TYPE ScissorZeroDimension::getTestType()
3955 /** Set up viewports
3958 * @param iteration_index Index of iteration for given test type
3960 void ScissorZeroDimension::setupViewports(TEST_TYPE /* type */, GLuint iteration_index)
3962 SCISSOR_METHOD method;
3963 switch (iteration_index)
3968 method = (SCISSOR_METHOD)iteration_index;
3971 TCU_FAIL("Invalid value");
3974 setup4x4Scissor(method, true /* set_zeros */);
3979 * @param context Test context
3980 * @param test_name Test name
3981 * @param test_description Test description
3983 ScissorClear::ScissorClear(deqp::Context& context, const glcts::ExtParameters& extParams)
3984 : DrawMultipleLayers(context, extParams, "scissor_clear",
3985 "Test verifies that Clear is affected only by settings of scissor test in first viewport")
3987 /* Nothing to be done here */
3990 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
3992 * @param texture_0 Verified texture
3996 * @return True if texture_0 is filled with expected pattern
3998 bool ScissorClear::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
4000 static const GLuint layer_size = m_width * m_height;
4002 bool check_result = true;
4004 std::vector<GLint> texture_data;
4005 texture_data.resize(layer_size * m_depth);
4006 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
4008 /* 16 layers, only region corresponding with scissor box 0 should be modified */
4009 for (GLuint layer = 0; layer < m_depth; ++layer)
4011 for (GLuint y = 0; y < 4; ++y)
4013 for (GLuint x = 0; x < 4; ++x)
4015 GLint* layer_data = &texture_data[layer * layer_size];
4017 GLint expected_value = -1;
4018 if ((0 == x) && (0 == y))
4023 bool result = checkRegionR32I(x, y, expected_value, layer_data);
4025 if (false == result)
4027 check_result = false;
4035 return check_result;
4042 DrawTestBase::TEST_TYPE ScissorClear::getTestType()
4047 /** Selects if test should do draw or clear operation
4049 * @return true - clear operation
4051 bool ScissorClear::isClearTest()
4058 * @param context Test context
4059 * @param test_name Test name
4060 * @param test_description Test description
4062 DepthRange::DepthRange(deqp::Context& context, const glcts::ExtParameters& extParams)
4063 : DrawTestBase(context, extParams, "depth_range", "Test verifies that depth range is applied as expected")
4065 /* Nothing to be done here */
4068 /** Check if R32F texture is filled with two rows, top with decreasing values, bottom with incresing values
4070 * @param texture_0 Verified texture
4074 * @return True if texture_0 is filled with expected pattern
4076 bool DepthRange::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */, GLuint /*draw_call_index */)
4078 static const GLfloat step = 1.0f / 16.0f;
4080 bool check_result = true;
4082 std::vector<GLfloat> texture_data;
4083 texture_data.resize(m_r32f_width * m_r32f_height);
4084 texture_0.get(GL_RED, GL_FLOAT, &texture_data[0]);
4086 GLfloat depth_data[16 * 2];
4088 for (GLuint i = 0; i < 16; ++i)
4090 const GLfloat near = step * (GLfloat)i;
4092 depth_data[i * 2 + 0] = near;
4093 depth_data[i * 2 + 1] = 1.0f - near;
4096 for (GLuint i = 0; i < 16; ++i)
4098 const GLfloat expected_near = depth_data[i * 2 + 0];
4099 const GLfloat expected_far = depth_data[i * 2 + 1];
4101 /* Bottom row should contain near values, top one should contain far values */
4102 const GLfloat near = texture_data[i];
4103 const GLfloat far = texture_data[i + 16];
4105 if ((expected_near != near) || (expected_far != far))
4107 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid values at " << i << " expected ["
4108 << expected_near << ", " << expected_far << "] got [" << near << ", "
4109 << far << "]" << tcu::TestLog::EndMessage;
4111 check_result = false;
4116 return check_result;
4119 /** Get string with fragment shader source code
4121 * @return Fragment shader source
4123 std::string DepthRange::getFragmentShader()
4125 static const GLchar* source = "#version 410 core\n"
4127 "out float fs_out_color;\n"
4131 " fs_out_color = gl_FragCoord.z;\n"
4135 std::string result = source;
4140 /** Get string with geometry shader source code
4142 * @return Geometry shader source
4144 std::string DepthRange::getGeometryShader()
4146 static const GLchar* source = "#version 410 core\n"
4148 "layout(points, invocations = 16) in;\n"
4149 "layout(triangle_strip, max_vertices = 8) out;\n"
4153 " const float top_z = 1.0;\n"
4154 " const float bottom_z = -1.0;\n"
4157 " gl_ViewportIndex = gl_InvocationID;\n"
4158 " gl_Position = vec4(-1, -1, bottom_z, 1);\n"
4160 " gl_ViewportIndex = gl_InvocationID;\n"
4161 " gl_Position = vec4(-1, 0, bottom_z, 1);\n"
4163 " gl_ViewportIndex = gl_InvocationID;\n"
4164 " gl_Position = vec4(1, -1, bottom_z, 1);\n"
4166 " gl_ViewportIndex = gl_InvocationID;\n"
4167 " gl_Position = vec4(1, 0, bottom_z, 1);\n"
4169 " EndPrimitive();\n"
4172 " gl_ViewportIndex = gl_InvocationID;\n"
4173 " gl_Position = vec4(-1, 0, top_z, 1);\n"
4175 " gl_ViewportIndex = gl_InvocationID;\n"
4176 " gl_Position = vec4(-1, 1, top_z, 1);\n"
4178 " gl_ViewportIndex = gl_InvocationID;\n"
4179 " gl_Position = vec4(1, 0, top_z, 1);\n"
4181 " gl_ViewportIndex = gl_InvocationID;\n"
4182 " gl_Position = vec4(1, 1, top_z, 1);\n"
4184 " EndPrimitive();\n"
4188 std::string result = source;
4195 * @return DEPTHRANGE
4197 DrawTestBase::TEST_TYPE DepthRange::getTestType()
4202 /** Prepare textures used as framebuffer's attachments for current draw call
4204 * @param texture_0 R32F texture
4207 void DepthRange::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
4209 prepareTextureR32F(texture_0);
4214 * @param context Test context
4215 * @param test_name Test name
4216 * @param test_description Test description
4218 DepthRangeDepthTest::DepthRangeDepthTest(deqp::Context& context, const glcts::ExtParameters& extParams)
4219 : DrawTestBase(context, extParams, "depth_range_depth_test",
4220 "Test verifies that depth test work as expected with multiple viewports")
4222 /* Nothing to be done here */
4225 /** Check if R32F texture is filled with two rows of values less than expected depth
4227 * @param texture_0 Verified texture
4229 * @param draw_call_index Index of draw call
4231 * @return True if texture_0 is filled with expected pattern
4233 bool DepthRangeDepthTest::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
4234 GLuint draw_call_index)
4236 static const GLfloat step = 1.0f / 16.0f;
4238 const GLfloat depth_value = step * (GLfloat)draw_call_index;
4240 bool check_result = true;
4242 std::vector<GLfloat> texture_data;
4243 texture_data.resize(m_r32f_width * m_r32f_height);
4244 texture_0.get(GL_RED, GL_FLOAT, &texture_data[0]);
4246 for (GLuint i = 0; i < 16; ++i)
4248 /* Bottom row should contain near values, top one should contain far values */
4249 const GLfloat near = texture_data[i];
4250 const GLfloat far = texture_data[i + 16];
4252 if ((depth_value <= near) || (depth_value <= far))
4254 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid values at " << i << " depth value "
4255 << depth_value << " got [" << near << ", " << far << "]"
4256 << tcu::TestLog::EndMessage;
4258 check_result = false;
4263 return check_result;
4266 /** Get settings of clear operation
4268 * @param clear_depth_before_draw Selects if clear should be executed before draw.
4269 * @param iteration_index Index of draw call
4270 * @param depth_value Value that will be used to clear depth buffer
4272 void DepthRangeDepthTest::getClearSettings(bool& clear_depth_before_draw, GLuint iteration_index, GLdouble& depth_value)
4274 static const GLdouble step = 1.0 / 16.0;
4276 clear_depth_before_draw = true;
4278 depth_value = step * (GLdouble)iteration_index;
4281 /** Get number of draw call to be executed during test
4285 GLuint DepthRangeDepthTest::getDrawCallsNumber()
4290 /** Get string with fragment shader source code
4292 * @return Fragment shader source
4294 std::string DepthRangeDepthTest::getFragmentShader()
4296 static const GLchar* source = "#version 410 core\n"
4298 "out float fs_out_color;\n"
4302 " fs_out_color = gl_FragCoord.z;\n"
4306 std::string result = source;
4311 /** Get string with geometry shader source code
4313 * @return Geometry shader source
4315 std::string DepthRangeDepthTest::getGeometryShader()
4317 static const GLchar* source = "#version 410 core\n"
4319 "layout(points, invocations = 16) in;\n"
4320 "layout(triangle_strip, max_vertices = 8) out;\n"
4324 " const float top_z = 1.0;\n"
4325 " const float bottom_z = -1.0;\n"
4328 " gl_ViewportIndex = gl_InvocationID;\n"
4329 " gl_Position = vec4(-1, -1, bottom_z, 1);\n"
4331 " gl_ViewportIndex = gl_InvocationID;\n"
4332 " gl_Position = vec4(-1, 0, bottom_z, 1);\n"
4334 " gl_ViewportIndex = gl_InvocationID;\n"
4335 " gl_Position = vec4(1, -1, bottom_z, 1);\n"
4337 " gl_ViewportIndex = gl_InvocationID;\n"
4338 " gl_Position = vec4(1, 0, bottom_z, 1);\n"
4342 " gl_ViewportIndex = gl_InvocationID;\n"
4343 " gl_Position = vec4(-1, 0, top_z, 1);\n"
4345 " gl_ViewportIndex = gl_InvocationID;\n"
4346 " gl_Position = vec4(-1, 1, top_z, 1);\n"
4348 " gl_ViewportIndex = gl_InvocationID;\n"
4349 " gl_Position = vec4(1, 0, top_z, 1);\n"
4351 " gl_ViewportIndex = gl_InvocationID;\n"
4352 " gl_Position = vec4(1, 1, top_z, 1);\n"
4354 " EndPrimitive();\n"
4358 std::string result = source;
4365 * @return DEPTHRANGE
4367 DrawTestBase::TEST_TYPE DepthRangeDepthTest::getTestType()
4372 /** Prepare textures used as framebuffer's attachments for current draw call
4374 * @param texture_0 R32F texture
4375 * @param texture_1 D32F texture
4377 void DepthRangeDepthTest::prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1)
4379 prepareTextureR32F(texture_0);
4380 prepareTextureD32F(texture_1);
4383 /** Attach textures to framebuffer
4385 * @param framebuffer Framebuffer instance
4386 * @param texture_0 Texture attached as color 0
4387 * @param texture_1 Texture attached as depth
4389 void DepthRangeDepthTest::setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
4390 Utils::texture& texture_1)
4392 framebuffer.attachTexture(GL_COLOR_ATTACHMENT0, texture_0.m_id, m_width, m_height);
4393 framebuffer.attachTexture(GL_DEPTH_ATTACHMENT, texture_1.m_id, m_width, m_height);
4396 /** Set up viewports
4399 * @param iteration_index Index of iteration for given test type
4401 void DepthRangeDepthTest::setupViewports(TEST_TYPE /* type */, GLuint iteration_index)
4403 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4405 DEPTH_RANGE_METHOD method;
4406 switch (iteration_index)
4410 method = (DEPTH_RANGE_METHOD)iteration_index;
4413 TCU_FAIL("Invalid value");
4415 setup16x2Depths(method);
4417 gl.enable(GL_DEPTH_TEST);
4418 GLU_EXPECT_NO_ERROR(gl.getError(), "Enable");
4423 * @param context Test context
4424 * @param test_name Test name
4425 * @param test_description Test description
4427 ProvokingVertex::ProvokingVertex(deqp::Context& context, const glcts::ExtParameters& extParams)
4428 : DrawTestBase(context, extParams, "provoking_vertex", "Test verifies that provoking vertex work as expected")
4430 /* Nothing to be done here */
4433 /** Check if R32I texture is filled with 4x4 regions of increasing values <0:15>
4435 * @param texture_0 Verified texture
4439 * @return True if texture_0 is filled with expected pattern
4441 bool ProvokingVertex::checkResults(Utils::texture& texture_0, Utils::texture& /* texture_1 */,
4442 GLuint /*draw_call_index */)
4444 static const GLuint layer_size = m_width * m_height;
4446 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4448 GLint layer_mode = 0;
4449 GLint viewport_mode = 0;
4450 gl.getIntegerv(GL_LAYER_PROVOKING_VERTEX, &layer_mode);
4451 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4452 gl.getIntegerv(GL_VIEWPORT_INDEX_PROVOKING_VERTEX, &viewport_mode);
4453 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4455 if ((GL_UNDEFINED_VERTEX == layer_mode) || (GL_UNDEFINED_VERTEX == viewport_mode))
4457 /* Results are undefined, therefore it does not make sense to verify them */
4461 bool check_result = true;
4462 GLint provoking = 0;
4464 std::vector<GLint> texture_data;
4465 texture_data.resize(layer_size * m_r32ix4_depth);
4466 texture_0.get(GL_RED_INTEGER, GL_INT, &texture_data[0]);
4468 gl.getIntegerv(GL_PROVOKING_VERTEX, &provoking);
4469 GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
4471 GLuint expected_layer = 0;
4472 GLint expected_viewport = 0;
4474 /* Mode is 1st, or mode is provoking and provoking is 1st */
4475 if ((GL_FIRST_VERTEX_CONVENTION == layer_mode) ||
4476 ((GL_PROVOKING_VERTEX == layer_mode) && (GL_FIRST_VERTEX_CONVENTION == provoking)))
4485 if ((GL_FIRST_VERTEX_CONVENTION == viewport_mode) ||
4486 ((GL_PROVOKING_VERTEX == viewport_mode) && (GL_FIRST_VERTEX_CONVENTION == provoking)))
4488 expected_viewport = 0;
4492 expected_viewport = 2;
4495 for (GLuint layer = 0; layer < m_r32ix4_depth; ++layer)
4497 GLint* layer_data = &texture_data[layer * layer_size];
4500 for (GLuint y = 0; y < 2; ++y)
4502 for (GLuint x = 0; x < 2; ++x)
4504 /* If layer and viewport are expected ones, than result shall be 1, otherwise -1. */
4505 const GLint expected_value = ((expected_viewport == viewport) && (expected_layer == layer)) ? 1 : -1;
4507 bool result = checkRegionR32I(x, y, m_width / 2, m_height / 2, expected_value, layer_data);
4509 if (false == result)
4511 check_result = false;
4521 return check_result;
4524 /** Get string with fragment shader source code
4526 * @return Fragment shader source
4528 std::string ProvokingVertex::getFragmentShader()
4530 static const GLchar* source = "#version 410 core\n"
4532 "flat in int gs_fs_color;\n"
4533 " out int fs_out_color;\n"
4537 " fs_out_color = gs_fs_color;\n"
4541 std::string result = source;
4546 /** Get string with geometry shader source code
4548 * @return Geometry shader source
4550 std::string ProvokingVertex::getGeometryShader()
4552 static const GLchar* source = "#version 410 core\n"
4554 "layout(points, invocations = 1) in;\n"
4555 "layout(triangle_strip, max_vertices = 6) out;\n"
4557 "flat out int gs_fs_color;\n"
4561 " /* Left-bottom half */\n"
4562 " gs_fs_color = 1;\n"
4563 " gl_ViewportIndex = 0;\n"
4565 " gl_Position = vec4(-1, -1, 0, 1);\n"
4567 " gs_fs_color = 1;\n"
4568 " gl_ViewportIndex = 1;\n"
4570 " gl_Position = vec4(-1, 1, 0, 1);\n"
4572 " gs_fs_color = 1;\n"
4573 " gl_ViewportIndex = 2;\n"
4575 " gl_Position = vec4(1, -1, 0, 1);\n"
4577 " EndPrimitive();\n"
4579 " /* Right-top half */\n"
4580 " gs_fs_color = 1;\n"
4581 " gl_ViewportIndex = 0;\n"
4583 " gl_Position = vec4(-1, 1, 0, 1);\n"
4585 " gs_fs_color = 1;\n"
4586 " gl_ViewportIndex = 1;\n"
4588 " gl_Position = vec4(1, 1, 0, 1);\n"
4590 " gs_fs_color = 1;\n"
4591 " gl_ViewportIndex = 2;\n"
4593 " gl_Position = vec4(1, -1, 0, 1);\n"
4595 " EndPrimitive();\n"
4599 std::string result = source;
4608 DrawTestBase::TEST_TYPE ProvokingVertex::getTestType()
4613 /** Prepare textures used as framebuffer's attachments for current draw call
4615 * @param texture_0 R32I texture
4618 void ProvokingVertex::prepareTextures(Utils::texture& texture_0, Utils::texture& /* texture_1 */)
4620 prepareTextureR32Ix4(texture_0);
4623 } /* ViewportArray namespace */
4627 * @param context Rendering context.
4629 ViewportArrayTests::ViewportArrayTests(deqp::Context& context, const glcts::ExtParameters& extParams)
4630 : TestCaseGroupBase(context, extParams, "viewport_array", "Verifies \"viewport_array\" functionality")
4632 /* Left blank on purpose */
4635 /** Initializes a texture_storage_multisample test group.
4638 void ViewportArrayTests::init(void)
4640 addChild(new ViewportArray::APIErrors(m_context, m_extParams));
4641 addChild(new ViewportArray::Queries(m_context, m_extParams));
4642 addChild(new ViewportArray::ViewportAPI(m_context, m_extParams));
4643 addChild(new ViewportArray::ScissorAPI(m_context, m_extParams));
4644 addChild(new ViewportArray::DepthRangeAPI(m_context, m_extParams));
4645 addChild(new ViewportArray::ScissorTestStateAPI(m_context, m_extParams));
4646 addChild(new ViewportArray::DrawToSingleLayerWithMultipleViewports(m_context, m_extParams));
4647 addChild(new ViewportArray::DynamicViewportIndex(m_context, m_extParams));
4648 addChild(new ViewportArray::DrawMulitpleViewportsWithSingleInvocation(m_context, m_extParams));
4649 addChild(new ViewportArray::ViewportIndexSubroutine(m_context, m_extParams));
4650 addChild(new ViewportArray::DrawMultipleLayers(m_context, m_extParams));
4651 addChild(new ViewportArray::Scissor(m_context, m_extParams));
4652 addChild(new ViewportArray::ScissorZeroDimension(m_context, m_extParams));
4653 addChild(new ViewportArray::ScissorClear(m_context, m_extParams));
4654 addChild(new ViewportArray::DepthRange(m_context, m_extParams));
4655 addChild(new ViewportArray::DepthRangeDepthTest(m_context, m_extParams));
4656 addChild(new ViewportArray::ProvokingVertex(m_context, m_extParams));
4659 } /* glcts namespace */