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 Shader object.
71 *//*--------------------------------------------------------------------*/
72 class Shader
73 {
74 public:
75 Shader (const glw::Functions& gl, ShaderType shaderType);
76 Shader (const RenderContext& renderCtx, ShaderType shaderType);
77 ~Shader (void);
78
79 void setSources (int numSourceStrings, const char* const* sourceStrings, const int* lengths);
80 void compile (void);
81
getShader(void) const82 deUint32 getShader (void) const { return m_shader; }
getInfo(void) const83 const ShaderInfo& getInfo (void) const { return m_info; }
84
getType(void) const85 glu::ShaderType getType (void) const { return getInfo().type; }
getCompileStatus(void) const86 bool getCompileStatus (void) const { return getInfo().compileOk; }
getSource(void) const87 const std::string& getSource (void) const { return getInfo().source; }
getInfoLog(void) const88 const std::string& getInfoLog (void) const { return getInfo().infoLog; }
89
operator *(void) const90 deUint32 operator* (void) const { return getShader(); }
91
92 private:
93 Shader (const Shader& other);
94 Shader& operator= (const Shader& other);
95
96 const glw::Functions& m_gl;
97 deUint32 m_shader; //!< Shader handle.
98 ShaderInfo m_info; //!< Client-side clone of state for debug / perf reasons.
99 };
100
101 /*--------------------------------------------------------------------*//*!
102 * \brief Program object.
103 *//*--------------------------------------------------------------------*/
104 class Program
105 {
106 public:
107 Program (const glw::Functions& gl);
108 Program (const RenderContext& renderCtx);
109 Program (const RenderContext& renderCtx, deUint32 program);
110 ~Program (void);
111
112 void attachShader (deUint32 shader);
113 void detachShader (deUint32 shader);
114
115 void bindAttribLocation (deUint32 location, const char* name);
116 void transformFeedbackVaryings (int count, const char* const* varyings, deUint32 bufferMode);
117
118 void link (void);
119
getProgram(void) const120 deUint32 getProgram (void) const { return m_program; }
getInfo(void) const121 const ProgramInfo& getInfo (void) const { return m_info; }
122
getLinkStatus(void) const123 bool getLinkStatus (void) const { return getInfo().linkOk; }
getInfoLog(void) const124 const std::string& getInfoLog (void) const { return getInfo().infoLog; }
125
126 bool isSeparable (void) const;
127 void setSeparable (bool separable);
128
129 int getUniformLocation (const std::string& name);
130
operator *(void) const131 deUint32 operator* (void) const { return getProgram(); }
132
133 private:
134 Program (const Program& other);
135 Program& operator= (const Program& other);
136
137 const glw::Functions& m_gl;
138 deUint32 m_program;
139 ProgramInfo m_info;
140 };
141
142
143 /*--------------------------------------------------------------------*//*!
144 * \brief Program pipeline object.
145 *//*--------------------------------------------------------------------*/
146 class ProgramPipeline
147 {
148 public:
149 ProgramPipeline (const RenderContext& renderCtx);
150 ProgramPipeline (const glw::Functions& gl);
151 ~ProgramPipeline (void);
152
getPipeline(void) const153 deUint32 getPipeline (void) const { return m_pipeline; }
154 void useProgramStages (deUint32 stages, deUint32 program);
155 void activeShaderProgram (deUint32 program);
156 bool isValid (void);
157
158 private:
159 ProgramPipeline (const ProgramPipeline& other);
160 ProgramPipeline& operator= (const ProgramPipeline& other);
161
162 const glw::Functions& m_gl;
163 deUint32 m_pipeline;
164 };
165
166 struct ProgramSources;
167
168 /*--------------------------------------------------------------------*//*!
169 * \brief Shader program manager.
170 *
171 * ShaderProgram manages both Shader and Program objects, and provides
172 * convenient API for constructing such programs.
173 *//*--------------------------------------------------------------------*/
174 class ShaderProgram
175 {
176 public:
177 ShaderProgram (const glw::Functions& gl, const ProgramSources& sources);
178 ShaderProgram (const RenderContext& renderCtx, const ProgramSources& sources);
179 ~ShaderProgram (void);
180
isOk(void) const181 bool isOk (void) const { return m_program.getLinkStatus(); }
getProgram(void) const182 deUint32 getProgram (void) const { return m_program.getProgram(); }
183
hasShader(glu::ShaderType shaderType) const184 bool hasShader (glu::ShaderType shaderType) const { return !m_shaders[shaderType].empty(); }
getNumShaders(glu::ShaderType shaderType) const185 int getNumShaders (glu::ShaderType shaderType) const { return (int)m_shaders[shaderType].size(); }
getShaderInfo(glu::ShaderType shaderType,int shaderNdx=0) const186 const ShaderInfo& getShaderInfo (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]->getInfo(); }
getProgramInfo(void) const187 const ProgramInfo& getProgramInfo (void) const { return m_program.getInfo(); }
188
189 private:
190 ShaderProgram (const ShaderProgram& other);
191 ShaderProgram& operator= (const ShaderProgram& other);
192 void init (const glw::Functions& gl, const ProgramSources& sources);
193
194 std::vector<Shader*> m_shaders[SHADERTYPE_LAST];
195 Program m_program;
196 };
197
198 // Utilities.
199
200 deUint32 getGLShaderType (ShaderType shaderType);
201 deUint32 getGLShaderTypeBit (ShaderType shaderType);
202 qpShaderType getLogShaderType (ShaderType shaderType);
203
204 tcu::TestLog& operator<< (tcu::TestLog& log, const Shader& shader);
205 tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgram& program);
206
207 // ProgramSources utilities and implementation.
208
209 struct AttribLocationBinding
210 {
211 std::string name;
212 deUint32 location;
213
AttribLocationBindingglu::AttribLocationBinding214 AttribLocationBinding (void) : location(0) {}
AttribLocationBindingglu::AttribLocationBinding215 AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
216 };
217
218 struct TransformFeedbackMode
219 {
220 deUint32 mode;
221
TransformFeedbackModeglu::TransformFeedbackMode222 TransformFeedbackMode (void) : mode(0) {}
TransformFeedbackModeglu::TransformFeedbackMode223 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
224 };
225
226 struct TransformFeedbackVarying
227 {
228 std::string name;
229
TransformFeedbackVaryingglu::TransformFeedbackVarying230 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
231 };
232
233 struct ProgramSeparable
234 {
235 bool separable;
ProgramSeparableglu::ProgramSeparable236 explicit ProgramSeparable (bool separable_) : separable(separable_) {}
237 };
238
239 template<typename Iterator>
240 struct TransformFeedbackVaryings
241 {
242 Iterator begin;
243 Iterator end;
244
TransformFeedbackVaryingsglu::TransformFeedbackVaryings245 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
246 };
247
248 struct ShaderSource
249 {
250 ShaderType shaderType;
251 std::string source;
252
ShaderSourceglu::ShaderSource253 ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
ShaderSourceglu::ShaderSource254 ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
255 };
256
257 struct VertexSource : public ShaderSource
258 {
VertexSourceglu::VertexSource259 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
260 };
261
262 struct FragmentSource : public ShaderSource
263 {
FragmentSourceglu::FragmentSource264 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
265 };
266
267 struct GeometrySource : public ShaderSource
268 {
GeometrySourceglu::GeometrySource269 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
270 };
271
272 struct ComputeSource : public ShaderSource
273 {
ComputeSourceglu::ComputeSource274 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
275 };
276
277 struct TessellationControlSource : public ShaderSource
278 {
TessellationControlSourceglu::TessellationControlSource279 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
280 };
281
282 struct TessellationEvaluationSource : public ShaderSource
283 {
TessellationEvaluationSourceglu::TessellationEvaluationSource284 TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
285 };
286
287 struct ProgramSources
288 {
289 std::vector<std::string> sources[SHADERTYPE_LAST];
290 std::vector<AttribLocationBinding> attribLocationBindings;
291
292 deUint32 transformFeedbackBufferMode; //!< TF buffer mode, or GL_NONE.
293 std::vector<std::string> transformFeedbackVaryings;
294 bool separable;
295
ProgramSourcesglu::ProgramSources296 ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
297
operator <<glu::ProgramSources298 ProgramSources& operator<< (const AttribLocationBinding& binding) { attribLocationBindings.push_back(binding); return *this; }
operator <<glu::ProgramSources299 ProgramSources& operator<< (const TransformFeedbackMode& mode) { transformFeedbackBufferMode = mode.mode; return *this; }
operator <<glu::ProgramSources300 ProgramSources& operator<< (const TransformFeedbackVarying& varying) { transformFeedbackVaryings.push_back(varying.name); return *this; }
operator <<glu::ProgramSources301 ProgramSources& operator<< (const ShaderSource& shaderSource) { sources[shaderSource.shaderType].push_back(shaderSource.source); return *this; }
operator <<glu::ProgramSources302 ProgramSources& operator<< (const ProgramSeparable& progSeparable) { separable = progSeparable.separable; return *this; }
303
304 template<typename Iterator>
305 ProgramSources& operator<< (const TransformFeedbackVaryings<Iterator>& varyings);
306 };
307
308 template<typename Iterator>
operator <<(const TransformFeedbackVaryings<Iterator> & varyings)309 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
310 {
311 for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
312 transformFeedbackVaryings.push_back(*cur);
313 return *this;
314 }
315
316 //! Helper for constructing vertex-fragment source pair.
makeVtxFragSources(const std::string & vertexSrc,const std::string & fragmentSrc)317 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
318 {
319 ProgramSources sources;
320 sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
321 sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
322 return sources;
323 }
324
325 } // glu
326
327 #endif // _GLUSHADERPROGRAM_HPP
328