xref: /aosp_15_r20/external/deqp/external/openglcts/modules/gl/gl4cShaderAtomicCounterOpsTests.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GL4CSHADERATOMICCOUNTEROPSTESTS_HPP
2 #define _GL4CSHADERATOMICCOUNTEROPSTESTS_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2017 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  gl4cShaderAtomicCounterOpsTests.hpp
23  * \brief Conformance tests for the ARB_shader_atomic_counter_ops functionality.
24  */ /*-------------------------------------------------------------------*/
25 
26 #include "deUniquePtr.hpp"
27 #include "glcTestCase.hpp"
28 #include "gluShaderProgram.hpp"
29 
30 #include <algorithm>
31 #include <map>
32 #include <string>
33 
34 namespace gl4cts
35 {
36 
37 class ShaderAtomicCounterOpsTestBase : public deqp::TestCase
38 {
39 public:
40     class AtomicOperation
41     {
42     private:
43         std::string m_function;
44         glw::GLuint m_inputValue;
45         glw::GLuint m_paramValue;
46         glw::GLuint m_compareValue;
47         bool m_testReturnValue;
48 
49     protected:
50         virtual glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const = 0;
51 
52     public:
AtomicOperation(std::string function,glw::GLuint inputValue,glw::GLuint paramValue,glw::GLuint compareValue=0,bool testReturnValue=false)53         AtomicOperation(std::string function, glw::GLuint inputValue, glw::GLuint paramValue,
54                         glw::GLuint compareValue = 0, bool testReturnValue = false)
55             : m_function(function)
56             , m_inputValue(inputValue)
57             , m_paramValue(paramValue)
58             , m_compareValue(compareValue)
59             , m_testReturnValue(testReturnValue)
60         {
61         }
62 
~AtomicOperation()63         virtual ~AtomicOperation()
64         {
65         }
66 
getResult(unsigned int iterations) const67         glw::GLuint getResult(unsigned int iterations) const
68         {
69             glw::GLuint result = m_inputValue;
70             for (unsigned int i = 0; i < iterations; ++i)
71             {
72                 result = iterate(result, m_paramValue, m_compareValue);
73             }
74             return result;
75         }
76 
getFunction() const77         inline std::string getFunction() const
78         {
79             return m_function;
80         }
getInputValue() const81         inline glw::GLuint getInputValue() const
82         {
83             return m_inputValue;
84         }
getParamValue() const85         inline glw::GLuint getParamValue() const
86         {
87             return m_paramValue;
88         }
getCompareValue() const89         inline glw::GLuint getCompareValue() const
90         {
91             return m_compareValue;
92         }
shouldTestReturnValue() const93         inline bool shouldTestReturnValue() const
94         {
95             return m_testReturnValue;
96         }
97     };
98 
99     class AtomicOperationAdd : public AtomicOperation
100     {
101     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const102         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
103         {
104             DE_UNREF(compare);
105             return input + param;
106         }
107 
108     public:
AtomicOperationAdd(glw::GLuint inputValue,glw::GLuint paramValue)109         AtomicOperationAdd(glw::GLuint inputValue, glw::GLuint paramValue)
110             : AtomicOperation("atomicCounterAdd", inputValue, paramValue, 0U, true)
111         {
112         }
113     };
114 
115     class AtomicOperationSubtract : public AtomicOperation
116     {
117     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const118         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
119         {
120             DE_UNREF(compare);
121             return input - param;
122         }
123 
124     public:
AtomicOperationSubtract(glw::GLuint inputValue,glw::GLuint paramValue)125         AtomicOperationSubtract(glw::GLuint inputValue, glw::GLuint paramValue)
126             : AtomicOperation("atomicCounterSubtract", inputValue, paramValue, 0U, true)
127         {
128         }
129     };
130 
131     class AtomicOperationMin : public AtomicOperation
132     {
133     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const134         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
135         {
136             DE_UNREF(compare);
137             return std::min(input, param);
138         }
139 
140     public:
AtomicOperationMin(glw::GLuint inputValue,glw::GLuint paramValue)141         AtomicOperationMin(glw::GLuint inputValue, glw::GLuint paramValue)
142             : AtomicOperation("atomicCounterMin", inputValue, paramValue)
143         {
144         }
145     };
146 
147     class AtomicOperationMax : public AtomicOperation
148     {
149     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const150         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
151         {
152             DE_UNREF(compare);
153             return std::max(input, param);
154         }
155 
156     public:
AtomicOperationMax(glw::GLuint inputValue,glw::GLuint paramValue)157         AtomicOperationMax(glw::GLuint inputValue, glw::GLuint paramValue)
158             : AtomicOperation("atomicCounterMax", inputValue, paramValue)
159         {
160         }
161     };
162 
163     class AtomicOperationAnd : public AtomicOperation
164     {
165     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const166         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
167         {
168             DE_UNREF(compare);
169             return input & param;
170         }
171 
172     public:
AtomicOperationAnd(glw::GLuint inputValue,glw::GLuint paramValue)173         AtomicOperationAnd(glw::GLuint inputValue, glw::GLuint paramValue)
174             : AtomicOperation("atomicCounterAnd", inputValue, paramValue)
175         {
176         }
177     };
178 
179     class AtomicOperationOr : public AtomicOperation
180     {
181     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const182         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
183         {
184             DE_UNREF(compare);
185             return input | param;
186         }
187 
188     public:
AtomicOperationOr(glw::GLuint inputValue,glw::GLuint paramValue)189         AtomicOperationOr(glw::GLuint inputValue, glw::GLuint paramValue)
190             : AtomicOperation("atomicCounterOr", inputValue, paramValue)
191         {
192         }
193     };
194 
195     class AtomicOperationXor : public AtomicOperation
196     {
197     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const198         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
199         {
200             DE_UNREF(compare);
201             return input ^ param;
202         }
203 
204     public:
AtomicOperationXor(glw::GLuint inputValue,glw::GLuint paramValue)205         AtomicOperationXor(glw::GLuint inputValue, glw::GLuint paramValue)
206             : AtomicOperation("atomicCounterXor", inputValue, paramValue)
207         {
208         }
209     };
210 
211     class AtomicOperationExchange : public AtomicOperation
212     {
213     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const214         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
215         {
216             DE_UNREF(input);
217             DE_UNREF(compare);
218             return param;
219         }
220 
221     public:
AtomicOperationExchange(glw::GLuint inputValue,glw::GLuint paramValue)222         AtomicOperationExchange(glw::GLuint inputValue, glw::GLuint paramValue)
223             : AtomicOperation("atomicCounterExchange", inputValue, paramValue)
224         {
225         }
226     };
227 
228     class AtomicOperationCompSwap : public AtomicOperation
229     {
230     private:
iterate(glw::GLuint input,glw::GLuint param,glw::GLuint compare) const231         glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
232         {
233             return input == compare ? param : input;
234         }
235 
236     public:
AtomicOperationCompSwap(glw::GLuint inputValue,glw::GLuint paramValue,glw::GLuint compareValue)237         AtomicOperationCompSwap(glw::GLuint inputValue, glw::GLuint paramValue, glw::GLuint compareValue)
238             : AtomicOperation("atomicCounterCompSwap", inputValue, paramValue, compareValue)
239         {
240         }
241     };
242 
243     class ShaderPipeline
244     {
245     private:
246         glu::ShaderProgram *m_program;
247         glu::ShaderProgram *m_programCompute;
248         glu::ShaderType m_testedShader;
249         AtomicOperation *m_atomicOp;
250 
251         std::string m_shaders[glu::SHADERTYPE_LAST];
252 
253         void renderQuad(deqp::Context &context);
254         void executeComputeShader(deqp::Context &context);
255 
256     public:
257         ShaderPipeline(glu::ShaderType testedShader, AtomicOperation *newOp, bool contextGL46);
258         ~ShaderPipeline();
259 
260         void prepareShader(std::string &shader, const std::string &tag, const std::string &replace);
261 
262         void create(deqp::Context &context);
263         void use(deqp::Context &context);
264 
getShaderProgram() const265         inline glu::ShaderProgram *getShaderProgram() const
266         {
267             return m_program;
268         }
269 
getAtomicOperation() const270         inline AtomicOperation *getAtomicOperation() const
271         {
272             return m_atomicOp;
273         }
274 
275         void test(deqp::Context &context);
276     };
277 
278 private:
279     /* Private methods*/
280     void fillAtomicCounterBuffer(AtomicOperation *atomicOp);
281     bool checkAtomicCounterBuffer(AtomicOperation *atomicOp);
282 
283     void bindBuffers();
284     bool validateColor(tcu::Vec4 testedColor, tcu::Vec4 desiredColor);
285     bool validateScreenPixels(tcu::Vec4 desiredColor, tcu::Vec4 ignoredColor);
286 
287 protected:
288     /* Protected members */
289     glw::GLuint m_atomicCounterBuffer;
290     glw::GLuint m_atomicCounterCallsBuffer;
291     bool m_contextSupportsGL46;
292     std::vector<AtomicOperation *> m_operations;
293     std::vector<ShaderPipeline> m_shaderPipelines;
294 
295     /* Protected methods */
addOperation(AtomicOperation * newOp)296     inline void addOperation(AtomicOperation *newOp)
297     {
298         for (unsigned int i = 0; i < glu::SHADERTYPE_LAST; ++i)
299         {
300             m_shaderPipelines.push_back(ShaderPipeline((glu::ShaderType)i, newOp, m_contextSupportsGL46));
301         }
302     }
303 
304     virtual void setOperations() = 0;
305 
306 public:
307     /* Public methods */
308     ShaderAtomicCounterOpsTestBase(deqp::Context &context, const char *name, const char *description);
309 
310     void init();
311     void deinit();
312 
313     tcu::TestNode::IterateResult iterate();
314 
315     typedef std::vector<ShaderPipeline>::iterator ShaderPipelineIter;
316     typedef std::vector<AtomicOperation *>::iterator AtomicOperationIter;
317 };
318 
319 /** Test verifies new built-in addition and substraction atomic counter operations
320  **/
321 class ShaderAtomicCounterOpsAdditionSubstractionTestCase : public ShaderAtomicCounterOpsTestBase
322 {
323 private:
324     /* Private methods */
325     void setOperations();
326 
327 public:
328     /* Public methods */
329     ShaderAtomicCounterOpsAdditionSubstractionTestCase(deqp::Context &context);
330 };
331 
332 /** Test verifies new built-in minimum and maximum atomic counter operations
333  **/
334 class ShaderAtomicCounterOpsMinMaxTestCase : public ShaderAtomicCounterOpsTestBase
335 {
336 private:
337     /* Private methods */
338     void setOperations();
339 
340 public:
341     /* Public methods */
342     ShaderAtomicCounterOpsMinMaxTestCase(deqp::Context &context);
343 };
344 
345 /** Test verifies new built-in bitwise atomic counter operations
346  **/
347 class ShaderAtomicCounterOpsBitwiseTestCase : public ShaderAtomicCounterOpsTestBase
348 {
349 private:
350     /* Private methods */
351     void setOperations();
352 
353 public:
354     /* Public methods */
355     ShaderAtomicCounterOpsBitwiseTestCase(deqp::Context &context);
356 };
357 
358 /** Test verifies new built-in exchange and swap atomic counter operations
359  **/
360 class ShaderAtomicCounterOpsExchangeTestCase : public ShaderAtomicCounterOpsTestBase
361 {
362 private:
363     /* Private methods */
364     void setOperations();
365 
366 public:
367     /* Public methods */
368     ShaderAtomicCounterOpsExchangeTestCase(deqp::Context &context);
369 };
370 
371 /** Test group which encapsulates all ARB_shader_atomic_counter_ops conformance tests */
372 class ShaderAtomicCounterOps : public deqp::TestCaseGroup
373 {
374 public:
375     /* Public methods */
376     ShaderAtomicCounterOps(deqp::Context &context);
377 
378     void init();
379 
380 private:
381     ShaderAtomicCounterOps(const ShaderAtomicCounterOps &other);
382     ShaderAtomicCounterOps &operator=(const ShaderAtomicCounterOps &other);
383 };
384 
385 } // namespace gl4cts
386 
387 #endif // _GL4CSHADERATOMICCOUNTEROPSTESTS_HPP
388