xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcViewportArrayTests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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())
224         {
225         }
~DepthFuncWrapper()226         ~DepthFuncWrapper()
227         {
228         }
229 
depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLfloat * v)230         void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLfloat *v)
231         {
232             m_gl.depthRangeArrayfvOES(first, count, v);
233         }
234 
depthRangeArray(glw::GLuint first,glw::GLsizei count,const glw::GLdouble * v)235         void depthRangeArray(glw::GLuint first, glw::GLsizei count, const glw::GLdouble *v)
236         {
237             m_gl.depthRangeArrayv(first, count, v);
238         }
239 
depthRangeIndexed(glw::GLuint index,glw::GLfloat n,glw::GLfloat f)240         void depthRangeIndexed(glw::GLuint index, glw::GLfloat n, glw::GLfloat f)
241         {
242             m_gl.depthRangeIndexedfOES(index, n, f);
243         }
244 
depthRangeIndexed(glw::GLuint index,glw::GLdouble n,glw::GLdouble f)245         void depthRangeIndexed(glw::GLuint index, glw::GLdouble n, glw::GLdouble f)
246         {
247             m_gl.depthRangeIndexed(index, n, f);
248         }
249 
depthRange(glw::GLfloat near,glw::GLfloat far)250         void depthRange(glw::GLfloat near, glw::GLfloat far)
251         {
252             m_gl.depthRangef(near, far);
253         }
254 
depthRange(glw::GLdouble near,glw::GLdouble far)255         void depthRange(glw::GLdouble near, glw::GLdouble far)
256         {
257             m_gl.depthRange(near, far);
258         }
259 
getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLfloat * data)260         void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLfloat *data)
261         {
262             m_gl.getFloati_v(target, index, data);
263         }
264 
getDepthi_v(glw::GLenum target,glw::GLuint index,glw::GLdouble * data)265         void getDepthi_v(glw::GLenum target, glw::GLuint index, glw::GLdouble *data)
266         {
267             m_gl.getDoublei_v(target, index, data);
268         }
269 
getFunctions()270         const glw::Functions &getFunctions()
271         {
272             return m_gl;
273         }
274 
275     private:
276         const glw::Functions &m_gl;
277     };
278 };
279 
280 /** Implements test APIErrors, description follows:
281  *
282  *   Verify that API generate errors as specified. Check that:
283  *   * DepthRangeArrayv generates INVALID_VALUE when <first> + <count> is greater
284  *   than or equal to the value of MAX_VIEWPORTS;
285  *   * DepthRangeIndexed generates INVALID_VALUE when <index> is greater than or
286  *   equal to the value of MAX_VIEWPORTS;
287  *   * ViewportArrayv generates INVALID_VALUE when <first> + <count> is greater
288  *   than or equal to the value of MAX_VIEWPORTS;
289  *   * ViewportIndexedf and ViewportIndexedfv generate INVALID_VALUE when <index>
290  *   is greater than or equal to the value of MAX_VIEWPORTS;
291  *   * ViewportArrayv, Viewport, ViewportIndexedf and ViewportIndexedfv generate
292  *   INVALID_VALUE when <w> or <h> values are negative;
293  *   * ScissorArrayv generates INVALID_VALUE when <first> + <count> is greater
294  *   than or equal to the value of MAX_VIEWPORTS;
295  *   * ScissorIndexed and ScissorIndexedv generate INVALID_VALUE when <index> is
296  *   greater than or equal to the value of MAX_VIEWPORTS;
297  *   * ScissorArrayv, ScissorIndexed, ScissorIndexedv and Scissor generate
298  *   INVALID_VALUE when <width> or <height> values are negative;
299  *   * Disablei, Enablei and IsEnabledi generate INVALID_VALUE when <cap> is
300  *   SCISSOR_TEST and <index> is greater than or equal to the
301  *   value of MAX_VIEWPORTS;
302  *   * GetIntegeri_v generates INVALID_VALUE when <target> is SCISSOR_BOX and
303  *   <index> is greater than or equal to the value of MAX_VIEWPORTS;
304  *   * GetFloati_v generates INVALID_VALUE when <target> is VIEWPORT and <index>
305  *   is greater than or equal to the value of MAX_VIEWPORTS;
306  *   * GetDoublei_v generates INVALID_VALUE when <target> is DEPTH_RANGE and
307  *   <index> is greater than or equal to the value of MAX_VIEWPORTS;
308  **/
309 class APIErrors : public glcts::TestCaseBase
310 {
311 public:
312     /* Public methods */
313     APIErrors(deqp::Context &context, const glcts::ExtParameters &extParams);
314 
~APIErrors()315     virtual ~APIErrors()
316     {
317     }
318 
319     /* Public methods inherited from TestCaseBase */
320     virtual IterateResult iterate(void);
321 
322 private:
323     template <typename T>
324     void depthRangeArrayHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result,
325                                T *data = NULL);
326 
327     template <typename T>
328     void depthRangeIndexedHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result,
329                                  T *data = NULL);
330 
331     template <typename T>
332     void getDepthHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result,
333                         T *data = NULL);
334 
335     void checkGLError(glw::GLenum expected_error, const glw::GLchar *description, bool &out_result);
336 };
337 
338 /** Implements test Queries, description follows:
339  *
340  *   Verify that:
341  *   * Initial dimensions of VIEWPORT returned by GetFloati_v match dimensions of
342  *   the window into which GL is rendering;
343  *   * Initial values of DEPTH_RANGE returned by GetDoublei_v are [0, 1];
344  *   * Initial state of SCISSOR_TEST returned by IsEnabledi is FALSE;
345  *   * Initial dimensions of SCISSOR_BOX returned by GetIntegeri_v are either
346  *   zeros or match dimensions of the window into which GL is rendering;
347  *   * Dimensions of MAX_VIEWPORT_DIMS returned by GetFloati_v are at least
348  *   as big as supported dimensions of render buffers, see MAX_RENDERBUFFER_SIZE;
349  *   * Value of MAX_VIEWPORTS returned by GetIntegeri_v is at least 16;
350  *   * Value of VIEWPORT_SUBPIXEL_BITS returned by GetIntegeri_v is at least 0;
351  *   * Values of VIEWPORT_BOUNDS_RANGE returned by GetFloatv are
352  *   at least [-32768, 32767];
353  *   * Values of LAYER_PROVOKING_VERTEX and VIEWPORT_INDEX_PROVOKING_VERTEX
354  *   returned by GetIntegerv are located in the following set
355  *   { FIRST_VERTEX_CONVENTION, LAST_VERTEX_CONVENTION, PROVOKING_VERTEX,
356  *   UNDEFINED_VERTEX };
357  **/
358 class Queries : public glcts::TestCaseBase
359 {
360 public:
361     /* Public methods */
362     Queries(deqp::Context &context, const glcts::ExtParameters &extParams);
363 
~Queries()364     virtual ~Queries()
365     {
366     }
367 
368     /* Public methods inherited from TestCase */
369     virtual tcu::TestNode::IterateResult iterate(void);
370 
371 private:
372     template <typename T>
373     void depthRangeInitialValuesHelper(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, bool &test_result,
374                                        T *data = NULL);
375 };
376 
377 /** Implements test ViewportAPI, description follows:
378  *
379  *   Verify that VIEWPORT can be set and queried.
380  *   Steps:
381  *   - get initial dimensions of VIEWPORT for all MAX_VIEWPORTS indices;
382  *   - change location and dimensions of all indices at once with
383  *   ViewportArrayv;
384  *   - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
385  *   - for each index:
386  *     * modify with ViewportIndexedf,
387  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
388  *     * modify with ViewportIndexedfv,
389  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
390  *   - for each index:
391  *     * modify all indices before and after current one with ViewportArrayv,
392  *     * get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
393  *   - change location and dimensions of all indices at once with Viewport;
394  *   - get VIEWPORT for all MAX_VIEWPORTS indices and verify results;
395  **/
396 class ViewportAPI : public glcts::TestCaseBase
397 {
398 public:
399     /* Public methods */
400     ViewportAPI(deqp::Context &context, const glcts::ExtParameters &extParams);
401 
~ViewportAPI()402     virtual ~ViewportAPI()
403     {
404     }
405 
406     /* Public methods inherited from TestCase */
407     virtual tcu::TestNode::IterateResult iterate(void);
408 
409 private:
410     /* Private methods */
411     void compareViewports(std::vector<glw::GLfloat> &left, std::vector<glw::GLfloat> &right,
412                           const glw::GLchar *description, bool &out_result);
413 
414     void getViewports(glw::GLint max_viewports, std::vector<glw::GLfloat> &out_data);
415 
416     /* Private constants */
417     static const glw::GLuint m_n_elements;
418 };
419 
420 /** Implements test ScissorAPI, description follows:
421  *
422  *   Verify that SCISSOR_BOX can be set and queried.
423  *   Steps:
424  *   - get initial dimensions of SCISSOR_BOX for all MAX_VIEWPORTS indices;
425  *   - change location and dimensions of all indices at once with
426  *   ScissorArrayv;
427  *   - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
428  *   - for each index:
429  *     * modify with ScissorIndexed,
430  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
431  *     * modify with ScissorIndexedv,
432  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
433  *   - for each index:
434  *     * modify all indices before and after current one with ScissorArrayv,
435  *     * get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
436  *   - change location and dimensions of all indices at once with Scissor;
437  *   - get SCISSOR_BOX for all MAX_VIEWPORTS indices and verify results;
438  **/
439 class ScissorAPI : public glcts::TestCaseBase
440 {
441 public:
442     /* Public methods */
443     ScissorAPI(deqp::Context &context, const glcts::ExtParameters &extParams);
444 
~ScissorAPI()445     virtual ~ScissorAPI()
446     {
447     }
448 
449     /* Public methods inherited from TestCase */
450     virtual tcu::TestNode::IterateResult iterate(void);
451 
452 private:
453     /* Private methods */
454     void compareScissorBoxes(std::vector<glw::GLint> &left, std::vector<glw::GLint> &right,
455                              const glw::GLchar *description, bool &out_result);
456 
457     void getScissorBoxes(glw::GLint max_viewports, std::vector<glw::GLint> &out_data);
458 
459     /* Private constants */
460     static const glw::GLuint m_n_elements;
461 };
462 
463 /** Implements test DepthRangeAPI, description follows:
464  *
465  *   Verify that DEPTH_RANGE can be set and queried.
466  *   Steps:
467  *   - get initial values of DEPTH_RANGE for all MAX_VIEWPORTS indices;
468  *   - change values of all indices at once with DepthRangeArrayv;
469  *   - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
470  *   - for each index:
471  *     * modify with DepthRangeIndexed,
472  *     * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
473  *   - for each index:
474  *     * modify all indices before and after current one with DepthRangeArrayv,
475  *     * get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
476  *   - change values of all indices at once with DepthRange;
477  *   - get DEPTH_RANGE for all MAX_VIEWPORTS indices and verify results;
478  **/
479 class DepthRangeAPI : public glcts::TestCaseBase
480 {
481 public:
482     /* Public methods */
483     DepthRangeAPI(deqp::Context &context, const glcts::ExtParameters &extParams);
484 
~DepthRangeAPI()485     virtual ~DepthRangeAPI()
486     {
487     }
488 
489     /* Public methods inherited from TestCase */
490     virtual tcu::TestNode::IterateResult iterate(void);
491 
492 private:
493     /* Private methods */
494     template <typename T>
495     void compareDepthRanges(std::vector<T> &left, std::vector<T> &right, const glw::GLchar *description,
496                             bool &out_result);
497 
498     template <typename T>
499     void getDepthRanges(Utils::DepthFuncWrapper &depthFunc, glw::GLint max_viewports, std::vector<T> &out_data);
500 
501     template <typename T>
502     bool iterateHelper(T *data = NULL);
503 
504     /* Private constants */
505     static const glw::GLuint m_n_elements;
506 };
507 
508 /** Implements test ScissorTestStateAPI, description follows:
509  *
510  *   Verify that state of SCISSOR_TEST can be set and queried.
511  *   Steps:
512  *   - get initial state of SCISSOR_TEST for all MAX_VIEWPORTS indices;
513  *   - for each index:
514  *     * toggle SCISSOR_TEST,
515  *     * get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
516  *   - for each index:
517  *     * toggle SCISSOR_TEST,
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  *   - disable SCISSOR_TEST for all indices at once with Disable;
522  *   - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
523  *   - enable SCISSOR_TEST for all indices at once with Enable;
524  *   - get state of SCISSOR_TEST for all MAX_VIEWPORTS indices and verify;
525  **/
526 class ScissorTestStateAPI : public glcts::TestCaseBase
527 {
528 public:
529     /* Public methods */
530     ScissorTestStateAPI(deqp::Context &context, const glcts::ExtParameters &extParams);
531 
~ScissorTestStateAPI()532     virtual ~ScissorTestStateAPI()
533     {
534     }
535 
536     /* Public methods inherited from TestCase */
537     virtual tcu::TestNode::IterateResult iterate(void);
538 
539 private:
540     /* Private methods */
541     void compareScissorTestStates(std::vector<glw::GLboolean> &left, std::vector<glw::GLboolean> &right,
542                                   const glw::GLchar *description, bool &out_result);
543 
544     void getScissorTestStates(glw::GLint max_viewports, std::vector<glw::GLboolean> &out_data);
545 };
546 
547 class DrawTestBase : public glcts::TestCaseBase
548 {
549 public:
550     /* Public methods */
551     DrawTestBase(deqp::Context &context, const glcts::ExtParameters &extParams, const glw::GLchar *test_name,
552                  const glw::GLchar *test_description);
553 
~DrawTestBase()554     virtual ~DrawTestBase()
555     {
556     }
557 
558     /* Public methods inherited from TestCase */
559     virtual tcu::TestNode::IterateResult iterate(void);
560 
561 protected:
562     /* Protected enums */
563     enum VIEWPORT_METHOD
564     {
565         VIEWPORTARRAYV = 0,
566         VIEWPORTINDEXEDF,
567         VIEWPORTINDEXEDF_V,
568     };
569     enum SCISSOR_METHOD
570     {
571         SCISSORARRAYV = 0,
572         SCISSORINDEXEDF,
573         SCISSORINDEXEDF_V,
574     };
575     enum DEPTH_RANGE_METHOD
576     {
577         DEPTHRANGEARRAYV = 0,
578         DEPTHRANGEINDEXED,
579     };
580     enum PROVOKING_VERTEX
581     {
582         FIRST,
583         LAST,
584     };
585     enum TEST_TYPE
586     {
587         VIEWPORT,
588         SCISSOR,
589         DEPTHRANGE,
590         PROVOKING,
591     };
592 
593     /* Protected methods to be implemented by child class */
594     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
595 
596     virtual void getClearSettings(bool &clear_depth_before_draw, glw::GLuint iteration_index,
597                                   glw::GLfloat &depth_value);
598 
599     virtual glw::GLuint getDrawCallsNumber();
600     virtual std::string getFragmentShader() = 0;
601     virtual std::string getGeometryShader() = 0;
602     virtual TEST_TYPE getTestType();
603     virtual bool isClearTest();
604 
605     virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1);
606 
607     virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index);
608 
609     virtual void setupFramebuffer(Utils::framebuffer &framebuffer, Utils::texture &texture_0,
610                                   Utils::texture &texture_1);
611 
612     virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
613 
614     /* Methods available for child class */
615     bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLint expected_value, glw::GLint *data);
616 
617     bool checkRegionR32I(glw::GLuint x, glw::GLuint y, glw::GLuint width, glw::GLuint height, glw::GLint expected_value,
618                          glw::GLint *data);
619 
620     void prepareTextureR32I(Utils::texture &texture);
621     void prepareTextureR32Ix4(Utils::texture &texture);
622     void prepareTextureArrayR32I(Utils::texture &texture);
623     void prepareTextureR32F(Utils::texture &texture);
624     void prepareTextureD32F(Utils::texture &texture);
625     void setup16x2Depths(DEPTH_RANGE_METHOD method);
626     void setup4x4Scissor(SCISSOR_METHOD method, bool set_zeros);
627     void setup4x4Viewport(VIEWPORT_METHOD method);
628     void setup2x2Viewport(PROVOKING_VERTEX provoking);
629 
630     /* Constants available to child class */
631     static const glw::GLuint m_depth;
632     static const glw::GLuint m_height;
633     static const glw::GLuint m_width;
634     static const glw::GLuint m_r32f_height;
635     static const glw::GLuint m_r32f_width;
636     static const glw::GLuint m_r32ix4_depth;
637 
638 private:
639     /* Private methods */
640     std::string getVertexShader();
641 
642     template <typename T>
643     void setup16x2DepthsHelper(DEPTH_RANGE_METHOD method, T *data = NULL);
644 };
645 
646 /** Implements test DrawToSingleLayerWithMultipleViewports, description follows:
647  *
648  *   Verify that multiple viewports can be used to draw to single image.
649  *   Steps:
650  *   - prepare 2D R32I 128x128 texture filled with value -1 and set it up as
651  *   COLOR_ATTACHMENT_0;
652  *   - prepare program that consist of:
653  *     * boilerplate vertex shader,
654  *     * geometry shader,
655  *     * fragment shaders;
656  *   Geometry shader should output a quad (-1,-1 : 1,1) made of
657  *   triangle_strip; gl_ViewportIndex and declared integer varying "color"
658  *   should be assigned the value of gl_InvocationID; Amount of geometry shader
659  *   invocations should be set to 16; Fragment shader should output value of
660  *   varying "color" to attachment 0.
661  *   - set up first 16 viewports with following code snippet:
662  *
663  *       index = 0;
664  *       for (y = 0; y < 4; ++y)
665  *         for (x = 0; x < 4; ++x)
666  *           ViewportIndexedf(index++,
667  *                            x * 32 x offset,
668  *                            y * 32 y offset,
669  *                            32     width   ,
670  *                            32     height  );
671  *   - draw single vertex;
672  *   - inspect contents of COLOR_ATTACHMENT_0;
673  *   - test pass if image is filled with the following pattern:
674  *
675  *       0  1  2  3
676  *       4  5  6  7
677  *       8  9  10 11
678  *       12 13 14 15;
679  *
680  *   Each area should be 32x32 pixels rectangle;
681  *   - repeat test with functions ViewportIndexedf_v and ViewportArrayv;
682  **/
683 class DrawToSingleLayerWithMultipleViewports : public DrawTestBase
684 {
685 public:
686     /* Public methods */
687     DrawToSingleLayerWithMultipleViewports(deqp::Context &context, const glcts::ExtParameters &extParams);
688 
~DrawToSingleLayerWithMultipleViewports()689     virtual ~DrawToSingleLayerWithMultipleViewports()
690     {
691     }
692 
693 protected:
694     /* Protected methods inherited from DrawTestBase */
695     virtual std::string getFragmentShader();
696     virtual std::string getGeometryShader();
697 };
698 
699 /** Implements test DynamicViewportIndex, description follows:
700  *
701  *   Verify that gl_ViewportIndex can be set in dynamic manner.
702  *   Modify DrawToSingleLayerWithMultipleViewports in the following aspects:
703  *   - geometry shader should declare unsigned integer uniform "index";
704  *   - geometry shader should assign a value of "index" to gl_ViewportIndex and
705  *   "color";
706  *   - amount of geometry shader invocations should be set to 1;
707  *   - 16 times:
708  *     * set "index" to unique value from range <0:15>;
709  *     * draw single vertex;
710  *     * verify that only area of viewport at "index" has been updated;
711  *   - test pass if correct pixels were modified in each draw;
712  **/
713 class DynamicViewportIndex : public DrawTestBase
714 {
715 public:
716     /* Public methods */
717     DynamicViewportIndex(deqp::Context &context, const glcts::ExtParameters &extParams);
718 
~DynamicViewportIndex()719     virtual ~DynamicViewportIndex()
720     {
721     }
722 
723 protected:
724     /* Protected methods inherited from DrawTestBase */
725     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
726 
727     virtual std::string getFragmentShader();
728     virtual std::string getGeometryShader();
729     virtual glw::GLuint getDrawCallsNumber();
730 
731     virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index);
732 };
733 
734 /** Implements test DrawMulitpleViewportsWithSingleInvocation, description follows:
735  *
736  *   Verify that multiple viewports can be affected by single invocation of
737  *   geometry shader.
738  *   Modify DrawToSingleLayerWithMultipleViewports in the following aspects:
739  *   - geometry shader should output 16 quads, as separate primitives;
740  *   - instead of gl_InvocationID, geometry shader should use predefined values
741  *   from range <0:15>, unique per quad;
742  *   - amount of geometry shader invocations should be set to 1;
743  **/
744 class DrawMulitpleViewportsWithSingleInvocation : public DrawTestBase
745 {
746 public:
747     /* Public methods */
748     DrawMulitpleViewportsWithSingleInvocation(deqp::Context &context, const glcts::ExtParameters &extParams);
749 
~DrawMulitpleViewportsWithSingleInvocation()750     virtual ~DrawMulitpleViewportsWithSingleInvocation()
751     {
752     }
753 
754 protected:
755     /* Protected methods inherited from DrawTestBase */
756     virtual std::string getFragmentShader();
757     virtual std::string getGeometryShader();
758 };
759 
760 /** Implements test ViewportIndexSubroutine, description follows:
761  *
762  *   Verify that gl_ViewportIndex can be assigned by subroutine.
763  *   Depends on: ARB_shader_subroutine.
764  *   Modify DynamicViewportIndex in the following aspects:
765  *   - geometry shader should define two subroutines and single subroutine
766  *   uniform; First subroutine should assign value 4 to gl_ViewportIndex and
767  *   "color"; Second subroutine should assign value 5 to gl_ViewportIndex and
768  *   "color"; subroutine should be called once per emitted vertex;
769  *   - uniform "index" should be removed;
770  *   - viewport 4 should be configured to span over left half of image; viewport
771  *   5 should span over right half of image;
772  *   - set up first subroutine and draw single vertex;
773  *   - set up second subroutine and draw single vertex;
774  *   - test pass if left half of image is filled with value 4 and right one with
775  *   5;
776  **/
777 class ViewportIndexSubroutine : public DrawTestBase
778 {
779 public:
780     /* Public methods */
781     ViewportIndexSubroutine(deqp::Context &context, const glcts::ExtParameters &extParams);
782 
~ViewportIndexSubroutine()783     virtual ~ViewportIndexSubroutine()
784     {
785     }
786 
787     /* Public methods inherited from TestCase/DrawTestBase */
788     virtual tcu::TestNode::IterateResult iterate(void);
789 
790 protected:
791     /* Protected methods inherited from DrawTestBase */
792     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
793 
794     virtual std::string getFragmentShader();
795     virtual std::string getGeometryShader();
796     virtual glw::GLuint getDrawCallsNumber();
797 
798     virtual void prepareUniforms(Utils::program &program, glw::GLuint draw_call_index);
799 
800     virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
801 };
802 
803 /** Implements test DrawMultipleLayers, description follows:
804  *
805  *   Verify that single viewport affects multiple layers in the same way.
806  *   Modify DynamicViewportIndex in the following aspects:
807  *   - texture should be 2D array with 16 layers;
808  *   - geometry shader should assign a value of gl_InvocationId to gl_Layer;
809  *   - amount of geometry shader invocations should be set to 16;
810  *   - verification should be applied to all 16 layers;
811  **/
812 class DrawMultipleLayers : public DrawTestBase
813 {
814 public:
815     /* Public methods */
816     DrawMultipleLayers(deqp::Context &context, const glcts::ExtParameters &extParams);
817 
818     DrawMultipleLayers(deqp::Context &context, const glcts::ExtParameters &extParams, const glw::GLchar *test_name,
819                        const glw::GLchar *test_description);
820 
~DrawMultipleLayers()821     virtual ~DrawMultipleLayers()
822     {
823     }
824 
825 protected:
826     /* Protected methods inherited from DrawTestBase */
827     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
828 
829     virtual std::string getFragmentShader();
830     virtual std::string getGeometryShader();
831 
832     virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1);
833 };
834 
835 /** Implements test Scissor, description follows:
836  *
837  *   Verify that scissor test is applied as expected.
838  *   Modify DrawMultipleLayers in the following aspects:
839  *   - set all viewports to location 0,0 and dimensions 128x128;
840  *   - set up first 16 scissor boxes with following code snippet:
841  *
842  *       index = 0;
843  *       for (y = 0; y < 4; ++y)
844  *         for (x = 0; x < 4; ++x)
845  *           ScissorIndexed(index++,
846  *                          x * 32 x offset,
847  *                          y * 32 y offset,
848  *                          32     width   ,
849  *                          32     height  );
850  *
851  *   - enable SCISSORT_TEST for first 16 indices;
852  *   - verification should be concerned with areas of the scissor boxes not
853  *   viewports;
854  *   - repeat test with functions ScissorIndexedv and ScissorArrayv;
855  **/
856 class Scissor : public DrawMultipleLayers
857 {
858 public:
859     /* Public methods */
860     Scissor(deqp::Context &context, const glcts::ExtParameters &extParams);
861 
~Scissor()862     virtual ~Scissor()
863     {
864     }
865 
866 protected:
867     /* Protected methods inherited from DrawTestBase */
868     virtual TEST_TYPE getTestType();
869 };
870 
871 /** Implements test ScissorZeroDimension, description follows:
872  *
873  *   Verify that scissor test discard all fragments when width and height is set
874  *   to zero.
875  *   Modify Scissor to set up width and height of scissor boxes to 0.
876  *   Test pass if no pixel is modified.
877  **/
878 class ScissorZeroDimension : public DrawMultipleLayers
879 {
880 public:
881     /* Public methods */
882     ScissorZeroDimension(deqp::Context &context, const glcts::ExtParameters &extParams);
883 
~ScissorZeroDimension()884     virtual ~ScissorZeroDimension()
885     {
886     }
887 
888 protected:
889     /* Protected methods inherited from DrawTestBase */
890     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
891 
892     virtual TEST_TYPE getTestType();
893 
894     virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
895 };
896 
897 /** Implements test ScissorClear, description follows:
898  *
899  *   Verify that Clear is affected only by settings of scissor test in first
900  *   viewport.
901  *   Steps:
902  *   - prepare 2D 128x128 R32I texture, filled with value -1 and set it as
903  *   COLOR_ATTACHMENT_0;
904  *   - configure first 16 viewports as in Scissor;
905  *   - enable SCISSOR_TEST for first 16 indices;
906  *   - clear framebuffer to (0, 0, 0, 0);
907  *   - inspect image;
908  *   - test pass if only area corresponding with first SCISSOR_BOX was filled
909  *   with 0, while rest of image remain filled with value -1;
910  **/
911 class ScissorClear : public DrawMultipleLayers
912 {
913 public:
914     /* Public methods */
915     ScissorClear(deqp::Context &context, const glcts::ExtParameters &extParams);
916 
~ScissorClear()917     virtual ~ScissorClear()
918     {
919     }
920 
921 protected:
922     /* Protected methods inherited from DrawTestBase */
923     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
924 
925     virtual TEST_TYPE getTestType();
926     virtual bool isClearTest();
927 };
928 
929 /** Implements test DepthRange, description follows:
930  *
931  *   Verify that depth range is applied as expected.
932  *   Steps:
933  *   - prepate 2D 16x2 R32F texture filled with value -1.0 and set it up as
934  *   COLOR_ATTACHMENT_0;
935  *   - prepare program that consist of:
936  *     * boilerplate vertex shader,
937  *     * geometry shader,
938  *     * fragment shader;
939  *   Geometry shader should emit two quads:
940  *     * -1,0 : 1,1 with z equal -1.0,
941  *     * -1,-1 : 1,0 with z equal 1.0,
942  *   made of triangle_strip; gl_ViewportIndex should be assigned an value of
943  *   gl_InvocationId; Amount of geometry shader invocations should be set to 16;
944  *   Fragment shader should output value of gl_FragCoord.z to attachment 0.
945  *   - set up first 16 viewports with the following code snippet:
946  *
947  *       const double step = 1.0 / 16.0;
948  *       for (index = 0; index < 16; ++index)
949  *       {
950  *           const double near = ((double) i) * step;
951  *           VieportIndexed   (i, (float) i, 0.0, 1.0, 2.0);
952  *           DepthRangeIndexed(i, near,      1.0 - near);
953  *       }
954  *
955  *   - draw single vertex;
956  *   - inspect contents of COLOR_ATTACHMENT_0;
957  *   - test pass if:
958  *     * top row of image is filled with increasing values, starting at 0 with
959  *     step 1/16;
960  *     * bottom row of image is filled with decreasing values, starting at 1 with
961  *     step 1/16;
962  *   - repeat test with function DepthRangeArrayv;
963  **/
964 class DepthRange : public DrawTestBase
965 {
966 public:
967     /* Public methods */
968     DepthRange(deqp::Context &context, const glcts::ExtParameters &extParams);
~DepthRange()969     virtual ~DepthRange()
970     {
971     }
972 
973 protected:
974     /* Protected methods inherited from DrawTestBase */
975     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
976 
977     virtual std::string getFragmentShader();
978     virtual std::string getGeometryShader();
979     virtual TEST_TYPE getTestType();
980 
981     virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1);
982 };
983 
984 /** Implements test DepthRangeDepthTest, description follows:
985  *
986  *   Verify that depth test work as expected with multiple viewports.
987  *   Modify DepthRange test in the following aspect:
988  *   - add second 2D 16x2 DEPTH_COMPONENT32F texture and set it up as
989  *   DEPTH_ATTACHMENT;
990  *   - enable DEPTH_TEST;
991  *   - DepthFunc should be set to LESS (initial value);
992  *   - 18 times:
993  *     * set ClearDepth to "i" * 1/16, starting at 0 up to 17/16,
994  *     * draw single vertex
995  *     * verify contents of color attachment;
996  *   - test pass when color attachment is filled only with values lower than
997  *   current ClearDepth value;
998  **/
999 class DepthRangeDepthTest : public DrawTestBase
1000 {
1001 public:
1002     /* Public methods */
1003     DepthRangeDepthTest(deqp::Context &context, const glcts::ExtParameters &extParams);
1004 
~DepthRangeDepthTest()1005     virtual ~DepthRangeDepthTest()
1006     {
1007     }
1008 
1009 protected:
1010     /* Protected methods inherited from DrawTestBase */
1011     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
1012 
1013     virtual void getClearSettings(bool &clear_depth_before_draw, glw::GLuint iteration_index,
1014                                   glw::GLfloat &depth_value);
1015 
1016     virtual glw::GLuint getDrawCallsNumber();
1017     virtual std::string getFragmentShader();
1018     virtual std::string getGeometryShader();
1019     virtual TEST_TYPE getTestType();
1020 
1021     virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1);
1022 
1023     virtual void setupFramebuffer(Utils::framebuffer &framebuffer, Utils::texture &texture_0,
1024                                   Utils::texture &texture_1);
1025 
1026     virtual void setupViewports(TEST_TYPE type, glw::GLuint iteration_index);
1027 };
1028 
1029 /** Implements test ProvokingVertex, description follows:
1030  *
1031  *   Verify that provoking vertex work as expected.
1032  *   Steps:
1033  *   - prepare 2D array R32I 128x128x4 texture and configure it as
1034  *   COLOR_ATTACHMENT_0;
1035  *   - prepare program consisting of:
1036  *     * boilerplate vertex shader,
1037  *     * geometry shader,
1038  *     * fragment shader;
1039  *   Geometry shader should output a quad (-1,-1 : 1,1); Each vertex should
1040  *   receive different gl_ViewportIndex value, first vertex should be assigned an
1041  *   0, second 1, third 2, fourth 3; gl_Layer should be set in the same way as
1042  *   gl_ViewportIndex; Fragment shader should output integer of value 1;
1043  *   - configure first four viewports to form 2x2 grid, spanning whole image;
1044  *   - for each combination of LAYER_PROVOKING_VERTEX and
1045  *   VIEWPORT_INDEX_PROVOKING_VERTEX:
1046  *     * clear framebuffer to (0,0,0,0),
1047  *     * draw single vertex
1048  *     * inspect image;
1049  *   - test pass if correct area of correct layer is filled with value 1, while
1050  *   rest of image remains "clean";
1051  *   Notes:
1052  *   - for UNDEFINED_VERTEX any selection is correct;
1053  *   - for PROVOKING_VERTEX convention is selected by function ProvokingVertex;
1054  *   Test all possible combinations;
1055  **/
1056 class ProvokingVertex : public DrawTestBase
1057 {
1058 public:
1059     /* Public methods */
1060     ProvokingVertex(deqp::Context &context, const glcts::ExtParameters &extParams);
1061 
~ProvokingVertex()1062     virtual ~ProvokingVertex()
1063     {
1064     }
1065 
1066 protected:
1067     /* Protected methods inherited from DrawTestBase */
1068     virtual bool checkResults(Utils::texture &texture_0, Utils::texture &texture_1, glw::GLuint draw_call_index);
1069 
1070     virtual std::string getFragmentShader();
1071     virtual std::string getGeometryShader();
1072     virtual TEST_TYPE getTestType();
1073 
1074     virtual void prepareTextures(Utils::texture &texture_0, Utils::texture &texture_1);
1075 };
1076 } // namespace ViewportArray
1077 
1078 /** Group class for Shader Language 420Pack conformance tests */
1079 class ViewportArrayTests : public glcts::TestCaseGroupBase
1080 {
1081 public:
1082     /* Public methods */
1083     ViewportArrayTests(deqp::Context &context, const glcts::ExtParameters &extParams);
1084 
~ViewportArrayTests(void)1085     virtual ~ViewportArrayTests(void)
1086     {
1087     }
1088 
1089     virtual void init(void);
1090 
1091 private:
1092     /* Private methods */
1093     ViewportArrayTests(const ViewportArrayTests &other);
1094     ViewportArrayTests &operator=(const ViewportArrayTests &other);
1095 };
1096 
1097 } // namespace glcts
1098 
1099 #endif // _GLCVIEWPORTARRAYTESTS_HPP
1100