Home | History | Annotate | Download | only in gl
      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:
     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 
     63 		virtual ~AtomicOperation()
     64 		{
     65 		}
     66 
     67 		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 
     77 		inline std::string getFunction() const
     78 		{
     79 			return m_function;
     80 		}
     81 		inline glw::GLuint getInputValue() const
     82 		{
     83 			return m_inputValue;
     84 		}
     85 		inline glw::GLuint getParamValue() const
     86 		{
     87 			return m_paramValue;
     88 		}
     89 		inline glw::GLuint getCompareValue() const
     90 		{
     91 			return m_compareValue;
     92 		}
     93 		inline bool shouldTestReturnValue() const
     94 		{
     95 			return m_testReturnValue;
     96 		}
     97 	};
     98 
     99 	class AtomicOperationAdd : public AtomicOperation
    100 	{
    101 	private:
    102 		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:
    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:
    118 		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:
    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:
    134 		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:
    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:
    150 		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:
    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:
    166 		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:
    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:
    182 		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:
    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:
    198 		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:
    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:
    214 		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:
    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:
    231 		glw::GLuint iterate(glw::GLuint input, glw::GLuint param, glw::GLuint compare) const
    232 		{
    233 			return input == compare ? param : input;
    234 		}
    235 
    236 	public:
    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 
    265 		inline glu::ShaderProgram* getShaderProgram() const
    266 		{
    267 			return m_program;
    268 		}
    269 
    270 		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 */
    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 } /* glcts namespace */
    386 
    387 #endif // _GL4CSHADERATOMICCOUNTEROPSTESTS_HPP
    388