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