Block/non-block uniforms match
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcViewportArrayTests.hpp
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