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 54 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 66 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 82 deUint32 getShader (void) const { return m_shader; } 83 const ShaderInfo& getInfo (void) const { return m_info; } 84 85 glu::ShaderType getType (void) const { return getInfo().type; } 86 bool getCompileStatus (void) const { return getInfo().compileOk; } 87 const std::string& getSource (void) const { return getInfo().source; } 88 const std::string& getInfoLog (void) const { return getInfo().infoLog; } 89 90 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 120 deUint32 getProgram (void) const { return m_program; } 121 const ProgramInfo& getInfo (void) const { return m_info; } 122 123 bool getLinkStatus (void) const { return getInfo().linkOk; } 124 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 131 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 153 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 181 bool isOk (void) const { return m_program.getLinkStatus(); } 182 deUint32 getProgram (void) const { return m_program.getProgram(); } 183 184 bool hasShader (glu::ShaderType shaderType) const { return !m_shaders[shaderType].empty(); } 185 int getNumShaders (glu::ShaderType shaderType) const { return (int)m_shaders[shaderType].size(); } 186 const ShaderInfo& getShaderInfo (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]->getInfo(); } 187 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 214 AttribLocationBinding (void) : location(0) {} 215 AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {} 216 }; 217 218 struct TransformFeedbackMode 219 { 220 deUint32 mode; 221 222 TransformFeedbackMode (void) : mode(0) {} 223 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {} 224 }; 225 226 struct TransformFeedbackVarying 227 { 228 std::string name; 229 230 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {} 231 }; 232 233 struct ProgramSeparable 234 { 235 bool separable; 236 explicit ProgramSeparable (bool separable_) : separable(separable_) {} 237 }; 238 239 template<typename Iterator> 240 struct TransformFeedbackVaryings 241 { 242 Iterator begin; 243 Iterator end; 244 245 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {} 246 }; 247 248 struct ShaderSource 249 { 250 ShaderType shaderType; 251 std::string source; 252 253 ShaderSource (void) : shaderType(SHADERTYPE_LAST) {} 254 ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); } 255 }; 256 257 struct VertexSource : public ShaderSource 258 { 259 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {} 260 }; 261 262 struct FragmentSource : public ShaderSource 263 { 264 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {} 265 }; 266 267 struct GeometrySource : public ShaderSource 268 { 269 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {} 270 }; 271 272 struct ComputeSource : public ShaderSource 273 { 274 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {} 275 }; 276 277 struct TessellationControlSource : public ShaderSource 278 { 279 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {} 280 }; 281 282 struct TessellationEvaluationSource : public ShaderSource 283 { 284 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 296 ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {} 297 298 ProgramSources& operator<< (const AttribLocationBinding& binding) { attribLocationBindings.push_back(binding); return *this; } 299 ProgramSources& operator<< (const TransformFeedbackMode& mode) { transformFeedbackBufferMode = mode.mode; return *this; } 300 ProgramSources& operator<< (const TransformFeedbackVarying& varying) { transformFeedbackVaryings.push_back(varying.name); return *this; } 301 ProgramSources& operator<< (const ShaderSource& shaderSource) { sources[shaderSource.shaderType].push_back(shaderSource.source); return *this; } 302 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> 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. 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