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 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 91 deUint32 getShader (void) const { return m_shader; } 92 const ShaderInfo& getInfo (void) const { return m_info; } 93 94 glu::ShaderType getType (void) const { return getInfo().type; } 95 bool getCompileStatus (void) const { return getInfo().compileOk; } 96 const std::string& getSource (void) const { return getInfo().source; } 97 const std::string& getInfoLog (void) const { return getInfo().infoLog; } 98 99 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 129 deUint32 getProgram (void) const { return m_program; } 130 const ProgramInfo& getInfo (void) const { return m_info; } 131 132 bool getLinkStatus (void) const { return getInfo().linkOk; } 133 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 140 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 162 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 190 bool isOk (void) const { return m_program.getLinkStatus(); } 191 deUint32 getProgram (void) const { return m_program.getProgram(); } 192 193 bool hasShader (glu::ShaderType shaderType) const { return !m_shaders[shaderType].empty(); } 194 int getNumShaders (glu::ShaderType shaderType) const { return (int)m_shaders[shaderType].size(); } 195 const ShaderInfo& getShaderInfo (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]->getInfo(); } 196 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 226 AttribLocationBinding (void) : location(0) {} 227 AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {} 228 }; 229 230 struct TransformFeedbackMode 231 { 232 deUint32 mode; 233 234 TransformFeedbackMode (void) : mode(0) {} 235 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {} 236 }; 237 238 struct TransformFeedbackVarying 239 { 240 std::string name; 241 242 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {} 243 }; 244 245 struct ProgramSeparable 246 { 247 bool separable; 248 explicit ProgramSeparable (bool separable_) : separable(separable_) {} 249 }; 250 251 template<typename Iterator> 252 struct TransformFeedbackVaryings 253 { 254 Iterator begin; 255 Iterator end; 256 257 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {} 258 }; 259 260 struct ShaderSource 261 { 262 ShaderType shaderType; 263 std::string source; 264 265 ShaderSource (void) : shaderType(SHADERTYPE_LAST) {} 266 ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); } 267 }; 268 269 struct VertexSource : public ShaderSource 270 { 271 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {} 272 }; 273 274 struct FragmentSource : public ShaderSource 275 { 276 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {} 277 }; 278 279 struct GeometrySource : public ShaderSource 280 { 281 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {} 282 }; 283 284 struct ComputeSource : public ShaderSource 285 { 286 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {} 287 }; 288 289 struct TessellationControlSource : public ShaderSource 290 { 291 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {} 292 }; 293 294 struct TessellationEvaluationSource : public ShaderSource 295 { 296 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 308 ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {} 309 310 ProgramSources& operator<< (const AttribLocationBinding& binding) { attribLocationBindings.push_back(binding); return *this; } 311 ProgramSources& operator<< (const TransformFeedbackMode& mode) { transformFeedbackBufferMode = mode.mode; return *this; } 312 ProgramSources& operator<< (const TransformFeedbackVarying& varying) { transformFeedbackVaryings.push_back(varying.name); return *this; } 313 ProgramSources& operator<< (const ShaderSource& shaderSource) { sources[shaderSource.shaderType].push_back(shaderSource.source); return *this; } 314 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> 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. 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