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