Home | History | Annotate | Download | only in common
      1 #ifndef _GLCVIEWPORTARRAYTESTS_HPP
      2 #define _GLCVIEWPORTARRAYTESTS_HPP
      3 /*-------------------------------------------------------------------------
      4  * OpenGL Conformance Test Suite
      5  * -----------------------------
      6  *
      7  * Copyright (c) 2014-2016 The Khronos Group Inc.
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  */ /*!
     22  * \file
     23  * \brief
     24  */ /*-------------------------------------------------------------------*/
     25 
     26 /**
     27  * \file  glcViewportArrayTests.hpp
     28  * \brief Declares test classes for "Viewport Array" functionality.
     29  */ /*-------------------------------------------------------------------*/
     30 
     31 #include "glcTestCase.hpp"
     32 #include "glwDefs.hpp"
     33 
     34 #include "esextcTestCaseBase.hpp"
     35 
     36 namespace tcu
     37 {
     38 class MessageBuilder;
     39 } /* namespace tcu */
     40 
     41 namespace glcts
     42 {
     43 namespace ViewportArray
     44 {
     45 
     46 class Utils
     47 {
     48 public:
     49 	enum SHADER_STAGES
     50 	{
     51 		COMPUTE_SHADER = 0,
     52 		VERTEX_SHADER,
     53 		TESS_CTRL_SHADER,
     54 		TESS_EVAL_SHADER,
     55 		GEOMETRY_SHADER,
     56 		FRAGMENT_SHADER,
     57 
     58 		/* */
     59 		SHADER_STAGES_MAX
     60 	};
     61 
     62 	/* Public types */
     63 	struct buffer
     64 	{
     65 		buffer(deqp::Context& context);
     66 		~buffer();
     67 
     68 		void bind() const;
     69 
     70 		void bindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size);
     71 
     72 		void generate(glw::GLenum target);
     73 		void* map(glw::GLenum access) const;
     74 		void unmap() const;
     75 
     76 		void update(glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage);
     77 
     78 		glw::GLuint m_id;
     79 
     80 	private:
     81 		deqp::Context& m_context;
     82 		glw::GLenum	m_target;
     83 	};
     84 
     85 	struct framebuffer
     86 	{
     87 		framebuffer(deqp::Context& context);
     88 		~framebuffer();
     89 
     90 		void attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width, glw::GLuint height);
     91 
     92 		void bind();
     93 		void clear(glw::GLenum mask);
     94 
     95 		void clearColor(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat alpha);
     96 
     97 		void generate();
     98 
     99 		glw::GLuint m_id;
    100 
    101 	private:
    102 		deqp::Context& m_context;
    103 	};
    104 
    105 	class shaderCompilationException : public std::exception
    106 	{
    107 	public:
    108 		shaderCompilationException(const glw::GLchar* source, const glw::GLchar* message);
    109 
    110 		virtual ~shaderCompilationException() throw()
    111 		{
    112 		}
    113 
    114 		virtual const char* what() const throw();
    115 
    116 		std::string m_shader_source;
    117 		std::string m_error_message;
    118 	};
    119 
    120 	class programLinkageException : public std::exception
    121 	{
    122 	public:
    123 		programLinkageException(const glw::GLchar* error_message);
    124 
    125 		virtual ~programLinkageException() throw()
    126 		{
    127 		}
    128 
    129 		virtual const char* what() const throw();
    130 
    131 		std::string m_error_message;
    132 	};
    133 
    134 	/** Store information about program object
    135 	 *
    136 	 **/
    137 	struct program
    138 	{
    139 		program(deqp::Context& context);
    140 		~program();
    141 
    142 		void build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
    143 				   const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code,
    144 				   const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code,
    145 				   const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable = false);
    146 
    147 		void compile(glw::GLuint shader_id, const glw::GLchar* source) const;
    148 
    149 		glw::GLint getAttribLocation(const glw::GLchar* name) const;
    150 
    151 		glw::GLuint getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const;
    152 
    153 		glw::GLint getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const;
    154 
    155 		glw::GLint getUniformLocation(const glw::GLchar* uniform_name) const;
    156 
    157 		void link() const;
    158 		void remove();
    159 		void use() const;
    160 
    161 		/* */
    162 		static void printShaderSource(const glw::GLchar* source, tcu::MessageBuilder& log);
    163 
    164 		static const glw::GLenum ARB_COMPUTE_SHADER;
    165 
    166 		glw::GLuint m_compute_shader_id;
    167 		glw::GLuint m_fragment_shader_id;
    168 		glw::GLuint m_geometry_shader_id;
    169 		glw::GLuint m_program_object_id;
    170 		glw::GLuint m_tesselation_control_shader_id;
    171 		glw::GLuint m_tesselation_evaluation_shader_id;
    172 		glw::GLuint m_vertex_shader_id;
    173 
    174 	private:
    175 		deqp::Context& m_context;
    176 	};
    177 
    178 	struct texture
    179 	{
    180 		texture(deqp::Context& context);
    181 		~texture();
    182 
    183 		void bind() const;
    184 
    185 		void create(glw::GLuint width, glw::GLuint height, glw::GLenum internal_format);
    186 
    187 		void create(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum internal_format);
    188 
    189 		void get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data) const;
    190 
    191 		void release();
    192 
    193 		void update(glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type,
    194 					glw::GLvoid* data);
    195 
    196 		glw::GLuint m_id;
    197 		glw::GLuint m_width;
    198 		glw::GLuint m_height;
    199 		glw::GLuint m_depth;
    200 
    201 	private:
    202 		deqp::Context& m_context;
    203 		bool		   m_is_array;
    204 	};
    205 
    206 	struct vertexArray
    207 	{
    208 		vertexArray(deqp::Context& Context);
    209 		~vertexArray();
    210 
    211 		void generate();
    212 		void bind();
    213 
    214 		glw::GLuint m_id;
    215 
    216 	private:
    217 		deqp::Context& m_context;
    218 	};
    219 
    220 	class DepthFuncWrapper
    221 	{
    222 	public:
    223 		DepthFuncWrapper(deqp::Context& context) : m_gl(context.getRenderContext().getFunctions()){};
    224 		~DepthFuncWrapper(){};
    225 
    226 		void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLfloat* v)
    227 		{
    228 			m_gl.depthRangeArrayfvOES(first, count, v);
    229 		}
    230 
    231 		void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLdouble* v)
    232 		{
    233 			m_gl.depthRangeArrayv(first, count, v);
    234 		}
    235 
    236 		void depthRangeIndexed(glw::GLuint index, glw::GLfloat n, glw::GLfloat f)
    237 		{
    238 			m_gl.depthRangeIndexedfOES(index, n, f);
    239 		}
    240 
    241 		void depthRangeIndexed(glw::GLuint index, glw::GLdouble n, glw::GLdouble f)
    242 		{
    243 			m_gl.depthRangeIndexed(index, n, f);
    244 		}
    245 
    246 		void depthRange(glw::GLfloat near, glw::GLfloat far)
    247 		{
    248 			m_gl.depthRangef(near, far);
    249 		}
    250 
    251 		void depthRange(glw::GLdouble near, glw::GLdouble far)
    252 		{
    253 			m_gl.depthRange(near, far);
    254 		}
    255 
    256 		void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLfloat* data)
    257 		{
    258 			m_gl.getFloati_v(target, index, data);
    259 		}
    260 
    261 		void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLdouble* data)
    262 		{
    263 			m_gl.getDoublei_v(target, index, data);
    264 		}
    265 
    266 		const glw::Functions& getFunctions()
    267 		{
    268 			return m_gl;
    269 		}
    270 
    271 	private:
    272 		const glw::Functions& m_gl;
    273 	};
    274 };
    275 
    276 /** Implements test APIErrors, description follows:
    277  *
    278  *   Verify that API generate errors as specified. Check that:
    279  *   * DepthRangeArrayv generates INVALID_VALUE when <first> + <count> is greater
    280  *   than or equal to the value of MAX_VIEWPORTS;
    281  *   * DepthRangeIndexed generates INVALID_VALUE when <index> is greater than or
    282  *   equal to the value of MAX_VIEWPORTS;
    283  *   * ViewportArrayv generates INVALID_VALUE when <first> + <count> is greater
    284  *   than or equal to the value of MAX_VIEWPORTS;
    285  *   * ViewportIndexedf and ViewportIndexedfv generate INVALID_VALUE when <index>
    286  *   is greater than or equal to the value of MAX_VIEWPORTS;
    287  *   * ViewportArrayv, Viewport, ViewportIndexedf and ViewportIndexedfv generate
    288  *   INVALID_VALUE when <w> or <h> values are negative;
    289  *   * ScissorArrayv generates INVALID_VALUE when <first> + <count> is greater
    290  *   than or equal to the value of MAX_VIEWPORTS;
    291  *   * ScissorIndexed and ScissorIndexedv generate INVALID_VALUE when <index> is
    292  *   greater than or equal to the value of MAX_VIEWPORTS;
    293  *   * ScissorArrayv, ScissorIndexed, ScissorIndexedv and Scissor generate
    294  *   INVALID_VALUE when <width> or <height> values are negative;
    295  *   * Disablei, Enablei and IsEnabledi generate INVALID_VALUE when <cap> is
    296  *   SCISSOR_TEST and <index> is greater than or equal to the
    297  *   value of MAX_VIEWPORTS;
    298  *   * GetIntegeri_v generates INVALID_VALUE when <target> is SCISSOR_BOX and
    299  *   <index> is greater than or equal to the value of MAX_VIEWPORTS;
    300  *   * GetFloati_v generates INVALID_VALUE when <target> is VIEWPORT and <index>
    301  *   is greater than or equal to the value of MAX_VIEWPORTS;
    302  *   * GetDoublei_v generates INVALID_VALUE when <target> is DEPTH_RANGE and
    303  *   <index> is greater than or equal to the value of MAX_VIEWPORTS;
    304  **/
    305 class APIErrors : public glcts::TestCaseBase
    306 {
    307 public:
    308 	/* Public methods */
    309 	APIErrors(deqp::Context& context, const glcts::ExtParameters& extParams);
    310 
    311 	virtual ~APIErrors()
    312 	{
    313 	}
    314 
    315 	/* Public methods inherited from TestCaseBase */
    316 	virtual IterateResult iterate(void);
    317 
    318 private:
    319 	template <typename T>
    320 	void depthRangeArrayHelper(Utils::DepthFuncWrapper& depthFunc, glw::GLint max_viewports, bool& test_result,
    321 							   T* data = NULL);
    322 
    323 	template <typename T>
    324 	void depthRangeIndexedHelper(Utils::DepthFuncWrapper& depthFunc, glw::GLint max_viewports, bool& test_result,
    325 								 T* data = NULL);
    326 
    327 	template <typename T>
    328 	void getDepthHelper(Utils::DepthFuncWrapper& depthFunc, glw::GLint max_viewports, bool& test_result,
    329 						T* data = NULL);
    330 
    331 	void checkGLError(glw::GLenum expected_error, const glw::GLchar* description, bool& out_result);
    332 };
    333 
    334 /** Implements test Queries, description follows:
    335  *
    336  *   Verify that:
    337  *   * Initial dimensions of VIEWPORT returned by GetFloati_v match dimensions of
    338  *   the window into which GL is rendering;
    339  *   * Initial values of DEPTH_RANGE returned by GetDoublei_v are [0, 1];
    340  *   * Initial state of SCISSOR_TEST returned by IsEnabledi is FALSE;
    341  *   * Initial dimensions of SCISSOR_BOX returned by GetIntegeri_v are either
    342  *   zeros or match dimensions of the window into which GL is rendering;
    343  *   * Dimensions of MAX_VIEWPORT_DIMS returned by GetFloati_v are at least
    344  *   as big as supported dimensions of render buffers, see MAX_RENDERBUFFER_SIZE;
    345  *   * Value of MAX_VIEWPORTS returned by GetIntegeri_v is at least 16;
    346  *   * Value of VIEWPORT_SUBPIXEL_BITS returned by GetIntegeri_v is at least 0;
    347  *   * Values of VIEWPORT_BOUNDS_RANGE returned by GetFloatv are
    348  *   at least [-32768, 32767];
    349  *   * Values of LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
    350  *   returned by GetIntegerv are located in the following set
    351  *   { FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, PROVOKING_VERTEX,
    352  *   UNDEFINED_VERTEX };
    353  **/
    354 class Queries : public glcts::TestCaseBase
    355 {
    356 public:
    357 	/* Public methods */
    358 	Queries(deqp::Context& context, const glcts::ExtParameters& extParams);
    359 
    360 	virtual ~Queries()
    361 	{
    362 	}
    363 
    364 	/* Public methods inherited from TestCase */
    365 	virtual tcu::TestNode::IterateResult iterate(void);
    366 
    367 private:
    368 	template <typename T>
    369 	void depthRangeInitialValuesHelper(Utils::DepthFuncWrapper& depthFunc, glw::GLint max_viewports, bool& test_result,
    370 									   T* data = NULL);
    371 };
    372 
    373 /** Implements test ViewportAPI, description follows:
    374  *
    375  *   Verify that VIEWPORT can be set and queried.
    376  *   Steps:
    377  *   - get initial dimensions of VIEWPORT for all MAX_VIEWPORTS indices;
    378  *   - change location and dimensions of all indices at once with
    379  *   ViewportArrayv;
    380  *   - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
    381  *   - for each index:
    382  *     * modify with ViewportIndexedf,
    383  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
    384  *     * modify with ViewportIndexedfv,
    385  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
    386  *   - for each index:
    387  *     * modify all indices before and after current one with ViewportArrayv,
    388  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
    389  *   - change location and dimensions of all indices at once with Viewport;
    390  *   - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
    391  **/
    392 class ViewportAPI : public glcts::TestCaseBase
    393 {
    394 public:
    395 	/* Public methods */
    396 	ViewportAPI(deqp::Context& context, const glcts::ExtParameters& extParams);
    397 
    398 	virtual ~ViewportAPI()
    399 	{
    400 	}
    401 
    402 	/* Public methods inherited from TestCase */
    403 	virtual tcu::TestNode::IterateResult iterate(void);
    404 
    405 private:
    406 	/* Private methods */
    407 	void compareViewports(std::vector<glw::GLfloat>& left, std::vector<glw::GLfloat>& right,
    408 						  const glw::GLchar* description, bool& out_result);
    409 
    410 	void getViewports(glw::GLint max_viewports, std::vector<glw::GLfloat>& out_data);
    411 
    412 	/* Private constants */
    413 	static const glw::GLuint m_n_elements;
    414 };
    415 
    416 /** Implements test ScissorAPI, description follows:
    417  *
    418  *   Verify that SCISSOR_BOX can be set and queried.
    419  *   Steps:
    420  *   - get initial dimensions of SCISSOR_BOX for all MAX_VIEWPORTS indices;
    421  *   - change location and dimensions of all indices at once with
    422  *   ScissorArrayv;
    423  *   - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
    424  *   - for each index:
    425  *     * modify with ScissorIndexed,
    426  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
    427  *     * modify with ScissorIndexedv,
    428  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
    429  *   - for each index:
    430  *     * modify all indices before and after current one with ScissorArrayv,
    431  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
    432  *   - change location and dimensions of all indices at once with Scissor;
    433  *   - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
    434  **/
    435 class ScissorAPI : public glcts::TestCaseBase
    436 {
    437 public:
    438 	/* Public methods */
    439 	ScissorAPI(deqp::Context& context, const glcts::ExtParameters& extParams);
    440 
    441 	virtual ~ScissorAPI()
    442 	{
    443 	}
    444 
    445 	/* Public methods inherited from TestCase */
    446 	virtual tcu::TestNode::IterateResult iterate(void);
    447 
    448 private:
    449 	/* Private methods */
    450 	void compareScissorBoxes(std::vector<glw::GLint>& left, std::vector<glw::GLint>& right,
    451 							 const glw::GLchar* description, bool& out_result);
    452 
    453 	void getScissorBoxes(glw::GLint max_viewports, std::vector<glw::GLint>& out_data);
    454 
    455 	/* Private constants */
    456 	static const glw::GLuint m_n_elements;
    457 };
    458 
    459 /** Implements test DepthRangeAPI, description follows:
    460  *
    461  *   Verify that DEPTH_RANGE can be set and queried.
    462  *   Steps:
    463  *   - get initial values of DEPTH_RANGE for all MAX_VIEWPORTS indices;
    464  *   - change values of all indices at once with DepthRangeArrayv;
    465  *   - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
    466  *   - for each index:
    467  *     * modify with DepthRangeIndexed,
    468  *     * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
    469  *   - for each index:
    470  *     * modify all indices before and after current one with DepthRangeArrayv,
    471  *     * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
    472  *   - change values of all indices at once with DepthRange;
    473  *   - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
    474  **/
    475 class DepthRangeAPI : public glcts::TestCaseBase
    476 {
    477 public:
    478 	/* Public methods */
    479 	DepthRangeAPI(deqp::Context& context, const glcts::ExtParameters& extParams);
    480 
    481 	virtual ~DepthRangeAPI()
    482 	{
    483 	}
    484 
    485 	/* Public methods inherited from TestCase */
    486 	virtual tcu::TestNode::IterateResult iterate(void);
    487 
    488 private:
    489 	/* Private methods */
    490 	template <typename T>
    491 	void compareDepthRanges(std::vector<T>& left, std::vector<T>& right, const glw::GLchar* description,
    492 							bool& out_result);
    493 
    494 	template <typename T>
    495 	void getDepthRanges(Utils::DepthFuncWrapper& depthFunc, glw::GLint max_viewports, std::vector<T>& out_data);
    496 
    497 	template <typename T>
    498 	bool iterateHelper(T* data = NULL);
    499 
    500 	/* Private constants */
    501 	static const glw::GLuint m_n_elements;
    502 };
    503 
    504 /** Implements test ScissorTestStateAPI, description follows:
    505  *
    506  *   Verify that state of SCISSOR_TEST can be set and queried.
    507  *   Steps:
    508  *   - get initial state of SCISSOR_TEST for all MAX_VIEWPORTS indices;
    509  *   - for each index:
    510  *     * toggle SCISSOR_TEST,
    511  *     * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
    512  *   - for each index:
    513  *     * toggle SCISSOR_TEST,
    514  *     * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
    515  *   - enable SCISSOR_TEST for all indices at once with Enable;
    516  *   - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
    517  *   - disable SCISSOR_TEST for all indices at once with Disable;
    518  *   - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
    519  *   - enable SCISSOR_TEST for all indices at once with Enable;
    520  *   - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
    521  **/
    522 class ScissorTestStateAPI : public glcts::TestCaseBase
    523 {
    524 public:
    525 	/* Public methods */
    526 	ScissorTestStateAPI(deqp::Context& context, const glcts::ExtParameters& extParams);
    527 
    528 	virtual ~ScissorTestStateAPI()
    529 	{
    530 	}
    531 
    532 	/* Public methods inherited from TestCase */
    533 	virtual tcu::TestNode::IterateResult iterate(void);
    534 
    535 private:
    536 	/* Private methods */
    537 	void compareScissorTestStates(std::vector<glw::GLboolean>& left, std::vector<glw::GLboolean>& right,
    538 								  const glw::GLchar* description, bool& out_result);
    539 
    540 	void getScissorTestStates(glw::GLint max_viewports, std::vector<glw::GLboolean>& out_data);
    541 };
    542 
    543 class DrawTestBase : public glcts::TestCaseBase
    544 {
    545 public:
    546 	/* Public methods */
    547 	DrawTestBase(deqp::Context& context, const glcts::ExtParameters& extParams, const glw::GLchar* test_name,
    548 				 const glw::GLchar* test_description);
    549 
    550 	virtual ~DrawTestBase()
    551 	{
    552 	}
    553 
    554 	/* Public methods inherited from TestCase */
    555 	virtual tcu::TestNode::IterateResult iterate(void);
    556 
    557 protected:
    558 	/* Protected enums */
    559 	enum VIEWPORT_METHOD
    560 	{
    561 		VIEWPORTARRAYV = 0,
    562 		VIEWPORTINDEXEDF,
    563 		VIEWPORTINDEXEDF_V,
    564 	};
    565 	enum SCISSOR_METHOD
    566 	{
    567 		SCISSORARRAYV = 0,
    568 		SCISSORINDEXEDF,
    569 		SCISSORINDEXEDF_V,
    570 	};
    571 	enum DEPTH_RANGE_METHOD
    572 	{
    573 		DEPTHRANGEARRAYV = 0,
    574 		DEPTHRANGEINDEXED,
    575 	};
    576 	enum PROVOKING_VERTEX
    577 	{
    578 		FIRST,
    579 		LAST,
    580 	};
    581 	enum TEST_TYPE
    582 	{
    583 		VIEWPORT,
    584 		SCISSOR,
    585 		DEPTHRANGE,
    586 		PROVOKING,
    587 	};
    588 
    589 	/* Protected methods to be implemented by child class */
    590 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    591 
    592 	virtual void getClearSettings(bool& clear_depth_before_draw, glw::GLuint iteration_index,
    593 								  glw::GLfloat& depth_value);
    594 
    595 	virtual glw::GLuint getDrawCallsNumber();
    596 	virtual std::string getFragmentShader() = 0;
    597 	virtual std::string getGeometryShader() = 0;
    598 	virtual TEST_TYPE   getTestType();
    599 	virtual bool		isClearTest();
    600 
    601 	virtual void prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1);
    602 
    603 	virtual void prepareUniforms(Utils::program& program, glw::GLuint draw_call_index);
    604 
    605 	virtual void setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
    606 								  Utils::texture& texture_1);
    607 
    608 	virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
    609 
    610 	/* Methods available for child class */
    611 	bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLint expected_value, glw::GLint* data);
    612 
    613 	bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLuint width, glw::GLuint height, glw::GLint expected_value,
    614 						 glw::GLint* data);
    615 
    616 	void prepareTextureR32I(Utils::texture& texture);
    617 	void prepareTextureR32Ix4(Utils::texture& texture);
    618 	void prepareTextureArrayR32I(Utils::texture& texture);
    619 	void prepareTextureR32F(Utils::texture& texture);
    620 	void prepareTextureD32F(Utils::texture& texture);
    621 	void setup16x2Depths(DEPTH_RANGE_METHOD method);
    622 	void setup4x4Scissor(SCISSOR_METHOD method, bool set_zeros);
    623 	void setup4x4Viewport(VIEWPORT_METHOD method);
    624 	void setup2x2Viewport(PROVOKING_VERTEX provoking);
    625 
    626 	/* Constants available to child class */
    627 	static const glw::GLuint m_depth;
    628 	static const glw::GLuint m_height;
    629 	static const glw::GLuint m_width;
    630 	static const glw::GLuint m_r32f_height;
    631 	static const glw::GLuint m_r32f_width;
    632 	static const glw::GLuint m_r32ix4_depth;
    633 
    634 private:
    635 	/* Private methods */
    636 	std::string getVertexShader();
    637 
    638 	template <typename T>
    639 	void setup16x2DepthsHelper(DEPTH_RANGE_METHOD method, T* data = NULL);
    640 };
    641 
    642 /** Implements test DrawToSingleLayerWithMultipleViewports, description follows:
    643  *
    644  *   Verify that multiple viewports can be used to draw to single image.
    645  *   Steps:
    646  *   - prepare 2D R32I 128x128 texture filled with value -1 and set it up as
    647  *   COLOR_ATTACHMENT_0;
    648  *   - prepare program that consist of:
    649  *     * boilerplate vertex shader,
    650  *     * geometry shader,
    651  *     * fragment shaders;
    652  *   Geometry shader should output a quad (-1,-1 : 1,1) made of
    653  *   triangle_strip; gl_ViewportIndex and declared integer varying "color"
    654  *   should be assigned the value of gl_InvocationID; Amount of geometry shader
    655  *   invocations should be set to 16; Fragment shader should output value of
    656  *   varying "color" to attachment 0.
    657  *   - set up first 16 viewports with following code snippet:
    658  *
    659  *       index = 0;
    660  *       for (y = 0; y < 4; ++y)
    661  *         for (x = 0; x < 4; ++x)
    662  *           ViewportIndexedf(index++,
    663  *                            x * 32 x offset,
    664  *                            y * 32 y offset,
    665  *                            32     width   ,
    666  *                            32     height  );
    667  *   - draw single vertex;
    668  *   - inspect contents of COLOR_ATTACHMENT_0;
    669  *   - test pass if image is filled with the following pattern:
    670  *
    671  *       0  1  2  3
    672  *       4  5  6  7
    673  *       8  9  10 11
    674  *       12 13 14 15;
    675  *
    676  *   Each area should be 32x32 pixels rectangle;
    677  *   - repeat test with functions ViewportIndexedf_v and ViewportArrayv;
    678  **/
    679 class DrawToSingleLayerWithMultipleViewports : public DrawTestBase
    680 {
    681 public:
    682 	/* Public methods */
    683 	DrawToSingleLayerWithMultipleViewports(deqp::Context& context, const glcts::ExtParameters& extParams);
    684 
    685 	virtual ~DrawToSingleLayerWithMultipleViewports()
    686 	{
    687 	}
    688 
    689 protected:
    690 	/* Protected methods inherited from DrawTestBase */
    691 	virtual std::string getFragmentShader();
    692 	virtual std::string getGeometryShader();
    693 };
    694 
    695 /** Implements test DynamicViewportIndex, description follows:
    696  *
    697  *   Verify that gl_ViewportIndex can be set in dynamic manner.
    698  *   Modify DrawToSingleLayerWithMultipleViewports in the following aspects:
    699  *   - geometry shader should declare unsigned integer uniform "index";
    700  *   - geometry shader should assign a value of "index" to gl_ViewportIndex and
    701  *   "color";
    702  *   - amount of geometry shader invocations should be set to 1;
    703  *   - 16 times:
    704  *     * set "index" to unique value from range <0:15>;
    705  *     * draw single vertex;
    706  *     * verify that only area of viewport at "index" has been updated;
    707  *   - test pass if correct pixels were modified in each draw;
    708  **/
    709 class DynamicViewportIndex : public DrawTestBase
    710 {
    711 public:
    712 	/* Public methods */
    713 	DynamicViewportIndex(deqp::Context& context, const glcts::ExtParameters& extParams);
    714 
    715 	virtual ~DynamicViewportIndex()
    716 	{
    717 	}
    718 
    719 protected:
    720 	/* Protected methods inherited from DrawTestBase */
    721 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    722 
    723 	virtual std::string getFragmentShader();
    724 	virtual std::string getGeometryShader();
    725 	virtual glw::GLuint getDrawCallsNumber();
    726 
    727 	virtual void prepareUniforms(Utils::program& program, glw::GLuint draw_call_index);
    728 };
    729 
    730 /** Implements test DrawMulitpleViewportsWithSingleInvocation, description follows:
    731  *
    732  *   Verify that multiple viewports can be affected by single invocation of
    733  *   geometry shader.
    734  *   Modify DrawToSingleLayerWithMultipleViewports in the following aspects:
    735  *   - geometry shader should output 16 quads, as separate primitives;
    736  *   - instead of gl_InvocationID, geometry shader should use predefined values
    737  *   from range <0:15>, unique per quad;
    738  *   - amount of geometry shader invocations should be set to 1;
    739  **/
    740 class DrawMulitpleViewportsWithSingleInvocation : public DrawTestBase
    741 {
    742 public:
    743 	/* Public methods */
    744 	DrawMulitpleViewportsWithSingleInvocation(deqp::Context& context, const glcts::ExtParameters& extParams);
    745 
    746 	virtual ~DrawMulitpleViewportsWithSingleInvocation()
    747 	{
    748 	}
    749 
    750 protected:
    751 	/* Protected methods inherited from DrawTestBase */
    752 	virtual std::string getFragmentShader();
    753 	virtual std::string getGeometryShader();
    754 };
    755 
    756 /** Implements test ViewportIndexSubroutine, description follows:
    757  *
    758  *   Verify that gl_ViewportIndex can be assigned by subroutine.
    759  *   Depends on: ARB_shader_subroutine.
    760  *   Modify DynamicViewportIndex in the following aspects:
    761  *   - geometry shader should define two subroutines and single subroutine
    762  *   uniform; First subroutine should assign value 4 to gl_ViewportIndex and
    763  *   "color"; Second subroutine should assign value 5 to gl_ViewportIndex and
    764  *   "color"; subroutine should be called once per emitted vertex;
    765  *   - uniform "index" should be removed;
    766  *   - viewport 4 should be configured to span over left half of image; viewport
    767  *   5 should span over right half of image;
    768  *   - set up first subroutine and draw single vertex;
    769  *   - set up second subroutine and draw single vertex;
    770  *   - test pass if left half of image is filled with value 4 and right one with
    771  *   5;
    772  **/
    773 class ViewportIndexSubroutine : public DrawTestBase
    774 {
    775 public:
    776 	/* Public methods */
    777 	ViewportIndexSubroutine(deqp::Context& context, const glcts::ExtParameters& extParams);
    778 
    779 	virtual ~ViewportIndexSubroutine()
    780 	{
    781 	}
    782 
    783 	/* Public methods inherited from TestCase/DrawTestBase */
    784 	virtual tcu::TestNode::IterateResult iterate(void);
    785 
    786 protected:
    787 	/* Protected methods inherited from DrawTestBase */
    788 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    789 
    790 	virtual std::string getFragmentShader();
    791 	virtual std::string getGeometryShader();
    792 	virtual glw::GLuint getDrawCallsNumber();
    793 
    794 	virtual void prepareUniforms(Utils::program& program, glw::GLuint draw_call_index);
    795 
    796 	virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
    797 };
    798 
    799 /** Implements test DrawMultipleLayers, description follows:
    800  *
    801  *   Verify that single viewport affects multiple layers in the same way.
    802  *   Modify DynamicViewportIndex in the following aspects:
    803  *   - texture should be 2D array with 16 layers;
    804  *   - geometry shader should assign a value of gl_InvocationId to gl_Layer;
    805  *   - amount of geometry shader invocations should be set to 16;
    806  *   - verification should be applied to all 16 layers;
    807  **/
    808 class DrawMultipleLayers : public DrawTestBase
    809 {
    810 public:
    811 	/* Public methods */
    812 	DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams);
    813 
    814 	DrawMultipleLayers(deqp::Context& context, const glcts::ExtParameters& extParams, const glw::GLchar* test_name,
    815 					   const glw::GLchar* test_description);
    816 
    817 	virtual ~DrawMultipleLayers()
    818 	{
    819 	}
    820 
    821 protected:
    822 	/* Protected methods inherited from DrawTestBase */
    823 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    824 
    825 	virtual std::string getFragmentShader();
    826 	virtual std::string getGeometryShader();
    827 
    828 	virtual void prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1);
    829 };
    830 
    831 /** Implements test Scissor, description follows:
    832  *
    833  *   Verify that scissor test is applied as expected.
    834  *   Modify DrawMultipleLayers in the following aspects:
    835  *   - set all viewports to location 0,0 and dimensions 128x128;
    836  *   - set up first 16 scissor boxes with following code snippet:
    837  *
    838  *       index = 0;
    839  *       for (y = 0; y < 4; ++y)
    840  *         for (x = 0; x < 4; ++x)
    841  *           ScissorIndexed(index++,
    842  *                          x * 32 x offset,
    843  *                          y * 32 y offset,
    844  *                          32     width   ,
    845  *                          32     height  );
    846  *
    847  *   - enable SCISSORT_TEST for first 16 indices;
    848  *   - verification should be concerned with areas of the scissor boxes not
    849  *   viewports;
    850  *   - repeat test with functions ScissorIndexedv and ScissorArrayv;
    851  **/
    852 class Scissor : public DrawMultipleLayers
    853 {
    854 public:
    855 	/* Public methods */
    856 	Scissor(deqp::Context& context, const glcts::ExtParameters& extParams);
    857 
    858 	virtual ~Scissor()
    859 	{
    860 	}
    861 
    862 protected:
    863 	/* Protected methods inherited from DrawTestBase */
    864 	virtual TEST_TYPE getTestType();
    865 };
    866 
    867 /** Implements test ScissorZeroDimension, description follows:
    868  *
    869  *   Verify that scissor test discard all fragments when width and height is set
    870  *   to zero.
    871  *   Modify Scissor to set up width and height of scissor boxes to 0.
    872  *   Test pass if no pixel is modified.
    873  **/
    874 class ScissorZeroDimension : public DrawMultipleLayers
    875 {
    876 public:
    877 	/* Public methods */
    878 	ScissorZeroDimension(deqp::Context& context, const glcts::ExtParameters& extParams);
    879 
    880 	virtual ~ScissorZeroDimension()
    881 	{
    882 	}
    883 
    884 protected:
    885 	/* Protected methods inherited from DrawTestBase */
    886 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    887 
    888 	virtual TEST_TYPE getTestType();
    889 
    890 	virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
    891 };
    892 
    893 /** Implements test ScissorClear, description follows:
    894  *
    895  *   Verify that Clear is affected only by settings of scissor test in first
    896  *   viewport.
    897  *   Steps:
    898  *   - prepare 2D 128x128 R32I texture, filled with value -1 and set it as
    899  *   COLOR_ATTACHMENT_0;
    900  *   - configure first 16 viewports as in Scissor;
    901  *   - enable SCISSOR_TEST for first 16 indices;
    902  *   - clear framebuffer to (0, 0, 0, 0);
    903  *   - inspect image;
    904  *   - test pass if only area corresponding with first SCISSOR_BOX was filled
    905  *   with 0, while rest of image remain filled with value -1;
    906  **/
    907 class ScissorClear : public DrawMultipleLayers
    908 {
    909 public:
    910 	/* Public methods */
    911 	ScissorClear(deqp::Context& context, const glcts::ExtParameters& extParams);
    912 
    913 	virtual ~ScissorClear()
    914 	{
    915 	}
    916 
    917 protected:
    918 	/* Protected methods inherited from DrawTestBase */
    919 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    920 
    921 	virtual TEST_TYPE getTestType();
    922 	virtual bool	  isClearTest();
    923 };
    924 
    925 /** Implements test DepthRange, description follows:
    926  *
    927  *   Verify that depth range is applied as expected.
    928  *   Steps:
    929  *   - prepate 2D 16x2 R32F texture filled with value -1.0 and set it up as
    930  *   COLOR_ATTACHMENT_0;
    931  *   - prepare program that consist of:
    932  *     * boilerplate vertex shader,
    933  *     * geometry shader,
    934  *     * fragment shader;
    935  *   Geometry shader should emit two quads:
    936  *     * -1,0 : 1,1 with z equal -1.0,
    937  *     * -1,-1 : 1,0 with z equal 1.0,
    938  *   made of triangle_strip; gl_ViewportIndex should be assigned an value of
    939  *   gl_InvocationId; Amount of geometry shader invocations should be set to 16;
    940  *   Fragment shader should output value of gl_FragCoord.z to attachment 0.
    941  *   - set up first 16 viewports with the following code snippet:
    942  *
    943  *       const double step = 1.0 / 16.0;
    944  *       for (index = 0; index < 16; ++index)
    945  *       {
    946  *           const double near = ((double) i) * step;
    947  *           VieportIndexed   (i, (float) i, 0.0, 1.0, 2.0);
    948  *           DepthRangeIndexed(i, near,      1.0 - near);
    949  *       }
    950  *
    951  *   - draw single vertex;
    952  *   - inspect contents of COLOR_ATTACHMENT_0;
    953  *   - test pass if:
    954  *     * top row of image is filled with increasing values, starting at 0 with
    955  *     step 1/16;
    956  *     * bottom row of image is filled with decreasing values, starting at 1 with
    957  *     step 1/16;
    958  *   - repeat test with function DepthRangeArrayv;
    959  **/
    960 class DepthRange : public DrawTestBase
    961 {
    962 public:
    963 	/* Public methods */
    964 	DepthRange(deqp::Context& context, const glcts::ExtParameters& extParams);
    965 	virtual ~DepthRange()
    966 	{
    967 	}
    968 
    969 protected:
    970 	/* Protected methods inherited from DrawTestBase */
    971 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
    972 
    973 	virtual std::string getFragmentShader();
    974 	virtual std::string getGeometryShader();
    975 	virtual TEST_TYPE   getTestType();
    976 
    977 	virtual void prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1);
    978 };
    979 
    980 /** Implements test DepthRangeDepthTest, description follows:
    981  *
    982  *   Verify that depth test work as expected with multiple viewports.
    983  *   Modify DepthRange test in the following aspect:
    984  *   - add second 2D 16x2 DEPTH_COMPONENT32F texture and set it up as
    985  *   DEPTH_ATTACHMENT;
    986  *   - enable DEPTH_TEST;
    987  *   - DepthFunc should be set to LESS (initial value);
    988  *   - 18 times:
    989  *     * set ClearDepth to "i" * 1/16, starting at 0 up to 17/16,
    990  *     * draw single vertex
    991  *     * verify contents of color attachment;
    992  *   - test pass when color attachment is filled only with values lower than
    993  *   current ClearDepth value;
    994  **/
    995 class DepthRangeDepthTest : public DrawTestBase
    996 {
    997 public:
    998 	/* Public methods */
    999 	DepthRangeDepthTest(deqp::Context& context, const glcts::ExtParameters& extParams);
   1000 
   1001 	virtual ~DepthRangeDepthTest()
   1002 	{
   1003 	}
   1004 
   1005 protected:
   1006 	/* Protected methods inherited from DrawTestBase */
   1007 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
   1008 
   1009 	virtual void getClearSettings(bool& clear_depth_before_draw, glw::GLuint iteration_index,
   1010 								  glw::GLfloat& depth_value);
   1011 
   1012 	virtual glw::GLuint getDrawCallsNumber();
   1013 	virtual std::string getFragmentShader();
   1014 	virtual std::string getGeometryShader();
   1015 	virtual TEST_TYPE   getTestType();
   1016 
   1017 	virtual void prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1);
   1018 
   1019 	virtual void setupFramebuffer(Utils::framebuffer& framebuffer, Utils::texture& texture_0,
   1020 								  Utils::texture& texture_1);
   1021 
   1022 	virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
   1023 };
   1024 
   1025 /** Implements test ProvokingVertex, description follows:
   1026  *
   1027  *   Verify that provoking vertex work as expected.
   1028  *   Steps:
   1029  *   - prepare 2D array R32I 128x128x4 texture and configure it as
   1030  *   COLOR_ATTACHMENT_0;
   1031  *   - prepare program consisting of:
   1032  *     * boilerplate vertex shader,
   1033  *     * geometry shader,
   1034  *     * fragment shader;
   1035  *   Geometry shader should output a quad (-1,-1 : 1,1); Each vertex should
   1036  *   receive different gl_ViewportIndex value, first vertex should be assigned an
   1037  *   0, second 1, third 2, fourth 3; gl_Layer should be set in the same way as
   1038  *   gl_ViewportIndex; Fragment shader should output integer of value 1;
   1039  *   - configure first four viewports to form 2x2 grid, spanning whole image;
   1040  *   - for each combination of LAYER_PROVOKING_VERTEX and
   1041  *   VIEWPORT_INDEX_PROVOKING_VERTEX:
   1042  *     * clear framebuffer to (0,0,0,0),
   1043  *     * draw single vertex
   1044  *     * inspect image;
   1045  *   - test pass if correct area of correct layer is filled with value 1, while
   1046  *   rest of image remains "clean";
   1047  *   Notes:
   1048  *   - for UNDEFINED_VERTEX any selection is correct;
   1049  *   - for PROVOKING_VERTEX convention is selected by function ProvokingVertex;
   1050  *   Test all possible combinations;
   1051  **/
   1052 class ProvokingVertex : public DrawTestBase
   1053 {
   1054 public:
   1055 	/* Public methods */
   1056 	ProvokingVertex(deqp::Context& context, const glcts::ExtParameters& extParams);
   1057 
   1058 	virtual ~ProvokingVertex()
   1059 	{
   1060 	}
   1061 
   1062 protected:
   1063 	/* Protected methods inherited from DrawTestBase */
   1064 	virtual bool checkResults(Utils::texture& texture_0, Utils::texture& texture_1, glw::GLuint draw_call_index);
   1065 
   1066 	virtual std::string getFragmentShader();
   1067 	virtual std::string getGeometryShader();
   1068 	virtual TEST_TYPE   getTestType();
   1069 
   1070 	virtual void prepareTextures(Utils::texture& texture_0, Utils::texture& texture_1);
   1071 };
   1072 } /* ViewportArray namespace */
   1073 
   1074 /** Group class for Shader Language 420Pack conformance tests */
   1075 class ViewportArrayTests : public glcts::TestCaseGroupBase
   1076 {
   1077 public:
   1078 	/* Public methods */
   1079 	ViewportArrayTests(deqp::Context& context, const glcts::ExtParameters& extParams);
   1080 
   1081 	virtual ~ViewportArrayTests(void)
   1082 	{
   1083 	}
   1084 
   1085 	virtual void init(void);
   1086 
   1087 private:
   1088 	/* Private methods */
   1089 	ViewportArrayTests(const ViewportArrayTests& other);
   1090 	ViewportArrayTests& operator=(const ViewportArrayTests& other);
   1091 };
   1092 
   1093 } // glcts
   1094 
   1095 #endif // _GLCVIEWPORTARRAYTESTS_HPP
   1096