1 #ifndef _ESEXTCTESSELLATIONSHADERBARRIER_HPP
2 #define _ESEXTCTESSELLATIONSHADERBARRIER_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 #include "gluShaderUtil.hpp"
27 #include "tcuDefs.hpp"
28 
29 #include "../esextcTestCaseBase.hpp"
30 
31 namespace glcts
32 {
33 
34 /* Groups all barrier tests */
35 class TessellationShaderBarrierTests : public TestCaseGroupBase
36 {
37 public:
38     /* Public methods */
39     TessellationShaderBarrierTests(Context &context, const ExtParameters &extParams);
40 
41     virtual void init(void);
42 };
43 
44 /** Base class for all tests that check the memory barrier functionality.
45  **/
46 class TessellationShaderBarrierTestCase : public TestCaseBase
47 {
48 public:
49     /* Public methods */
50     TessellationShaderBarrierTestCase(Context &context, const ExtParameters &extParams, const char *name,
51                                       const char *description);
52 
~TessellationShaderBarrierTestCase(void)53     virtual ~TessellationShaderBarrierTestCase(void)
54     {
55     }
56 
57     virtual void deinit();
58     virtual void initTest(void);
59     virtual IterateResult iterate(void);
60 
61 protected:
62     /* Protected methods */
63     virtual void getDrawCallArgs(glw::GLenum *out_mode, glw::GLint *out_count, glw::GLenum *out_tf_mode,
64                                  glw::GLint *out_n_patch_vertices, glw::GLint *out_n_instances) = 0;
65 
66     virtual const char *getTCSCode()                                         = 0;
67     virtual const char *getTESCode()                                         = 0;
68     virtual const char *getVSCode()                                          = 0;
69     virtual int getXFBBufferSize()                                           = 0;
70     virtual void getXFBProperties(int *out_n_names, const char ***out_names) = 0;
71     virtual bool verifyXFBBuffer(const void *data)                           = 0;
72 
73     /* Protected variables */
74     glw::GLuint m_bo_id;
75     glw::GLuint m_fs_id;
76     glw::GLuint m_po_id;
77     glw::GLuint m_tcs_id;
78     glw::GLuint m_tes_id;
79     glw::GLuint m_vao_id;
80     glw::GLuint m_vs_id;
81 };
82 
83 /** Implementation of Test Case 22.1
84  *
85  *  Make sure that a barrier used in a tessellation control shader synchronizes
86  *  all instances working on the same patch. Tests the following scenario:
87  *
88  * * invocation A can correctly read a per-vertex & per-patch attribute
89  *    modified by invocation B after a barrier() call;
90  **/
91 class TessellationShaderBarrier1 : public TessellationShaderBarrierTestCase
92 {
93 public:
94     /* Public methods */
95     TessellationShaderBarrier1(Context &context, const ExtParameters &extParams);
96 
~TessellationShaderBarrier1(void)97     virtual ~TessellationShaderBarrier1(void)
98     {
99     }
100 
101 protected:
102     /* Protected methods */
103     void getDrawCallArgs(glw::GLenum *out_mode, glw::GLint *out_count, glw::GLenum *out_tf_mode,
104                          glw::GLint *out_n_patch_vertices, glw::GLint *out_n_instances);
105 
106     const char *getTCSCode();
107     const char *getTESCode();
108     const char *getVSCode();
109     int getXFBBufferSize();
110     void getXFBProperties(int *out_n_names, const char ***out_names);
111     bool verifyXFBBuffer(const void *data);
112 
113 private:
114     /* Private fields */
115     unsigned int m_n_input_vertices;
116     const unsigned int m_n_result_vertices;
117 };
118 
119 /** Implementation of Test Case 22.2
120  *
121  *  Make sure that a barrier used in a tessellation control shader synchronizes
122  *  all instances working on the same patch. Tests the following scenario:
123  *
124  * * invocation A writes to a per-patch output. A barrier is then issued,
125  *   after which invocation B overwrites the same per-patch output. One more
126  *   barrier is issued, after which invocation A should be able to read this
127  *   output correctly.
128  **/
129 class TessellationShaderBarrier2 : public TessellationShaderBarrierTestCase
130 {
131 public:
132     /* Public methods */
133     TessellationShaderBarrier2(Context &context, const ExtParameters &extParams);
134 
~TessellationShaderBarrier2(void)135     virtual ~TessellationShaderBarrier2(void)
136     {
137     }
138 
139 protected:
140     /* Protected methods */
141     void getDrawCallArgs(glw::GLenum *out_mode, glw::GLint *out_count, glw::GLenum *out_tf_mode,
142                          glw::GLint *out_n_patch_vertices, glw::GLint *out_n_instances);
143 
144     const char *getTCSCode();
145     const char *getTESCode();
146     const char *getVSCode();
147     int getXFBBufferSize();
148     void getXFBProperties(int *out_n_names, const char ***out_names);
149     bool verifyXFBBuffer(const void *data);
150 
151 private:
152     /* Private fields */
153     unsigned int m_n_input_vertices;
154     const unsigned int m_n_result_vertices;
155 };
156 
157 /** Implementation of Test Case 22.3
158  *
159  *  Make sure that a barrier used in a tessellation control shader synchronizes
160  *  all instances working on the same patch. Tests the following scenario:
161  *
162  * * even invocations should write their gl_InvocationID value to their
163  *   per-vertex output. A barrier is then issued, after which each odd invocation
164  *   should read values stored by preceding even invocation, add current
165  *   invocation's ID to that value and then write it to its per-vertex output.
166  *   One more barrier should be issued. Then, every fourth invocation should
167  *   read & sum up per-vertex outputs for four invocations following it
168  *   (including the one discussed), and store it in a per-patch variable. (n+1)-th,
169  *   (n+2)-th and (n+3)-th invocations should store zero in dedicated per-patch
170  *   variables. 16 invocations should be considered, with 10 instances used for the
171  *   draw call, each patch should consist of 8 vertices.
172  **/
173 class TessellationShaderBarrier3 : public TessellationShaderBarrierTestCase
174 {
175 public:
176     /* Public methods */
177     TessellationShaderBarrier3(Context &context, const ExtParameters &extParams);
178 
~TessellationShaderBarrier3(void)179     virtual ~TessellationShaderBarrier3(void)
180     {
181     }
182 
183 protected:
184     /* Protected methods */
185     void getDrawCallArgs(glw::GLenum *out_mode, glw::GLint *out_count, glw::GLenum *out_tf_mode,
186                          glw::GLint *out_n_patch_vertices, glw::GLint *out_n_instances);
187 
188     const char *getTCSCode();
189     const char *getTESCode();
190     const char *getVSCode();
191     int getXFBBufferSize();
192     void getXFBProperties(int *out_n_names, const char ***out_names);
193     bool verifyXFBBuffer(const void *data);
194 
195 private:
196     /* Private fields */
197     unsigned int m_n_input_vertices;
198     const unsigned int m_n_instances;
199     const unsigned int m_n_invocations;
200     const unsigned int m_n_patch_vertices;
201     const unsigned int m_n_patches_per_invocation;
202     const unsigned int m_n_result_vertices;
203 };
204 
205 } // namespace glcts
206 
207 #endif // _ESEXTCTESSELLATIONSHADERBARRIER_HPP
208