• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _GLUSHADERPROGRAM_HPP
2 #define _GLUSHADERPROGRAM_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL ES Utilities
5  * ------------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
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 Shader and Program helpers.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "gluDefs.hpp"
27 #include "gluShaderUtil.hpp"
28 #include "glwEnums.hpp"
29 #include "qpTestLog.h"
30 
31 #include <string>
32 #include <vector>
33 
34 namespace tcu
35 {
36 class TestLog;
37 }
38 
39 namespace glu
40 {
41 
42 class RenderContext;
43 
44 typedef std::vector<deUint32> ShaderBinaryDataType;
45 
46 /*--------------------------------------------------------------------*//*!
47  * \brief Shader information (compile status, log, etc.).
48  *//*--------------------------------------------------------------------*/
49 struct ShaderInfo
50 {
51 	ShaderType				type;			//!< Shader type.
52 	std::string				source;			//!< Shader source.
53 	std::string				infoLog;		//!< Compile info log.
54 	bool					compileOk;		//!< Did compilation succeed?
55 	deUint64				compileTimeUs;	//!< Compile time in microseconds (us).
56 
ShaderInfoglu::ShaderInfo57 	ShaderInfo (void) : type(SHADERTYPE_LAST), compileOk(false), compileTimeUs(0) {}
58 };
59 
60 /*--------------------------------------------------------------------*//*!
61  * \brief Program information (link status, log).
62  *//*--------------------------------------------------------------------*/
63 struct ProgramInfo
64 {
65 	std::string				infoLog;		//!< Link info log.
66 	bool					linkOk;			//!< Did link succeed?
67 	deUint64				linkTimeUs;		//!< Link time in microseconds (us).
68 
ProgramInfoglu::ProgramInfo69 	ProgramInfo (void) : linkOk(false), linkTimeUs(0) {}
70 };
71 
72 /*--------------------------------------------------------------------*//*!
73  * \brief Combined shader compilation and program linking info.
74  *//*--------------------------------------------------------------------*/
75 struct ShaderProgramInfo
76 {
77 	glu::ProgramInfo				program;
78 	std::vector<glu::ShaderInfo>	shaders;
79 };
80 
81 /*--------------------------------------------------------------------*//*!
82  * \brief Shader object.
83  *//*--------------------------------------------------------------------*/
84 class Shader
85 {
86 public:
87 							Shader				(const glw::Functions& gl, ShaderType shaderType);
88 							Shader				(const RenderContext& renderCtx, ShaderType shaderType);
89 							~Shader				(void);
90 
91 	void					setSources			(int numSourceStrings, const char* const* sourceStrings, const int* lengths);
92 	void					compile				(void);
93 	void					specialize			(const char* entryPoint, glw::GLuint numSpecializationConstants,
94 												 const glw::GLuint* constantIndex, const glw::GLuint* constantValue);
95 
getShader(void) const96 	deUint32				getShader			(void) const { return m_shader;				}
getInfo(void) const97 	const ShaderInfo&		getInfo				(void) const { return m_info;				}
98 
getType(void) const99 	glu::ShaderType			getType				(void) const { return getInfo().type;		}
getCompileStatus(void) const100 	bool					getCompileStatus	(void) const { return getInfo().compileOk;	}
getSource(void) const101 	const std::string&		getSource			(void) const { return getInfo().source;		}
getInfoLog(void) const102 	const std::string&		getInfoLog			(void) const { return getInfo().infoLog;	}
103 
operator *(void) const104 	deUint32				operator*			(void) const { return getShader();			}
105 
106 private:
107 							Shader				(const Shader& other);
108 	Shader&					operator=			(const Shader& other);
109 
110 	const glw::Functions&	m_gl;
111 	deUint32				m_shader;	//!< Shader handle.
112 	ShaderInfo				m_info;		//!< Client-side clone of state for debug / perf reasons.
113 };
114 
115 /*--------------------------------------------------------------------*//*!
116  * \brief Program object.
117  *//*--------------------------------------------------------------------*/
118 class Program
119 {
120 public:
121 							Program						(const glw::Functions& gl);
122 							Program						(const RenderContext& renderCtx);
123 							Program						(const RenderContext& renderCtx, deUint32 program);
124 							~Program					(void);
125 
126 	void					attachShader				(deUint32 shader);
127 	void					detachShader				(deUint32 shader);
128 
129 	void					bindAttribLocation			(deUint32 location, const char* name);
130 	void					transformFeedbackVaryings	(int count, const char* const* varyings, deUint32 bufferMode);
131 
132 	void					link						(void);
133 
getProgram(void) const134 	deUint32				getProgram					(void) const { return m_program;			}
getInfo(void) const135 	const ProgramInfo&		getInfo						(void) const { return m_info;				}
136 
getLinkStatus(void) const137 	bool					getLinkStatus				(void) const { return getInfo().linkOk;		}
getInfoLog(void) const138 	const std::string&		getInfoLog					(void) const { return getInfo().infoLog;	}
139 
140 	bool					isSeparable					(void) const;
141 	void					setSeparable				(bool separable);
142 
143 	int						getUniformLocation			(const std::string& name);
144 
operator *(void) const145 	deUint32				operator*					(void) const { return getProgram();			}
146 
147 private:
148 							Program						(const Program& other);
149 	Program&				operator=					(const Program& other);
150 
151 	const glw::Functions&	m_gl;
152 	deUint32				m_program;
153 	ProgramInfo				m_info;
154 };
155 
156 
157 /*--------------------------------------------------------------------*//*!
158  * \brief Program pipeline object.
159  *//*--------------------------------------------------------------------*/
160 class ProgramPipeline
161 {
162 public:
163 							ProgramPipeline				(const RenderContext& renderCtx);
164 							ProgramPipeline				(const glw::Functions& gl);
165 							~ProgramPipeline			(void);
166 
getPipeline(void) const167 	deUint32				getPipeline					(void) const { return m_pipeline; }
168 	void					useProgramStages			(deUint32 stages, deUint32 program);
169 	void					activeShaderProgram			(deUint32 program);
170 	bool					isValid						(void);
171 
172 private:
173 							ProgramPipeline				(const ProgramPipeline& other);
174 	ProgramPipeline&		operator=					(const ProgramPipeline& other);
175 
176 	const glw::Functions&	m_gl;
177 	deUint32				m_pipeline;
178 };
179 
180 struct ProgramSources;
181 struct ProgramBinaries;
182 
183 /*--------------------------------------------------------------------*//*!
184  * \brief Shader program manager.
185  *
186  * ShaderProgram manages both Shader and Program objects, and provides
187  * convenient API for constructing such programs.
188  *//*--------------------------------------------------------------------*/
189 class ShaderProgram
190 {
191 public:
192 							ShaderProgram				(const glw::Functions& gl, const ProgramSources& sources);
193 							ShaderProgram				(const glw::Functions& gl, const ProgramBinaries& binaries);
194 							ShaderProgram				(const RenderContext& renderCtx, const ProgramSources& sources);
195 							ShaderProgram				(const RenderContext& renderCtx, const ProgramBinaries& binaries);
196 							~ShaderProgram				(void);
197 
isOk(void) const198 	bool					isOk						(void) const											{ return m_program.getLinkStatus();						}
getProgram(void) const199 	deUint32				getProgram					(void) const											{ return m_program.getProgram();						}
200 
hasShader(glu::ShaderType shaderType) const201 	bool					hasShader					(glu::ShaderType shaderType) const						{ return !m_shaders[shaderType].empty();				}
getShader(glu::ShaderType shaderType,int shaderNdx=0) const202 	Shader*					getShader					(glu::ShaderType shaderType, int shaderNdx = 0) const	{ return m_shaders[shaderType][shaderNdx];	}
getNumShaders(glu::ShaderType shaderType) const203 	int						getNumShaders				(glu::ShaderType shaderType) const						{ return (int)m_shaders[shaderType].size();				}
getShaderInfo(glu::ShaderType shaderType,int shaderNdx=0) const204 	const ShaderInfo&		getShaderInfo				(glu::ShaderType shaderType, int shaderNdx = 0) const	{ return m_shaders[shaderType][shaderNdx]->getInfo();	}
getProgramInfo(void) const205 	const ProgramInfo&		getProgramInfo				(void) const											{ return m_program.getInfo();							}
206 
207 private:
208 							ShaderProgram				(const ShaderProgram& other);
209 	ShaderProgram&			operator=					(const ShaderProgram& other);
210 	void					init						(const glw::Functions& gl, const ProgramSources& sources);
211 	void					init						(const glw::Functions& gl, const ProgramBinaries& binaries);
212 	void					setBinary					(const glw::Functions& gl, std::vector<Shader*>& shaders, glw::GLenum binaryFormat, const void* binaryData, const int length);
213 
214 	std::vector<Shader*>	m_shaders[SHADERTYPE_LAST];
215 	Program					m_program;
216 };
217 
218 // Utilities.
219 
220 deUint32		getGLShaderType		(ShaderType shaderType);
221 deUint32		getGLShaderTypeBit	(ShaderType shaderType);
222 qpShaderType	getLogShaderType	(ShaderType shaderType);
223 
224 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderInfo& shaderInfo);
225 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo);
226 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ProgramSources& sources);
227 tcu::TestLog&	operator<<			(tcu::TestLog& log, const Shader& shader);
228 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgram& program);
229 
230 // ProgramSources utilities and implementation.
231 
232 struct AttribLocationBinding
233 {
234 	std::string			name;
235 	deUint32			location;
236 
AttribLocationBindingglu::AttribLocationBinding237 	AttribLocationBinding (void) : location(0) {}
AttribLocationBindingglu::AttribLocationBinding238 	AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
239 };
240 
241 struct TransformFeedbackMode
242 {
243 	deUint32			mode;
244 
TransformFeedbackModeglu::TransformFeedbackMode245 	TransformFeedbackMode (void) : mode(0) {}
TransformFeedbackModeglu::TransformFeedbackMode246 	TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
247 };
248 
249 struct TransformFeedbackVarying
250 {
251 	std::string			name;
252 
TransformFeedbackVaryingglu::TransformFeedbackVarying253 	explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
254 };
255 
256 struct ProgramSeparable
257 {
258 	bool				separable;
ProgramSeparableglu::ProgramSeparable259 	explicit ProgramSeparable (bool separable_) : separable(separable_) {}
260 };
261 
262 template<typename Iterator>
263 struct TransformFeedbackVaryings
264 {
265 	Iterator			begin;
266 	Iterator			end;
267 
TransformFeedbackVaryingsglu::TransformFeedbackVaryings268 	TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
269 };
270 
271 struct ShaderSource
272 {
273 	ShaderType			shaderType;
274 	std::string			source;
275 
ShaderSourceglu::ShaderSource276 	ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
ShaderSourceglu::ShaderSource277 	ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
278 };
279 
280 struct VertexSource : public ShaderSource
281 {
VertexSourceglu::VertexSource282 	VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
283 };
284 
285 struct FragmentSource : public ShaderSource
286 {
FragmentSourceglu::FragmentSource287 	FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
288 };
289 
290 struct GeometrySource : public ShaderSource
291 {
GeometrySourceglu::GeometrySource292 	GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
293 };
294 
295 struct ComputeSource : public ShaderSource
296 {
ComputeSourceglu::ComputeSource297 	ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
298 };
299 
300 struct TessellationControlSource : public ShaderSource
301 {
TessellationControlSourceglu::TessellationControlSource302 	TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
303 };
304 
305 struct TessellationEvaluationSource : public ShaderSource
306 {
TessellationEvaluationSourceglu::TessellationEvaluationSource307 	TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
308 };
309 
310 struct RaygenSource : public ShaderSource
311 {
RaygenSourceglu::RaygenSource312 	RaygenSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_RAYGEN, source_) {}
313 };
314 
315 struct AnyHitSource : public ShaderSource
316 {
AnyHitSourceglu::AnyHitSource317 	AnyHitSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_ANY_HIT, source_) {}
318 };
319 
320 struct ClosestHitSource : public ShaderSource
321 {
ClosestHitSourceglu::ClosestHitSource322 	ClosestHitSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_CLOSEST_HIT, source_) {}
323 };
324 
325 struct MissSource : public ShaderSource
326 {
MissSourceglu::MissSource327 	MissSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_MISS, source_) {}
328 };
329 
330 struct IntersectionSource : public ShaderSource
331 {
IntersectionSourceglu::IntersectionSource332 	IntersectionSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_INTERSECTION, source_) {}
333 };
334 
335 struct CallableSource : public ShaderSource
336 {
CallableSourceglu::CallableSource337 	CallableSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_CALLABLE, source_) {}
338 };
339 
340 struct TaskSource : public ShaderSource
341 {
TaskSourceglu::TaskSource342 	TaskSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_TASK, source_) {}
343 };
344 
345 struct MeshSource : public ShaderSource
346 {
MeshSourceglu::MeshSource347 	MeshSource(const std::string& source_) : ShaderSource(glu::SHADERTYPE_MESH, source_) {}
348 };
349 
350 struct ProgramSources
351 {
352 	std::vector<std::string>			sources[SHADERTYPE_LAST];
353 	std::vector<AttribLocationBinding>	attribLocationBindings;
354 
355 	deUint32							transformFeedbackBufferMode;		//!< TF buffer mode, or GL_NONE.
356 	std::vector<std::string>			transformFeedbackVaryings;
357 	bool								separable;
358 
ProgramSourcesglu::ProgramSources359 	ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
360 
operator <<glu::ProgramSources361 	ProgramSources&						operator<<			(const AttribLocationBinding& binding)		{ attribLocationBindings.push_back(binding);						return *this;	}
operator <<glu::ProgramSources362 	ProgramSources&						operator<<			(const TransformFeedbackMode& mode)			{ transformFeedbackBufferMode = mode.mode;							return *this;	}
operator <<glu::ProgramSources363 	ProgramSources&						operator<<			(const TransformFeedbackVarying& varying)	{ transformFeedbackVaryings.push_back(varying.name);				return *this;	}
operator <<glu::ProgramSources364 	ProgramSources&						operator<<			(const ShaderSource& shaderSource)			{ sources[shaderSource.shaderType].push_back(shaderSource.source);	return *this;	}
operator <<glu::ProgramSources365 	ProgramSources&						operator<<			(const ProgramSeparable& progSeparable)		{ separable = progSeparable.separable;								return *this;	}
366 
367 	template<typename Iterator>
368 	ProgramSources&						operator<<			(const TransformFeedbackVaryings<Iterator>& varyings);
369 };
370 
371 struct SpecializationData
372 {
373 	deUint32 index;
374 	deUint32 value;
375 
SpecializationDataglu::SpecializationData376 	SpecializationData (void) : index(0), value(0) {}
SpecializationDataglu::SpecializationData377 	SpecializationData (const deUint32 index_, const deUint32 value_) : index(index_), value(value_) {}
378 };
379 
380 struct ShaderBinary
381 {
382 	ShaderBinaryDataType		binary;
383 	std::vector<ShaderType>		shaderTypes;
384 	std::vector<std::string>	shaderEntryPoints;
385 	std::vector<deUint32>		specializationIndices;
386 	std::vector<deUint32>		specializationValues;
387 
ShaderBinaryglu::ShaderBinary388 	ShaderBinary (void) {}
ShaderBinaryglu::ShaderBinary389 	ShaderBinary (const ShaderBinaryDataType binary_) : binary(binary_)
390 	{
391 		DE_ASSERT(!binary_.empty());
392 	}
ShaderBinaryglu::ShaderBinary393 	ShaderBinary (const ShaderBinaryDataType binary_, glu::ShaderType shaderType_) : binary(binary_)
394 	{
395 		DE_ASSERT(!binary_.empty());
396 		shaderTypes.push_back(shaderType_);
397 		shaderEntryPoints.push_back("main");
398 	}
399 
operator <<glu::ShaderBinary400 	ShaderBinary& operator<< (const ShaderType& shaderType)
401 	{
402 		shaderTypes.push_back(shaderType);
403 		return *this;
404 	}
405 
operator <<glu::ShaderBinary406 	ShaderBinary& operator<< (const std::string& entryPoint)
407 	{
408 		shaderEntryPoints.push_back(entryPoint);
409 		return *this;
410 	}
411 
operator <<glu::ShaderBinary412 	ShaderBinary& operator<< (const SpecializationData& specData)
413 	{
414 		specializationIndices.push_back(specData.index);
415 		specializationValues.push_back(specData.value);
416 		return *this;
417 	}
418 };
419 
420 struct VertexBinary : public ShaderBinary
421 {
VertexBinaryglu::VertexBinary422 	VertexBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_VERTEX) {}
423 };
424 
425 struct FragmentBinary : public ShaderBinary
426 {
FragmentBinaryglu::FragmentBinary427 	FragmentBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_FRAGMENT) {}
428 };
429 
430 struct GeometryBinary : public ShaderBinary
431 {
GeometryBinaryglu::GeometryBinary432 	GeometryBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_GEOMETRY) {}
433 };
434 
435 struct ComputeBinary : public ShaderBinary
436 {
ComputeBinaryglu::ComputeBinary437 	ComputeBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_COMPUTE) {}
438 };
439 
440 struct TessellationControlBinary : public ShaderBinary
441 {
TessellationControlBinaryglu::TessellationControlBinary442 	TessellationControlBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_CONTROL) {}
443 };
444 
445 struct TessellationEvaluationBinary : public ShaderBinary
446 {
TessellationEvaluationBinaryglu::TessellationEvaluationBinary447 	TessellationEvaluationBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_EVALUATION) {}
448 };
449 
450 struct ProgramBinaries
451 {
452 	std::vector<ShaderBinary>	binaries;
453 
454 	glw::GLenum					binaryFormat;
455 
ProgramBinariesglu::ProgramBinaries456 	ProgramBinaries (void) : binaryFormat(GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) {}
ProgramBinariesglu::ProgramBinaries457 	ProgramBinaries (glw::GLenum binaryFormat_) : binaryFormat(binaryFormat_) {}
458 
operator <<glu::ProgramBinaries459 	ProgramBinaries& operator<< (const ShaderBinary& shaderBinary)	{ binaries.push_back(shaderBinary);	return *this;	}
460 };
461 
462 template<typename Iterator>
operator <<(const TransformFeedbackVaryings<Iterator> & varyings)463 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
464 {
465 	for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
466 		transformFeedbackVaryings.push_back(*cur);
467 	return *this;
468 }
469 
470 //! Helper for constructing vertex-fragment source pair.
makeVtxFragSources(const std::string & vertexSrc,const std::string & fragmentSrc)471 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
472 {
473 	ProgramSources sources;
474 	sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
475 	sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
476 	return sources;
477 }
478 
479 } // glu
480 
481 #endif // _GLUSHADERPROGRAM_HPP
482