• 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 "qpTestLog.h"
29 
30 #include <string>
31 #include <vector>
32 
33 namespace tcu
34 {
35 class TestLog;
36 }
37 
38 namespace glu
39 {
40 
41 class RenderContext;
42 
43 /*--------------------------------------------------------------------*//*!
44  * \brief Shader information (compile status, log, etc.).
45  *//*--------------------------------------------------------------------*/
46 struct 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 
ShaderInfoglu::ShaderInfo54 	ShaderInfo (void) : compileOk(false), compileTimeUs(0) {}
55 };
56 
57 /*--------------------------------------------------------------------*//*!
58  * \brief Program information (link status, log).
59  *//*--------------------------------------------------------------------*/
60 struct ProgramInfo
61 {
62 	std::string				infoLog;		//!< Link info log.
63 	bool					linkOk;			//!< Did link succeed?
64 	deUint64				linkTimeUs;		//!< Link time in microseconds (us).
65 
ProgramInfoglu::ProgramInfo66 	ProgramInfo (void) : linkOk(false), linkTimeUs(0) {}
67 };
68 
69 /*--------------------------------------------------------------------*//*!
70  * \brief Combined shader compilation and program linking info.
71  *//*--------------------------------------------------------------------*/
72 struct ShaderProgramInfo
73 {
74 	glu::ProgramInfo				program;
75 	std::vector<glu::ShaderInfo>	shaders;
76 };
77 
78 /*--------------------------------------------------------------------*//*!
79  * \brief Shader object.
80  *//*--------------------------------------------------------------------*/
81 class Shader
82 {
83 public:
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 
getShader(void) const91 	deUint32				getShader			(void) const { return m_shader;				}
getInfo(void) const92 	const ShaderInfo&		getInfo				(void) const { return m_info;				}
93 
getType(void) const94 	glu::ShaderType			getType				(void) const { return getInfo().type;		}
getCompileStatus(void) const95 	bool					getCompileStatus	(void) const { return getInfo().compileOk;	}
getSource(void) const96 	const std::string&		getSource			(void) const { return getInfo().source;		}
getInfoLog(void) const97 	const std::string&		getInfoLog			(void) const { return getInfo().infoLog;	}
98 
operator *(void) const99 	deUint32				operator*			(void) const { return getShader();			}
100 
101 private:
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  *//*--------------------------------------------------------------------*/
113 class Program
114 {
115 public:
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 
getProgram(void) const129 	deUint32				getProgram					(void) const { return m_program;			}
getInfo(void) const130 	const ProgramInfo&		getInfo						(void) const { return m_info;				}
131 
getLinkStatus(void) const132 	bool					getLinkStatus				(void) const { return getInfo().linkOk;		}
getInfoLog(void) const133 	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 
operator *(void) const140 	deUint32				operator*					(void) const { return getProgram();			}
141 
142 private:
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  *//*--------------------------------------------------------------------*/
155 class ProgramPipeline
156 {
157 public:
158 							ProgramPipeline				(const RenderContext& renderCtx);
159 							ProgramPipeline				(const glw::Functions& gl);
160 							~ProgramPipeline			(void);
161 
getPipeline(void) const162 	deUint32				getPipeline					(void) const { return m_pipeline; }
163 	void					useProgramStages			(deUint32 stages, deUint32 program);
164 	void					activeShaderProgram			(deUint32 program);
165 	bool					isValid						(void);
166 
167 private:
168 							ProgramPipeline				(const ProgramPipeline& other);
169 	ProgramPipeline&		operator=					(const ProgramPipeline& other);
170 
171 	const glw::Functions&	m_gl;
172 	deUint32				m_pipeline;
173 };
174 
175 struct 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  *//*--------------------------------------------------------------------*/
183 class ShaderProgram
184 {
185 public:
186 							ShaderProgram				(const glw::Functions& gl, const ProgramSources& sources);
187 							ShaderProgram				(const RenderContext& renderCtx, const ProgramSources& sources);
188 							~ShaderProgram				(void);
189 
isOk(void) const190 	bool					isOk						(void) const											{ return m_program.getLinkStatus();						}
getProgram(void) const191 	deUint32				getProgram					(void) const											{ return m_program.getProgram();						}
192 
hasShader(glu::ShaderType shaderType) const193 	bool					hasShader					(glu::ShaderType shaderType) const						{ return !m_shaders[shaderType].empty();				}
getNumShaders(glu::ShaderType shaderType) const194 	int						getNumShaders				(glu::ShaderType shaderType) const						{ return (int)m_shaders[shaderType].size();				}
getShaderInfo(glu::ShaderType shaderType,int shaderNdx=0) const195 	const ShaderInfo&		getShaderInfo				(glu::ShaderType shaderType, int shaderNdx = 0) const	{ return m_shaders[shaderType][shaderNdx]->getInfo();	}
getProgramInfo(void) const196 	const ProgramInfo&		getProgramInfo				(void) const											{ return m_program.getInfo();							}
197 
198 private:
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 
209 deUint32		getGLShaderType		(ShaderType shaderType);
210 deUint32		getGLShaderTypeBit	(ShaderType shaderType);
211 qpShaderType	getLogShaderType	(ShaderType shaderType);
212 
213 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderInfo& shaderInfo);
214 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo);
215 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ProgramSources& sources);
216 tcu::TestLog&	operator<<			(tcu::TestLog& log, const Shader& shader);
217 tcu::TestLog&	operator<<			(tcu::TestLog& log, const ShaderProgram& program);
218 
219 // ProgramSources utilities and implementation.
220 
221 struct AttribLocationBinding
222 {
223 	std::string			name;
224 	deUint32			location;
225 
AttribLocationBindingglu::AttribLocationBinding226 	AttribLocationBinding (void) : location(0) {}
AttribLocationBindingglu::AttribLocationBinding227 	AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
228 };
229 
230 struct TransformFeedbackMode
231 {
232 	deUint32			mode;
233 
TransformFeedbackModeglu::TransformFeedbackMode234 	TransformFeedbackMode (void) : mode(0) {}
TransformFeedbackModeglu::TransformFeedbackMode235 	TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
236 };
237 
238 struct TransformFeedbackVarying
239 {
240 	std::string			name;
241 
TransformFeedbackVaryingglu::TransformFeedbackVarying242 	explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
243 };
244 
245 struct ProgramSeparable
246 {
247 	bool				separable;
ProgramSeparableglu::ProgramSeparable248 	explicit ProgramSeparable (bool separable_) : separable(separable_) {}
249 };
250 
251 template<typename Iterator>
252 struct TransformFeedbackVaryings
253 {
254 	Iterator			begin;
255 	Iterator			end;
256 
TransformFeedbackVaryingsglu::TransformFeedbackVaryings257 	TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
258 };
259 
260 struct ShaderSource
261 {
262 	ShaderType			shaderType;
263 	std::string			source;
264 
ShaderSourceglu::ShaderSource265 	ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
ShaderSourceglu::ShaderSource266 	ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
267 };
268 
269 struct VertexSource : public ShaderSource
270 {
VertexSourceglu::VertexSource271 	VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
272 };
273 
274 struct FragmentSource : public ShaderSource
275 {
FragmentSourceglu::FragmentSource276 	FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
277 };
278 
279 struct GeometrySource : public ShaderSource
280 {
GeometrySourceglu::GeometrySource281 	GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
282 };
283 
284 struct ComputeSource : public ShaderSource
285 {
ComputeSourceglu::ComputeSource286 	ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
287 };
288 
289 struct TessellationControlSource : public ShaderSource
290 {
TessellationControlSourceglu::TessellationControlSource291 	TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
292 };
293 
294 struct TessellationEvaluationSource : public ShaderSource
295 {
TessellationEvaluationSourceglu::TessellationEvaluationSource296 	TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
297 };
298 
299 struct 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 
ProgramSourcesglu::ProgramSources308 	ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
309 
operator <<glu::ProgramSources310 	ProgramSources&						operator<<			(const AttribLocationBinding& binding)		{ attribLocationBindings.push_back(binding);						return *this;	}
operator <<glu::ProgramSources311 	ProgramSources&						operator<<			(const TransformFeedbackMode& mode)			{ transformFeedbackBufferMode = mode.mode;							return *this;	}
operator <<glu::ProgramSources312 	ProgramSources&						operator<<			(const TransformFeedbackVarying& varying)	{ transformFeedbackVaryings.push_back(varying.name);				return *this;	}
operator <<glu::ProgramSources313 	ProgramSources&						operator<<			(const ShaderSource& shaderSource)			{ sources[shaderSource.shaderType].push_back(shaderSource.source);	return *this;	}
operator <<glu::ProgramSources314 	ProgramSources&						operator<<			(const ProgramSeparable& progSeparable)		{ separable = progSeparable.separable;								return *this;	}
315 
316 	template<typename Iterator>
317 	ProgramSources&						operator<<			(const TransformFeedbackVaryings<Iterator>& varyings);
318 };
319 
320 template<typename Iterator>
operator <<(const TransformFeedbackVaryings<Iterator> & varyings)321 inline 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.
makeVtxFragSources(const std::string & vertexSrc,const std::string & fragmentSrc)329 inline 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