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 
~shaderCompilationException()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 
~programLinkageException()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:
DepthFuncWrapper(deqp::Context & context)223 		DepthFuncWrapper(deqp::Context& context) : m_gl(context.getRenderContext().getFunctions()){};
~DepthFuncWrapper()224 		~DepthFuncWrapper(){};
225 
depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLfloat * v)226 		void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLfloat* v)
227 		{
228 			m_gl.depthRangeArrayfvOES(first, count, v);
229 		}
230 
depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLdouble * v)231 		void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLdouble* v)
232 		{
233 			m_gl.depthRangeArrayv(first, count, v);
234 		}
235 
depthRangeIndexed(glw::GLuint index,glw::GLfloat n,glw::GLfloat f)236 		void depthRangeIndexed(glw::GLuint index, glw::GLfloat n, glw::GLfloat f)
237 		{
238 			m_gl.depthRangeIndexedfOES(index, n, f);
239 		}
240 
depthRangeIndexed(glw::GLuint index,glw::GLdouble n,glw::GLdouble f)241 		void depthRangeIndexed(glw::GLuint index, glw::GLdouble n, glw::GLdouble f)
242 		{
243 			m_gl.depthRangeIndexed(index, n, f);
244 		}
245 
depthRange(glw::GLfloat near,glw::GLfloat far)246 		void depthRange(glw::GLfloat near, glw::GLfloat far)
247 		{
248 			m_gl.depthRangef(near, far);
249 		}
250 
depthRange(glw::GLdouble near,glw::GLdouble far)251 		void depthRange(glw::GLdouble near, glw::GLdouble far)
252 		{
253 			m_gl.depthRange(near, far);
254 		}
255 
getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLfloat * data)256 		void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLfloat* data)
257 		{
258 			m_gl.getFloati_v(target, index, data);
259 		}
260 
getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLdouble * data)261 		void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLdouble* data)
262 		{
263 			m_gl.getDoublei_v(target, index, data);
264 		}
265 
getFunctions()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 
~APIErrors()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 
~Queries()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 
~ViewportAPI()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 
~ScissorAPI()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 
~DepthRangeAPI()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 
~ScissorTestStateAPI()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 
~DrawTestBase()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 
~DrawToSingleLayerWithMultipleViewports()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 
~DynamicViewportIndex()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 
~DrawMulitpleViewportsWithSingleInvocation()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 
~ViewportIndexSubroutine()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 
~DrawMultipleLayers()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 
~Scissor()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 
~ScissorZeroDimension()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 
~ScissorClear()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);
~DepthRange()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 
~DepthRangeDepthTest()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 
~ProvokingVertex()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 
~ViewportArrayTests(void)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