1e5c31af7Sopenharmony_ci#ifndef _GLCSUBGROUPSTESTSUTILS_HPP
2e5c31af7Sopenharmony_ci#define _GLCSUBGROUPSTESTSUTILS_HPP
3e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
4e5c31af7Sopenharmony_ci * OpenGL Conformance Tests
5e5c31af7Sopenharmony_ci * ------------------------
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Copyright (c) 2017-2019 The Khronos Group Inc.
8e5c31af7Sopenharmony_ci * Copyright (c) 2017 Codeplay Software Ltd.
9e5c31af7Sopenharmony_ci * Copyright (c) 2019 NVIDIA Corporation.
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
12e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
13e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
14e5c31af7Sopenharmony_ci *
15e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
16e5c31af7Sopenharmony_ci *
17e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
18e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
19e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
21e5c31af7Sopenharmony_ci * limitations under the License.
22e5c31af7Sopenharmony_ci *
23e5c31af7Sopenharmony_ci */ /*!
24e5c31af7Sopenharmony_ci * \file
25e5c31af7Sopenharmony_ci * \brief Subgroups tests utility classes
26e5c31af7Sopenharmony_ci */ /*--------------------------------------------------------------------*/
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ci#include "deDefs.hpp"
29e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
30e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
31e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
32e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
33e5c31af7Sopenharmony_ci#include "glwDefs.hpp"
34e5c31af7Sopenharmony_ci#include "tcuDefs.hpp"
35e5c31af7Sopenharmony_ci#include "tcuTestCase.hpp"
36e5c31af7Sopenharmony_ci#include "glcTestCase.hpp"
37e5c31af7Sopenharmony_ci#include "glcSpirvUtils.hpp"
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ci#include "tcuFormatUtil.hpp"
40e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
41e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp"
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp"
44e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp"
47e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ci#include <string>
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_cinamespace glc
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_cienum ShaderType
55e5c31af7Sopenharmony_ci{
56e5c31af7Sopenharmony_ci	SHADER_TYPE_GLSL = 0,
57e5c31af7Sopenharmony_ci	SHADER_TYPE_SPIRV,
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_ci	SHADER_TYPE_LAST
60e5c31af7Sopenharmony_ci};
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_citemplate<typename Program>
63e5c31af7Sopenharmony_ciclass ProgramCollection
64e5c31af7Sopenharmony_ci{
65e5c31af7Sopenharmony_cipublic:
66e5c31af7Sopenharmony_ci								ProgramCollection	(void);
67e5c31af7Sopenharmony_ci								~ProgramCollection	(void);
68e5c31af7Sopenharmony_ci
69e5c31af7Sopenharmony_ci	void						clear				(void);
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	Program&					add					(const std::string& name);
72e5c31af7Sopenharmony_ci	void						add					(const std::string& name, de::MovePtr<Program>& program);
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci	bool						contains			(const std::string& name) const;
75e5c31af7Sopenharmony_ci	const Program&				get					(const std::string& name) const;
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_ci	class Iterator
78e5c31af7Sopenharmony_ci	{
79e5c31af7Sopenharmony_ci	private:
80e5c31af7Sopenharmony_ci		typedef typename std::map<std::string, Program*>::const_iterator	IteratorImpl;
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	public:
83e5c31af7Sopenharmony_ci		explicit			Iterator	(const IteratorImpl& i) : m_impl(i) {}
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci		Iterator&			operator++	(void)			{ ++m_impl; return *this;	}
86e5c31af7Sopenharmony_ci		const Program&		operator*	(void) const	{ return getProgram();		}
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci		const std::string&	getName		(void) const	{ return m_impl->first;		}
89e5c31af7Sopenharmony_ci		const Program&		getProgram	(void) const	{ return *m_impl->second;	}
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci		bool				operator==	(const Iterator& other) const	{ return m_impl == other.m_impl;	}
92e5c31af7Sopenharmony_ci		bool				operator!=	(const Iterator& other) const	{ return m_impl != other.m_impl;	}
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	private:
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci		IteratorImpl	m_impl;
97e5c31af7Sopenharmony_ci	};
98e5c31af7Sopenharmony_ci
99e5c31af7Sopenharmony_ci	Iterator					begin				(void) const { return Iterator(m_programs.begin());	}
100e5c31af7Sopenharmony_ci	Iterator					end					(void) const { return Iterator(m_programs.end());	}
101e5c31af7Sopenharmony_ci
102e5c31af7Sopenharmony_ci	bool						empty				(void) const { return m_programs.empty();			}
103e5c31af7Sopenharmony_ci
104e5c31af7Sopenharmony_ciprivate:
105e5c31af7Sopenharmony_ci	typedef std::map<std::string, Program*>	ProgramMap;
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_ci	ProgramMap					m_programs;
108e5c31af7Sopenharmony_ci};
109e5c31af7Sopenharmony_ci
110e5c31af7Sopenharmony_citemplate<typename Program>
111e5c31af7Sopenharmony_ciProgramCollection<Program>::ProgramCollection (void)
112e5c31af7Sopenharmony_ci{
113e5c31af7Sopenharmony_ci}
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_citemplate<typename Program>
116e5c31af7Sopenharmony_ciProgramCollection<Program>::~ProgramCollection (void)
117e5c31af7Sopenharmony_ci{
118e5c31af7Sopenharmony_ci	clear();
119e5c31af7Sopenharmony_ci}
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_citemplate<typename Program>
122e5c31af7Sopenharmony_civoid ProgramCollection<Program>::clear (void)
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	for (typename ProgramMap::const_iterator i = m_programs.begin(); i != m_programs.end(); ++i)
125e5c31af7Sopenharmony_ci		delete i->second;
126e5c31af7Sopenharmony_ci	m_programs.clear();
127e5c31af7Sopenharmony_ci}
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_citemplate<typename Program>
130e5c31af7Sopenharmony_ciProgram& ProgramCollection<Program>::add (const std::string& name)
131e5c31af7Sopenharmony_ci{
132e5c31af7Sopenharmony_ci	DE_ASSERT(!contains(name));
133e5c31af7Sopenharmony_ci	de::MovePtr<Program> prog = de::newMovePtr<Program>();
134e5c31af7Sopenharmony_ci	m_programs[name] = prog.get();
135e5c31af7Sopenharmony_ci	prog.release();
136e5c31af7Sopenharmony_ci	return *m_programs[name];
137e5c31af7Sopenharmony_ci}
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_citemplate<typename Program>
140e5c31af7Sopenharmony_civoid ProgramCollection<Program>::add (const std::string& name, de::MovePtr<Program>& program)
141e5c31af7Sopenharmony_ci{
142e5c31af7Sopenharmony_ci	DE_ASSERT(!contains(name));
143e5c31af7Sopenharmony_ci	m_programs[name] = program.get();
144e5c31af7Sopenharmony_ci	program.release();
145e5c31af7Sopenharmony_ci}
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_citemplate<typename Program>
148e5c31af7Sopenharmony_cibool ProgramCollection<Program>::contains (const std::string& name) const
149e5c31af7Sopenharmony_ci{
150e5c31af7Sopenharmony_ci	return de::contains(m_programs, name);
151e5c31af7Sopenharmony_ci}
152e5c31af7Sopenharmony_ci
153e5c31af7Sopenharmony_citemplate<typename Program>
154e5c31af7Sopenharmony_ciconst Program& ProgramCollection<Program>::get (const std::string& name) const
155e5c31af7Sopenharmony_ci{
156e5c31af7Sopenharmony_ci	DE_ASSERT(contains(name));
157e5c31af7Sopenharmony_ci	return *m_programs.find(name)->second;
158e5c31af7Sopenharmony_ci}
159e5c31af7Sopenharmony_ci
160e5c31af7Sopenharmony_cistruct GlslSource
161e5c31af7Sopenharmony_ci{
162e5c31af7Sopenharmony_ci	std::vector<std::string>	sources[glu::SHADERTYPE_LAST];
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci	GlslSource&					operator<< (const glu::ShaderSource& shaderSource)
165e5c31af7Sopenharmony_ci	{
166e5c31af7Sopenharmony_ci		sources[shaderSource.shaderType].push_back(shaderSource.source);
167e5c31af7Sopenharmony_ci		return *this;
168e5c31af7Sopenharmony_ci	}
169e5c31af7Sopenharmony_ci};
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_citypedef ProgramCollection<GlslSource>		SourceCollections;
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_ciclass Context
175e5c31af7Sopenharmony_ci{
176e5c31af7Sopenharmony_cipublic:
177e5c31af7Sopenharmony_ci	Context (deqp::Context& deqpCtx)
178e5c31af7Sopenharmony_ci		: m_deqpCtx(deqpCtx)
179e5c31af7Sopenharmony_ci		, m_sourceCollection()
180e5c31af7Sopenharmony_ci		, m_glslVersion(glu::getContextTypeGLSLVersion(m_deqpCtx.getRenderContext().getType()))
181e5c31af7Sopenharmony_ci		, m_shaderType(SHADER_TYPE_GLSL)
182e5c31af7Sopenharmony_ci		{}
183e5c31af7Sopenharmony_ci	~Context (void) {}
184e5c31af7Sopenharmony_ci	deqp::Context&			getDeqpContext		(void) const { return m_deqpCtx; }
185e5c31af7Sopenharmony_ci	SourceCollections&		getSourceCollection (void) { return m_sourceCollection; }
186e5c31af7Sopenharmony_ci	glu::GLSLVersion		getGLSLVersion		(void) { return m_glslVersion; }
187e5c31af7Sopenharmony_ci	ShaderType				getShaderType		(void) { return m_shaderType; }
188e5c31af7Sopenharmony_ci	void					setShaderType		(ShaderType type) { m_shaderType = type; }
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ciprotected:
191e5c31af7Sopenharmony_ci	deqp::Context&		m_deqpCtx;
192e5c31af7Sopenharmony_ci	SourceCollections	m_sourceCollection;
193e5c31af7Sopenharmony_ci	glu::GLSLVersion	m_glslVersion;
194e5c31af7Sopenharmony_ci	ShaderType			m_shaderType;
195e5c31af7Sopenharmony_ci};
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_cinamespace subgroups
198e5c31af7Sopenharmony_ci{
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_citemplate<typename Arg0>
201e5c31af7Sopenharmony_ciclass SubgroupFactory : public deqp::TestCase
202e5c31af7Sopenharmony_ci{
203e5c31af7Sopenharmony_cipublic:
204e5c31af7Sopenharmony_ci	//void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
205e5c31af7Sopenharmony_ci	typedef void (*InitFunction)(SourceCollections& programCollection, Arg0 arg0);
206e5c31af7Sopenharmony_ci	//void supportedCheck (Context& context, CaseDefinition caseDef)
207e5c31af7Sopenharmony_ci	typedef void (*SupportFunction)(Context& context, Arg0 arg0);
208e5c31af7Sopenharmony_ci	//tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
209e5c31af7Sopenharmony_ci	typedef tcu::TestStatus (*TestFunction)(Context& context, const Arg0 arg0);
210e5c31af7Sopenharmony_ci
211e5c31af7Sopenharmony_ci	/* Public methods */
212e5c31af7Sopenharmony_ci	SubgroupFactory(deqp::Context& context, tcu::TestNodeType type, const std::string& name, const std::string& desc,
213e5c31af7Sopenharmony_ci		SupportFunction suppFunc, InitFunction initFunc, TestFunction testFunc, Arg0 arg0)
214e5c31af7Sopenharmony_ci		: TestCase(context, type, name.c_str(), desc.c_str())
215e5c31af7Sopenharmony_ci		, m_supportedFunc(suppFunc)
216e5c31af7Sopenharmony_ci		, m_initFunc(initFunc)
217e5c31af7Sopenharmony_ci		, m_testFunc(testFunc)
218e5c31af7Sopenharmony_ci		, m_arg0(arg0)
219e5c31af7Sopenharmony_ci		, m_glcContext(m_context)
220e5c31af7Sopenharmony_ci	{}
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci	void init()
223e5c31af7Sopenharmony_ci	{
224e5c31af7Sopenharmony_ci		m_supportedFunc(m_glcContext, m_arg0);
225e5c31af7Sopenharmony_ci
226e5c31af7Sopenharmony_ci		m_initFunc(m_glcContext.getSourceCollection(), m_arg0);
227e5c31af7Sopenharmony_ci	}
228e5c31af7Sopenharmony_ci
229e5c31af7Sopenharmony_ci	void deinit()
230e5c31af7Sopenharmony_ci	{
231e5c31af7Sopenharmony_ci		// nothing to do
232e5c31af7Sopenharmony_ci	}
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ci	tcu::TestNode::IterateResult iterate()
235e5c31af7Sopenharmony_ci	{
236e5c31af7Sopenharmony_ci		DE_ASSERT(m_testFunc);
237e5c31af7Sopenharmony_ci		tcu::TestLog& log = m_testCtx.getLog();
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ci		try {
240e5c31af7Sopenharmony_ci			// do SPIRV version of tests if supported
241e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << "SPIRV pass beginning..." << tcu::TestLog::EndMessage;
242e5c31af7Sopenharmony_ci			spirvUtils::checkGlSpirvSupported(m_glcContext.getDeqpContext());
243e5c31af7Sopenharmony_ci
244e5c31af7Sopenharmony_ci			m_glcContext.setShaderType(SHADER_TYPE_SPIRV);
245e5c31af7Sopenharmony_ci
246e5c31af7Sopenharmony_ci			const tcu::TestStatus result = m_testFunc(m_glcContext, m_arg0);
247e5c31af7Sopenharmony_ci			if (result.isComplete())
248e5c31af7Sopenharmony_ci			{
249e5c31af7Sopenharmony_ci				DE_ASSERT(m_testCtx.getTestResult() == QP_TEST_RESULT_LAST);
250e5c31af7Sopenharmony_ci				if (result.getCode() == QP_TEST_RESULT_PASS)
251e5c31af7Sopenharmony_ci				{
252e5c31af7Sopenharmony_ci					log << tcu::TestLog::Message << "SPIRV pass completed successfully ("
253e5c31af7Sopenharmony_ci						<< result.getDescription() << ")." << tcu::TestLog::EndMessage;
254e5c31af7Sopenharmony_ci				} else {
255e5c31af7Sopenharmony_ci					// test failed - log result and stop
256e5c31af7Sopenharmony_ci					m_testCtx.setTestResult(result.getCode(), result.getDescription().c_str());
257e5c31af7Sopenharmony_ci					return tcu::TestNode::STOP;
258e5c31af7Sopenharmony_ci				}
259e5c31af7Sopenharmony_ci			}
260e5c31af7Sopenharmony_ci		} catch(tcu::NotSupportedError& e)
261e5c31af7Sopenharmony_ci		{
262e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << "SPIRV pass skipped ("
263e5c31af7Sopenharmony_ci						<< e.getMessage() << ")." << tcu::TestLog::EndMessage;
264e5c31af7Sopenharmony_ci		}
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci		// do GLSL version of the tests
267e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << "GLSL pass beginning..." << tcu::TestLog::EndMessage;
268e5c31af7Sopenharmony_ci		m_glcContext.setShaderType(SHADER_TYPE_GLSL);
269e5c31af7Sopenharmony_ci		const tcu::TestStatus result = m_testFunc(m_glcContext, m_arg0);
270e5c31af7Sopenharmony_ci
271e5c31af7Sopenharmony_ci		if (result.isComplete())
272e5c31af7Sopenharmony_ci		{
273e5c31af7Sopenharmony_ci			DE_ASSERT(m_testCtx.getTestResult() == QP_TEST_RESULT_LAST);
274e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << "GLSL pass completed successfully ("
275e5c31af7Sopenharmony_ci				<< result.getDescription() << ")." << tcu::TestLog::EndMessage;
276e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(result.getCode(), result.getDescription().c_str());
277e5c31af7Sopenharmony_ci			return tcu::TestNode::STOP;
278e5c31af7Sopenharmony_ci		}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci		return tcu::TestNode::CONTINUE;
281e5c31af7Sopenharmony_ci	}
282e5c31af7Sopenharmony_ci
283e5c31af7Sopenharmony_ci	static void addFunctionCaseWithPrograms (deqp::TestCaseGroup*				group,
284e5c31af7Sopenharmony_ci								  const std::string&							name,
285e5c31af7Sopenharmony_ci								  const std::string&							desc,
286e5c31af7Sopenharmony_ci								  SupportFunction								suppFunc,
287e5c31af7Sopenharmony_ci								  InitFunction									initFunc,
288e5c31af7Sopenharmony_ci								  TestFunction									testFunc,
289e5c31af7Sopenharmony_ci								  Arg0											arg0)
290e5c31af7Sopenharmony_ci	{
291e5c31af7Sopenharmony_ci		group->addChild(new SubgroupFactory(group->getContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, suppFunc, initFunc, testFunc, arg0));
292e5c31af7Sopenharmony_ci	}
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ciprivate:
295e5c31af7Sopenharmony_ci	SupportFunction		m_supportedFunc;
296e5c31af7Sopenharmony_ci	InitFunction		m_initFunc;
297e5c31af7Sopenharmony_ci	TestFunction		m_testFunc;
298e5c31af7Sopenharmony_ci	Arg0				m_arg0;
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_ci	Context				m_glcContext;
301e5c31af7Sopenharmony_ci};
302e5c31af7Sopenharmony_ci
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_citypedef enum ShaderStageFlags
305e5c31af7Sopenharmony_ci{
306e5c31af7Sopenharmony_ci	SHADER_STAGE_VERTEX_BIT = GL_VERTEX_SHADER_BIT,
307e5c31af7Sopenharmony_ci	SHADER_STAGE_FRAGMENT_BIT = GL_FRAGMENT_SHADER_BIT,
308e5c31af7Sopenharmony_ci	SHADER_STAGE_GEOMETRY_BIT = GL_GEOMETRY_SHADER_BIT,
309e5c31af7Sopenharmony_ci	SHADER_STAGE_TESS_CONTROL_BIT = GL_TESS_CONTROL_SHADER_BIT,
310e5c31af7Sopenharmony_ci	SHADER_STAGE_TESS_EVALUATION_BIT = GL_TESS_EVALUATION_SHADER_BIT,
311e5c31af7Sopenharmony_ci	SHADER_STAGE_COMPUTE_BIT = GL_COMPUTE_SHADER_BIT,
312e5c31af7Sopenharmony_ci	SHADER_STAGE_ALL_GRAPHICS = (SHADER_STAGE_VERTEX_BIT | SHADER_STAGE_FRAGMENT_BIT | SHADER_STAGE_GEOMETRY_BIT |
313e5c31af7Sopenharmony_ci								 SHADER_STAGE_TESS_CONTROL_BIT | SHADER_STAGE_TESS_EVALUATION_BIT ),
314e5c31af7Sopenharmony_ci	SHADER_STAGE_ALL_VALID = (SHADER_STAGE_ALL_GRAPHICS | SHADER_STAGE_COMPUTE_BIT),
315e5c31af7Sopenharmony_ci} ShaderStageFlags;
316e5c31af7Sopenharmony_ci
317e5c31af7Sopenharmony_citypedef enum SubgroupFeatureFlags
318e5c31af7Sopenharmony_ci{
319e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_BASIC_BIT = GL_SUBGROUP_FEATURE_BASIC_BIT_KHR,
320e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_VOTE_BIT = GL_SUBGROUP_FEATURE_VOTE_BIT_KHR,
321e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_ARITHMETIC_BIT = GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR,
322e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_BALLOT_BIT = GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR,
323e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_SHUFFLE_BIT = GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR,
324e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR,
325e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_CLUSTERED_BIT = GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR,
326e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_QUAD_BIT = GL_SUBGROUP_FEATURE_QUAD_BIT_KHR,
327e5c31af7Sopenharmony_ci    SUBGROUP_FEATURE_PARTITIONED_BIT_NV = GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV,
328e5c31af7Sopenharmony_ci	SUBGROUP_FEATURE_ALL_VALID = (SUBGROUP_FEATURE_BASIC_BIT | SUBGROUP_FEATURE_VOTE_BIT | SUBGROUP_FEATURE_ARITHMETIC_BIT |
329e5c31af7Sopenharmony_ci								  SUBGROUP_FEATURE_BALLOT_BIT | SUBGROUP_FEATURE_SHUFFLE_BIT | SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
330e5c31af7Sopenharmony_ci								  SUBGROUP_FEATURE_CLUSTERED_BIT | SUBGROUP_FEATURE_QUAD_BIT | SUBGROUP_FEATURE_PARTITIONED_BIT_NV),
331e5c31af7Sopenharmony_ci} SubgroupFeatureFlags;
332e5c31af7Sopenharmony_ci
333e5c31af7Sopenharmony_citypedef enum Format
334e5c31af7Sopenharmony_ci{
335e5c31af7Sopenharmony_ci	FORMAT_UNDEFINED = 0,
336e5c31af7Sopenharmony_ci	FORMAT_R32_SINT = GL_R32I,
337e5c31af7Sopenharmony_ci	FORMAT_R32_UINT = GL_R32UI,
338e5c31af7Sopenharmony_ci	FORMAT_R32G32_SINT = GL_RG32I,
339e5c31af7Sopenharmony_ci	FORMAT_R32G32_UINT = GL_RG32UI,
340e5c31af7Sopenharmony_ci	FORMAT_R32G32B32_SINT = GL_RGB32I,
341e5c31af7Sopenharmony_ci	FORMAT_R32G32B32_UINT = GL_RGB32UI,
342e5c31af7Sopenharmony_ci	FORMAT_R32G32B32A32_SINT = GL_RGBA32I,
343e5c31af7Sopenharmony_ci	FORMAT_R32G32B32A32_UINT = GL_RGBA32UI,
344e5c31af7Sopenharmony_ci	FORMAT_R32_SFLOAT = GL_R32F,
345e5c31af7Sopenharmony_ci	FORMAT_R32G32_SFLOAT = GL_RG32F,
346e5c31af7Sopenharmony_ci	FORMAT_R32G32B32_SFLOAT = GL_RGB32F,
347e5c31af7Sopenharmony_ci	FORMAT_R32G32B32A32_SFLOAT = GL_RGBA32F,
348e5c31af7Sopenharmony_ci	FORMAT_R64_SFLOAT = 0x6000,
349e5c31af7Sopenharmony_ci	FORMAT_R64G64_SFLOAT,
350e5c31af7Sopenharmony_ci	FORMAT_R64G64B64_SFLOAT,
351e5c31af7Sopenharmony_ci	FORMAT_R64G64B64A64_SFLOAT,
352e5c31af7Sopenharmony_ci	FORMAT_R32_BOOL = 0x6100,
353e5c31af7Sopenharmony_ci	FORMAT_R32G32_BOOL,
354e5c31af7Sopenharmony_ci	FORMAT_R32G32B32_BOOL,
355e5c31af7Sopenharmony_ci	FORMAT_R32G32B32A32_BOOL,
356e5c31af7Sopenharmony_ci} Format;
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_citypedef enum DescriptorType
359e5c31af7Sopenharmony_ci{
360e5c31af7Sopenharmony_ci	DESCRIPTOR_TYPE_UNIFORM_BUFFER = GL_UNIFORM_BUFFER,
361e5c31af7Sopenharmony_ci	DESCRIPTOR_TYPE_STORAGE_BUFFER = GL_SHADER_STORAGE_BUFFER,
362e5c31af7Sopenharmony_ci	DESCRIPTOR_TYPE_STORAGE_IMAGE  = GL_TEXTURE_2D,
363e5c31af7Sopenharmony_ci} DescriptorType;
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci// A struct to represent input data to a shader
366e5c31af7Sopenharmony_cistruct SSBOData
367e5c31af7Sopenharmony_ci{
368e5c31af7Sopenharmony_ci	SSBOData() :
369e5c31af7Sopenharmony_ci		initializeType	(InitializeNone),
370e5c31af7Sopenharmony_ci		layout			(LayoutStd140),
371e5c31af7Sopenharmony_ci		format			(FORMAT_UNDEFINED),
372e5c31af7Sopenharmony_ci		numElements		(0),
373e5c31af7Sopenharmony_ci		isImage			(false),
374e5c31af7Sopenharmony_ci		binding			(0u),
375e5c31af7Sopenharmony_ci		stages			((ShaderStageFlags)0u)
376e5c31af7Sopenharmony_ci	{}
377e5c31af7Sopenharmony_ci
378e5c31af7Sopenharmony_ci	enum InputDataInitializeType
379e5c31af7Sopenharmony_ci	{
380e5c31af7Sopenharmony_ci		InitializeNone = 0,
381e5c31af7Sopenharmony_ci		InitializeNonZero,
382e5c31af7Sopenharmony_ci		InitializeZero,
383e5c31af7Sopenharmony_ci	} initializeType;
384e5c31af7Sopenharmony_ci
385e5c31af7Sopenharmony_ci	enum InputDataLayoutType
386e5c31af7Sopenharmony_ci	{
387e5c31af7Sopenharmony_ci		LayoutStd140 = 0,
388e5c31af7Sopenharmony_ci		LayoutStd430,
389e5c31af7Sopenharmony_ci		LayoutPacked,
390e5c31af7Sopenharmony_ci	} layout;
391e5c31af7Sopenharmony_ci
392e5c31af7Sopenharmony_ci	Format						format;
393e5c31af7Sopenharmony_ci	deUint64					numElements;
394e5c31af7Sopenharmony_ci	bool						isImage;
395e5c31af7Sopenharmony_ci	deUint32					binding;
396e5c31af7Sopenharmony_ci	ShaderStageFlags			stages;
397e5c31af7Sopenharmony_ci};
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_cistd::string getSharedMemoryBallotHelper();
400e5c31af7Sopenharmony_ci
401e5c31af7Sopenharmony_cideUint32 getSubgroupSize(Context& context);
402e5c31af7Sopenharmony_ci
403e5c31af7Sopenharmony_cideUint32 maxSupportedSubgroupSize();
404e5c31af7Sopenharmony_ci
405e5c31af7Sopenharmony_cistd::string getShaderStageName(ShaderStageFlags stage);
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_cistd::string getSubgroupFeatureName(SubgroupFeatureFlags bit);
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_civoid addNoSubgroupShader (SourceCollections& programCollection);
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_cistd::string getVertShaderForStage(ShaderStageFlags stage);
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_cibool isSubgroupSupported(Context& context);
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_cibool areSubgroupOperationsSupportedForStage(
416e5c31af7Sopenharmony_ci	Context& context, ShaderStageFlags stage);
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_cibool areSubgroupOperationsRequiredForStage(ShaderStageFlags stage);
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_cibool isSubgroupFeatureSupportedForDevice(Context& context, SubgroupFeatureFlags bit);
421e5c31af7Sopenharmony_ci
422e5c31af7Sopenharmony_cibool isFragmentSSBOSupportedForDevice(Context& context);
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_cibool isVertexSSBOSupportedForDevice(Context& context);
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_cibool isImageSupportedForStageOnDevice(Context& context, const ShaderStageFlags stage);
427e5c31af7Sopenharmony_ci
428e5c31af7Sopenharmony_cibool isDoubleSupportedForDevice(Context& context);
429e5c31af7Sopenharmony_ci
430e5c31af7Sopenharmony_cibool isDoubleFormat(Format format);
431e5c31af7Sopenharmony_ci
432e5c31af7Sopenharmony_cistd::string getFormatNameForGLSL(Format format);
433e5c31af7Sopenharmony_ci
434e5c31af7Sopenharmony_civoid addGeometryShadersFromTemplate (const std::string& glslTemplate, SourceCollections& collection);
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_civoid setVertexShaderFrameBuffer (SourceCollections& programCollection);
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_civoid setFragmentShaderFrameBuffer (SourceCollections& programCollection);
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_civoid setFragmentShaderFrameBuffer (SourceCollections& programCollection);
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_civoid setTesCtrlShaderFrameBuffer (SourceCollections& programCollection);
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_civoid setTesEvalShaderFrameBuffer (SourceCollections& programCollection);
445e5c31af7Sopenharmony_ci
446e5c31af7Sopenharmony_cibool check(std::vector<const void*> datas,
447e5c31af7Sopenharmony_ci	deUint32 width, deUint32 ref);
448e5c31af7Sopenharmony_ci
449e5c31af7Sopenharmony_cibool checkCompute(std::vector<const void*> datas,
450e5c31af7Sopenharmony_ci	const deUint32 numWorkgroups[3], const deUint32 localSize[3],
451e5c31af7Sopenharmony_ci	deUint32 ref);
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_citcu::TestStatus makeTessellationEvaluationFrameBufferTest(Context& context, Format format,
454e5c31af7Sopenharmony_ci	SSBOData* extraData, deUint32 extraDataCount,
455e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize),
456e5c31af7Sopenharmony_ci	const ShaderStageFlags shaderStage = SHADER_STAGE_ALL_GRAPHICS);
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_citcu::TestStatus makeGeometryFrameBufferTest(Context& context, Format format, SSBOData* extraData,
459e5c31af7Sopenharmony_ci	deUint32 extraDataCount,
460e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize));
461e5c31af7Sopenharmony_ci
462e5c31af7Sopenharmony_citcu::TestStatus allStages(Context& context, Format format,
463e5c31af7Sopenharmony_ci	SSBOData* extraData, deUint32 extraDataCount,
464e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize),
465e5c31af7Sopenharmony_ci	const ShaderStageFlags shaderStage);
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_citcu::TestStatus makeVertexFrameBufferTest(Context& context, Format format,
468e5c31af7Sopenharmony_ci	SSBOData* extraData, deUint32 extraDataCount,
469e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas, deUint32 width, deUint32 subgroupSize));
470e5c31af7Sopenharmony_ci
471e5c31af7Sopenharmony_citcu::TestStatus makeFragmentFrameBufferTest(Context& context, Format format,
472e5c31af7Sopenharmony_ci	SSBOData* extraData, deUint32 extraDataCount,
473e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas, deUint32 width,
474e5c31af7Sopenharmony_ci									 deUint32 height, deUint32 subgroupSize));
475e5c31af7Sopenharmony_ci
476e5c31af7Sopenharmony_citcu::TestStatus makeComputeTest(
477e5c31af7Sopenharmony_ci	Context& context, Format format, SSBOData* inputs,
478e5c31af7Sopenharmony_ci	deUint32 inputsCount,
479e5c31af7Sopenharmony_ci	bool (*checkResult)(std::vector<const void*> datas,
480e5c31af7Sopenharmony_ci		const deUint32 numWorkgroups[3], const deUint32 localSize[3],
481e5c31af7Sopenharmony_ci		deUint32 subgroupSize));
482e5c31af7Sopenharmony_ci} // subgroups
483e5c31af7Sopenharmony_ci} // glc
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_ci#endif // _GLCSUBGROUPSTESTSUTILS_HPP
486