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 "qpTestLog.h"
29
30#include <string>
31#include <vector>
32
33namespace tcu
34{
35class TestLog;
36}
37
38namespace glu
39{
40
41class RenderContext;
42
43/*--------------------------------------------------------------------*//*!
44 * \brief Shader information (compile status, log, etc.).
45 *//*--------------------------------------------------------------------*/
46struct ShaderInfo
47{
48	ShaderType				type;			//!< Shader type.
49	std::string				source;			//!< Shader source.
50	std::string				infoLog;		//!< Compile info log.
51	bool					compileOk;		//!< Did compilation succeed?
52	deUint64				compileTimeUs;	//!< Compile time in microseconds (us).
53
54	ShaderInfo (void) : compileOk(false), compileTimeUs(0) {}
55};
56
57/*--------------------------------------------------------------------*//*!
58 * \brief Program information (link status, log).
59 *//*--------------------------------------------------------------------*/
60struct ProgramInfo
61{
62	std::string				infoLog;		//!< Link info log.
63	bool					linkOk;			//!< Did link succeed?
64	deUint64				linkTimeUs;		//!< Link time in microseconds (us).
65
66	ProgramInfo (void) : linkOk(false), linkTimeUs(0) {}
67};
68
69/*--------------------------------------------------------------------*//*!
70 * \brief Combined shader compilation and program linking info.
71 *//*--------------------------------------------------------------------*/
72struct ShaderProgramInfo
73{
74	glu::ProgramInfo				program;
75	std::vector<glu::ShaderInfo>	shaders;
76};
77
78/*--------------------------------------------------------------------*//*!
79 * \brief Shader object.
80 *//*--------------------------------------------------------------------*/
81class Shader
82{
83public:
84							Shader				(const glw::Functions& gl, ShaderType shaderType);
85							Shader				(const RenderContext& renderCtx, ShaderType shaderType);
86							~Shader				(void);
87
88	void					setSources			(int numSourceStrings, const char* const* sourceStrings, const int* lengths);
89	void					compile				(void);
90
91	deUint32				getShader			(void) const { return m_shader;				}
92	const ShaderInfo&		getInfo				(void) const { return m_info;				}
93
94	glu::ShaderType			getType				(void) const { return getInfo().type;		}
95	bool					getCompileStatus	(void) const { return getInfo().compileOk;	}
96	const std::string&		getSource			(void) const { return getInfo().source;		}
97	const std::string&		getInfoLog			(void) const { return getInfo().infoLog;	}
98
99	deUint32				operator*			(void) const { return getShader();			}
100
101private:
102							Shader				(const Shader& other);
103	Shader&					operator=			(const Shader& other);
104
105	const glw::Functions&	m_gl;
106	deUint32				m_shader;	//!< Shader handle.
107	ShaderInfo				m_info;		//!< Client-side clone of state for debug / perf reasons.
108};
109
110/*--------------------------------------------------------------------*//*!
111 * \brief Program object.
112 *//*--------------------------------------------------------------------*/
113class Program
114{
115public:
116							Program						(const glw::Functions& gl);
117							Program						(const RenderContext& renderCtx);
118							Program						(const RenderContext& renderCtx, deUint32 program);
119							~Program					(void);
120
121	void					attachShader				(deUint32 shader);
122	void					detachShader				(deUint32 shader);
123
124	void					bindAttribLocation			(deUint32 location, const char* name);
125	void					transformFeedbackVaryings	(int count, const char* const* varyings, deUint32 bufferMode);
126
127	void					link						(void);
128
129	deUint32				getProgram					(void) const { return m_program;			}
130	const ProgramInfo&		getInfo						(void) const { return m_info;				}
131
132	bool					getLinkStatus				(void) const { return getInfo().linkOk;		}
133	const std::string&		getInfoLog					(void) const { return getInfo().infoLog;	}
134
135	bool					isSeparable					(void) const;
136	void					setSeparable				(bool separable);
137
138	int						getUniformLocation			(const std::string& name);
139
140	deUint32				operator*					(void) const { return getProgram();			}
141
142private:
143							Program						(const Program& other);
144	Program&				operator=					(const Program& other);
145
146	const glw::Functions&	m_gl;
147	deUint32				m_program;
148	ProgramInfo				m_info;
149};
150
151
152/*--------------------------------------------------------------------*//*!
153 * \brief Program pipeline object.
154 *//*--------------------------------------------------------------------*/
155class ProgramPipeline
156{
157public:
158							ProgramPipeline				(const RenderContext& renderCtx);
159							ProgramPipeline				(const glw::Functions& gl);
160							~ProgramPipeline			(void);
161
162	deUint32				getPipeline					(void) const { return m_pipeline; }
163	void					useProgramStages			(deUint32 stages, deUint32 program);
164	void					activeShaderProgram			(deUint32 program);
165	bool					isValid						(void);
166
167private:
168							ProgramPipeline				(const ProgramPipeline& other);
169	ProgramPipeline&		operator=					(const ProgramPipeline& other);
170
171	const glw::Functions&	m_gl;
172	deUint32				m_pipeline;
173};
174
175struct ProgramSources;
176
177/*--------------------------------------------------------------------*//*!
178 * \brief Shader program manager.
179 *
180 * ShaderProgram manages both Shader and Program objects, and provides
181 * convenient API for constructing such programs.
182 *//*--------------------------------------------------------------------*/
183class ShaderProgram
184{
185public:
186							ShaderProgram				(const glw::Functions& gl, const ProgramSources& sources);
187							ShaderProgram				(const RenderContext& renderCtx, const ProgramSources& sources);
188							~ShaderProgram				(void);
189
190	bool					isOk						(void) const											{ return m_program.getLinkStatus();						}
191	deUint32				getProgram					(void) const											{ return m_program.getProgram();						}
192
193	bool					hasShader					(glu::ShaderType shaderType) const						{ return !m_shaders[shaderType].empty();				}
194	int						getNumShaders				(glu::ShaderType shaderType) const						{ return (int)m_shaders[shaderType].size();				}
195	const ShaderInfo&		getShaderInfo				(glu::ShaderType shaderType, int shaderNdx = 0) const	{ return m_shaders[shaderType][shaderNdx]->getInfo();	}
196	const ProgramInfo&		getProgramInfo				(void) const											{ return m_program.getInfo();							}
197
198private:
199							ShaderProgram				(const ShaderProgram& other);
200	ShaderProgram&			operator=					(const ShaderProgram& other);
201	void					init						(const glw::Functions& gl, const ProgramSources& sources);
202
203	std::vector<Shader*>	m_shaders[SHADERTYPE_LAST];
204	Program					m_program;
205};
206
207// Utilities.
208
209deUint32		getGLShaderType		(ShaderType shaderType);
210deUint32		getGLShaderTypeBit	(ShaderType shaderType);
211qpShaderType	getLogShaderType	(ShaderType shaderType);
212
213tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderInfo& shaderInfo);
214tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo);
215tcu::TestLog&	operator<<			(tcu::TestLog& log, const ProgramSources& sources);
216tcu::TestLog&	operator<<			(tcu::TestLog& log, const Shader& shader);
217tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgram& program);
218
219// ProgramSources utilities and implementation.
220
221struct AttribLocationBinding
222{
223	std::string			name;
224	deUint32			location;
225
226	AttribLocationBinding (void) : location(0) {}
227	AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
228};
229
230struct TransformFeedbackMode
231{
232	deUint32			mode;
233
234	TransformFeedbackMode (void) : mode(0) {}
235	TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
236};
237
238struct TransformFeedbackVarying
239{
240	std::string			name;
241
242	explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
243};
244
245struct ProgramSeparable
246{
247	bool				separable;
248	explicit ProgramSeparable (bool separable_) : separable(separable_) {}
249};
250
251template<typename Iterator>
252struct TransformFeedbackVaryings
253{
254	Iterator			begin;
255	Iterator			end;
256
257	TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
258};
259
260struct ShaderSource
261{
262	ShaderType			shaderType;
263	std::string			source;
264
265	ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
266	ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
267};
268
269struct VertexSource : public ShaderSource
270{
271	VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
272};
273
274struct FragmentSource : public ShaderSource
275{
276	FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
277};
278
279struct GeometrySource : public ShaderSource
280{
281	GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
282};
283
284struct ComputeSource : public ShaderSource
285{
286	ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
287};
288
289struct TessellationControlSource : public ShaderSource
290{
291	TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
292};
293
294struct TessellationEvaluationSource : public ShaderSource
295{
296	TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
297};
298
299struct ProgramSources
300{
301	std::vector<std::string>			sources[SHADERTYPE_LAST];
302	std::vector<AttribLocationBinding>	attribLocationBindings;
303
304	deUint32							transformFeedbackBufferMode;		//!< TF buffer mode, or GL_NONE.
305	std::vector<std::string>			transformFeedbackVaryings;
306	bool								separable;
307
308	ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
309
310	ProgramSources&						operator<<			(const AttribLocationBinding& binding)		{ attribLocationBindings.push_back(binding);						return *this;	}
311	ProgramSources&						operator<<			(const TransformFeedbackMode& mode)			{ transformFeedbackBufferMode = mode.mode;							return *this;	}
312	ProgramSources&						operator<<			(const TransformFeedbackVarying& varying)	{ transformFeedbackVaryings.push_back(varying.name);				return *this;	}
313	ProgramSources&						operator<<			(const ShaderSource& shaderSource)			{ sources[shaderSource.shaderType].push_back(shaderSource.source);	return *this;	}
314	ProgramSources&						operator<<			(const ProgramSeparable& progSeparable)		{ separable = progSeparable.separable;								return *this;	}
315
316	template<typename Iterator>
317	ProgramSources&						operator<<			(const TransformFeedbackVaryings<Iterator>& varyings);
318};
319
320template<typename Iterator>
321inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
322{
323	for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
324		transformFeedbackVaryings.push_back(*cur);
325	return *this;
326}
327
328//! Helper for constructing vertex-fragment source pair.
329inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
330{
331	ProgramSources sources;
332	sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
333	sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
334	return sources;
335}
336
337} // glu
338
339#endif // _GLUSHADERPROGRAM_HPP
340