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 RenderContext& renderCtx, ShaderType shaderType);
76 ~Shader (void);
77
78 void setSources (int numSourceStrings, const char* const* sourceStrings, const int* lengths);
79 void compile (void);
80
getShader(void) const81 deUint32 getShader (void) const { return m_shader; }
getInfo(void) const82 const ShaderInfo& getInfo (void) const { return m_info; }
83
getType(void) const84 glu::ShaderType getType (void) const { return getInfo().type; }
getCompileStatus(void) const85 bool getCompileStatus (void) const { return getInfo().compileOk; }
getSource(void) const86 const std::string& getSource (void) const { return getInfo().source; }
getInfoLog(void) const87 const std::string& getInfoLog (void) const { return getInfo().infoLog; }
88
operator *(void) const89 deUint32 operator* (void) const { return getShader(); }
90
91 private:
92 Shader (const Shader& other);
93 Shader& operator= (const Shader& other);
94
95 const RenderContext& m_renderCtx;
96 deUint32 m_shader; //!< Shader handle.
97 ShaderInfo m_info; //!< Client-side clone of state for debug / perf reasons.
98 };
99
100 /*--------------------------------------------------------------------*//*!
101 * \brief Program object.
102 *//*--------------------------------------------------------------------*/
103 class Program
104 {
105 public:
106 Program (const RenderContext& renderCtx);
107 Program (const RenderContext& renderCtx, deUint32 program);
108 ~Program (void);
109
110 void attachShader (deUint32 shader);
111 void detachShader (deUint32 shader);
112
113 void bindAttribLocation (deUint32 location, const char* name);
114 void transformFeedbackVaryings (int count, const char* const* varyings, deUint32 bufferMode);
115
116 void link (void);
117
getProgram(void) const118 deUint32 getProgram (void) const { return m_program; }
getInfo(void) const119 const ProgramInfo& getInfo (void) const { return m_info; }
120
getLinkStatus(void) const121 bool getLinkStatus (void) const { return getInfo().linkOk; }
getInfoLog(void) const122 const std::string& getInfoLog (void) const { return getInfo().infoLog; }
123
124 bool isSeparable (void) const;
125 void setSeparable (bool separable);
126
127 int getUniformLocation (const std::string& name);
128
operator *(void) const129 deUint32 operator* (void) const { return getProgram(); }
130
131 private:
132 Program (const Program& other);
133 Program& operator= (const Program& other);
134
135 const RenderContext& m_renderCtx;
136 deUint32 m_program;
137 ProgramInfo m_info;
138 };
139
140
141 /*--------------------------------------------------------------------*//*!
142 * \brief Program pipeline object.
143 *//*--------------------------------------------------------------------*/
144 class ProgramPipeline
145 {
146 public:
147 ProgramPipeline (const RenderContext& renderCtx);
148 ~ProgramPipeline (void);
149
getPipeline(void) const150 deUint32 getPipeline (void) const { return m_pipeline; }
151 void useProgramStages (deUint32 stages, deUint32 program);
152 void activeShaderProgram (deUint32 program);
153 bool isValid (void);
154
155 private:
156 ProgramPipeline (const ProgramPipeline& other);
157 ProgramPipeline& operator= (const ProgramPipeline& other);
158
159 const RenderContext& m_renderCtx;
160 deUint32 m_pipeline;
161 };
162
163 struct ProgramSources;
164
165 /*--------------------------------------------------------------------*//*!
166 * \brief Shader program manager.
167 *
168 * ShaderProgram manages both Shader and Program objects, and provides
169 * convenient API for constructing such programs.
170 *//*--------------------------------------------------------------------*/
171 class ShaderProgram
172 {
173 public:
174 ShaderProgram (const RenderContext& renderCtx, const ProgramSources& sources);
175 ~ShaderProgram (void);
176
isOk(void) const177 bool isOk (void) const { return m_program.getLinkStatus(); }
getProgram(void) const178 deUint32 getProgram (void) const { return m_program.getProgram(); }
179
hasShader(glu::ShaderType shaderType) const180 bool hasShader (glu::ShaderType shaderType) const { return !m_shaders[shaderType].empty(); }
getNumShaders(glu::ShaderType shaderType) const181 int getNumShaders (glu::ShaderType shaderType) const { return (int)m_shaders[shaderType].size(); }
getShaderInfo(glu::ShaderType shaderType,int shaderNdx=0) const182 const ShaderInfo& getShaderInfo (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]->getInfo(); }
getProgramInfo(void) const183 const ProgramInfo& getProgramInfo (void) const { return m_program.getInfo(); }
184
185 private:
186 ShaderProgram (const ShaderProgram& other);
187 ShaderProgram& operator= (const ShaderProgram& other);
188
189 std::vector<Shader*> m_shaders[SHADERTYPE_LAST];
190 Program m_program;
191 };
192
193 // Utilities.
194
195 deUint32 getGLShaderType (ShaderType shaderType);
196 deUint32 getGLShaderTypeBit (ShaderType shaderType);
197 qpShaderType getLogShaderType (ShaderType shaderType);
198
199 tcu::TestLog& operator<< (tcu::TestLog& log, const Shader& shader);
200 tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgram& program);
201
202 // ProgramSources utilities and implementation.
203
204 struct AttribLocationBinding
205 {
206 std::string name;
207 deUint32 location;
208
AttribLocationBindingglu::AttribLocationBinding209 AttribLocationBinding (void) : location(0) {}
AttribLocationBindingglu::AttribLocationBinding210 AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {}
211 };
212
213 struct TransformFeedbackMode
214 {
215 deUint32 mode;
216
TransformFeedbackModeglu::TransformFeedbackMode217 TransformFeedbackMode (void) : mode(0) {}
TransformFeedbackModeglu::TransformFeedbackMode218 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {}
219 };
220
221 struct TransformFeedbackVarying
222 {
223 std::string name;
224
TransformFeedbackVaryingglu::TransformFeedbackVarying225 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {}
226 };
227
228 struct ProgramSeparable
229 {
230 bool separable;
ProgramSeparableglu::ProgramSeparable231 explicit ProgramSeparable (bool separable_) : separable(separable_) {}
232 };
233
234 template<typename Iterator>
235 struct TransformFeedbackVaryings
236 {
237 Iterator begin;
238 Iterator end;
239
TransformFeedbackVaryingsglu::TransformFeedbackVaryings240 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {}
241 };
242
243 struct ShaderSource
244 {
245 ShaderType shaderType;
246 std::string source;
247
ShaderSourceglu::ShaderSource248 ShaderSource (void) : shaderType(SHADERTYPE_LAST) {}
ShaderSourceglu::ShaderSource249 ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); }
250 };
251
252 struct VertexSource : public ShaderSource
253 {
VertexSourceglu::VertexSource254 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {}
255 };
256
257 struct FragmentSource : public ShaderSource
258 {
FragmentSourceglu::FragmentSource259 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {}
260 };
261
262 struct GeometrySource : public ShaderSource
263 {
GeometrySourceglu::GeometrySource264 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {}
265 };
266
267 struct ComputeSource : public ShaderSource
268 {
ComputeSourceglu::ComputeSource269 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {}
270 };
271
272 struct TessellationControlSource : public ShaderSource
273 {
TessellationControlSourceglu::TessellationControlSource274 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {}
275 };
276
277 struct TessellationEvaluationSource : public ShaderSource
278 {
TessellationEvaluationSourceglu::TessellationEvaluationSource279 TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {}
280 };
281
282 struct ProgramSources
283 {
284 std::vector<std::string> sources[SHADERTYPE_LAST];
285 std::vector<AttribLocationBinding> attribLocationBindings;
286
287 deUint32 transformFeedbackBufferMode; //!< TF buffer mode, or GL_NONE.
288 std::vector<std::string> transformFeedbackVaryings;
289 bool separable;
290
ProgramSourcesglu::ProgramSources291 ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {}
292
operator <<glu::ProgramSources293 ProgramSources& operator<< (const AttribLocationBinding& binding) { attribLocationBindings.push_back(binding); return *this; }
operator <<glu::ProgramSources294 ProgramSources& operator<< (const TransformFeedbackMode& mode) { transformFeedbackBufferMode = mode.mode; return *this; }
operator <<glu::ProgramSources295 ProgramSources& operator<< (const TransformFeedbackVarying& varying) { transformFeedbackVaryings.push_back(varying.name); return *this; }
operator <<glu::ProgramSources296 ProgramSources& operator<< (const ShaderSource& shaderSource) { sources[shaderSource.shaderType].push_back(shaderSource.source); return *this; }
operator <<glu::ProgramSources297 ProgramSources& operator<< (const ProgramSeparable& progSeparable) { separable = progSeparable.separable; return *this; }
298
299 template<typename Iterator>
300 ProgramSources& operator<< (const TransformFeedbackVaryings<Iterator>& varyings);
301 };
302
303 template<typename Iterator>
operator <<(const TransformFeedbackVaryings<Iterator> & varyings)304 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings)
305 {
306 for (Iterator cur = varyings.begin; cur != varyings.end; ++cur)
307 transformFeedbackVaryings.push_back(*cur);
308 return *this;
309 }
310
311 //! Helper for constructing vertex-fragment source pair.
makeVtxFragSources(const std::string & vertexSrc,const std::string & fragmentSrc)312 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc)
313 {
314 ProgramSources sources;
315 sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc);
316 sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
317 return sources;
318 }
319
320 } // glu
321
322 #endif // _GLUSHADERPROGRAM_HPP
323