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 "glwEnums.hpp" 29 #include "qpTestLog.h" 30 31 #include <string> 32 #include <vector> 33 34 namespace tcu 35 { 36 class TestLog; 37 } 38 39 namespace glu 40 { 41 42 class RenderContext; 43 44 typedef std::vector<deUint32> ShaderBinaryDataType; 45 46 /*--------------------------------------------------------------------*//*! 47 * \brief Shader information (compile status, log, etc.). 48 *//*--------------------------------------------------------------------*/ 49 struct ShaderInfo 50 { 51 ShaderType type; //!< Shader type. 52 std::string source; //!< Shader source. 53 std::string infoLog; //!< Compile info log. 54 bool compileOk; //!< Did compilation succeed? 55 deUint64 compileTimeUs; //!< Compile time in microseconds (us). 56 57 ShaderInfo (void) : compileOk(false), compileTimeUs(0) {} 58 }; 59 60 /*--------------------------------------------------------------------*//*! 61 * \brief Program information (link status, log). 62 *//*--------------------------------------------------------------------*/ 63 struct ProgramInfo 64 { 65 std::string infoLog; //!< Link info log. 66 bool linkOk; //!< Did link succeed? 67 deUint64 linkTimeUs; //!< Link time in microseconds (us). 68 69 ProgramInfo (void) : linkOk(false), linkTimeUs(0) {} 70 }; 71 72 /*--------------------------------------------------------------------*//*! 73 * \brief Combined shader compilation and program linking info. 74 *//*--------------------------------------------------------------------*/ 75 struct ShaderProgramInfo 76 { 77 glu::ProgramInfo program; 78 std::vector<glu::ShaderInfo> shaders; 79 }; 80 81 /*--------------------------------------------------------------------*//*! 82 * \brief Shader object. 83 *//*--------------------------------------------------------------------*/ 84 class Shader 85 { 86 public: 87 Shader (const glw::Functions& gl, ShaderType shaderType); 88 Shader (const RenderContext& renderCtx, ShaderType shaderType); 89 ~Shader (void); 90 91 void setSources (int numSourceStrings, const char* const* sourceStrings, const int* lengths); 92 void compile (void); 93 void specialize (const char* entryPoint, glw::GLuint numSpecializationConstants, 94 const glw::GLuint* constantIndex, const glw::GLuint* constantValue); 95 96 deUint32 getShader (void) const { return m_shader; } 97 const ShaderInfo& getInfo (void) const { return m_info; } 98 99 glu::ShaderType getType (void) const { return getInfo().type; } 100 bool getCompileStatus (void) const { return getInfo().compileOk; } 101 const std::string& getSource (void) const { return getInfo().source; } 102 const std::string& getInfoLog (void) const { return getInfo().infoLog; } 103 104 deUint32 operator* (void) const { return getShader(); } 105 106 private: 107 Shader (const Shader& other); 108 Shader& operator= (const Shader& other); 109 110 const glw::Functions& m_gl; 111 deUint32 m_shader; //!< Shader handle. 112 ShaderInfo m_info; //!< Client-side clone of state for debug / perf reasons. 113 }; 114 115 /*--------------------------------------------------------------------*//*! 116 * \brief Program object. 117 *//*--------------------------------------------------------------------*/ 118 class Program 119 { 120 public: 121 Program (const glw::Functions& gl); 122 Program (const RenderContext& renderCtx); 123 Program (const RenderContext& renderCtx, deUint32 program); 124 ~Program (void); 125 126 void attachShader (deUint32 shader); 127 void detachShader (deUint32 shader); 128 129 void bindAttribLocation (deUint32 location, const char* name); 130 void transformFeedbackVaryings (int count, const char* const* varyings, deUint32 bufferMode); 131 132 void link (void); 133 134 deUint32 getProgram (void) const { return m_program; } 135 const ProgramInfo& getInfo (void) const { return m_info; } 136 137 bool getLinkStatus (void) const { return getInfo().linkOk; } 138 const std::string& getInfoLog (void) const { return getInfo().infoLog; } 139 140 bool isSeparable (void) const; 141 void setSeparable (bool separable); 142 143 int getUniformLocation (const std::string& name); 144 145 deUint32 operator* (void) const { return getProgram(); } 146 147 private: 148 Program (const Program& other); 149 Program& operator= (const Program& other); 150 151 const glw::Functions& m_gl; 152 deUint32 m_program; 153 ProgramInfo m_info; 154 }; 155 156 157 /*--------------------------------------------------------------------*//*! 158 * \brief Program pipeline object. 159 *//*--------------------------------------------------------------------*/ 160 class ProgramPipeline 161 { 162 public: 163 ProgramPipeline (const RenderContext& renderCtx); 164 ProgramPipeline (const glw::Functions& gl); 165 ~ProgramPipeline (void); 166 167 deUint32 getPipeline (void) const { return m_pipeline; } 168 void useProgramStages (deUint32 stages, deUint32 program); 169 void activeShaderProgram (deUint32 program); 170 bool isValid (void); 171 172 private: 173 ProgramPipeline (const ProgramPipeline& other); 174 ProgramPipeline& operator= (const ProgramPipeline& other); 175 176 const glw::Functions& m_gl; 177 deUint32 m_pipeline; 178 }; 179 180 struct ProgramSources; 181 struct ProgramBinaries; 182 183 /*--------------------------------------------------------------------*//*! 184 * \brief Shader program manager. 185 * 186 * ShaderProgram manages both Shader and Program objects, and provides 187 * convenient API for constructing such programs. 188 *//*--------------------------------------------------------------------*/ 189 class ShaderProgram 190 { 191 public: 192 ShaderProgram (const glw::Functions& gl, const ProgramSources& sources); 193 ShaderProgram (const glw::Functions& gl, const ProgramBinaries& binaries); 194 ShaderProgram (const RenderContext& renderCtx, const ProgramSources& sources); 195 ShaderProgram (const RenderContext& renderCtx, const ProgramBinaries& binaries); 196 ~ShaderProgram (void); 197 198 bool isOk (void) const { return m_program.getLinkStatus(); } 199 deUint32 getProgram (void) const { return m_program.getProgram(); } 200 201 bool hasShader (glu::ShaderType shaderType) const { return !m_shaders[shaderType].empty(); } 202 Shader* getShader (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]; } 203 int getNumShaders (glu::ShaderType shaderType) const { return (int)m_shaders[shaderType].size(); } 204 const ShaderInfo& getShaderInfo (glu::ShaderType shaderType, int shaderNdx = 0) const { return m_shaders[shaderType][shaderNdx]->getInfo(); } 205 const ProgramInfo& getProgramInfo (void) const { return m_program.getInfo(); } 206 207 private: 208 ShaderProgram (const ShaderProgram& other); 209 ShaderProgram& operator= (const ShaderProgram& other); 210 void init (const glw::Functions& gl, const ProgramSources& sources); 211 void init (const glw::Functions& gl, const ProgramBinaries& binaries); 212 void setBinary (const glw::Functions& gl, std::vector<Shader*>& shaders, glw::GLenum binaryFormat, const void* binaryData, const int length); 213 214 std::vector<Shader*> m_shaders[SHADERTYPE_LAST]; 215 Program m_program; 216 }; 217 218 // Utilities. 219 220 deUint32 getGLShaderType (ShaderType shaderType); 221 deUint32 getGLShaderTypeBit (ShaderType shaderType); 222 qpShaderType getLogShaderType (ShaderType shaderType); 223 224 tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderInfo& shaderInfo); 225 tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo); 226 tcu::TestLog& operator<< (tcu::TestLog& log, const ProgramSources& sources); 227 tcu::TestLog& operator<< (tcu::TestLog& log, const Shader& shader); 228 tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgram& program); 229 230 // ProgramSources utilities and implementation. 231 232 struct AttribLocationBinding 233 { 234 std::string name; 235 deUint32 location; 236 237 AttribLocationBinding (void) : location(0) {} 238 AttribLocationBinding (const std::string& name_, deUint32 location_) : name(name_), location(location_) {} 239 }; 240 241 struct TransformFeedbackMode 242 { 243 deUint32 mode; 244 245 TransformFeedbackMode (void) : mode(0) {} 246 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {} 247 }; 248 249 struct TransformFeedbackVarying 250 { 251 std::string name; 252 253 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {} 254 }; 255 256 struct ProgramSeparable 257 { 258 bool separable; 259 explicit ProgramSeparable (bool separable_) : separable(separable_) {} 260 }; 261 262 template<typename Iterator> 263 struct TransformFeedbackVaryings 264 { 265 Iterator begin; 266 Iterator end; 267 268 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {} 269 }; 270 271 struct ShaderSource 272 { 273 ShaderType shaderType; 274 std::string source; 275 276 ShaderSource (void) : shaderType(SHADERTYPE_LAST) {} 277 ShaderSource (glu::ShaderType shaderType_, const std::string& source_) : shaderType(shaderType_), source(source_) { DE_ASSERT(!source_.empty()); } 278 }; 279 280 struct VertexSource : public ShaderSource 281 { 282 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {} 283 }; 284 285 struct FragmentSource : public ShaderSource 286 { 287 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {} 288 }; 289 290 struct GeometrySource : public ShaderSource 291 { 292 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {} 293 }; 294 295 struct ComputeSource : public ShaderSource 296 { 297 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {} 298 }; 299 300 struct TessellationControlSource : public ShaderSource 301 { 302 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {} 303 }; 304 305 struct TessellationEvaluationSource : public ShaderSource 306 { 307 TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {} 308 }; 309 310 struct ProgramSources 311 { 312 std::vector<std::string> sources[SHADERTYPE_LAST]; 313 std::vector<AttribLocationBinding> attribLocationBindings; 314 315 deUint32 transformFeedbackBufferMode; //!< TF buffer mode, or GL_NONE. 316 std::vector<std::string> transformFeedbackVaryings; 317 bool separable; 318 319 ProgramSources (void) : transformFeedbackBufferMode(0), separable(false) {} 320 321 ProgramSources& operator<< (const AttribLocationBinding& binding) { attribLocationBindings.push_back(binding); return *this; } 322 ProgramSources& operator<< (const TransformFeedbackMode& mode) { transformFeedbackBufferMode = mode.mode; return *this; } 323 ProgramSources& operator<< (const TransformFeedbackVarying& varying) { transformFeedbackVaryings.push_back(varying.name); return *this; } 324 ProgramSources& operator<< (const ShaderSource& shaderSource) { sources[shaderSource.shaderType].push_back(shaderSource.source); return *this; } 325 ProgramSources& operator<< (const ProgramSeparable& progSeparable) { separable = progSeparable.separable; return *this; } 326 327 template<typename Iterator> 328 ProgramSources& operator<< (const TransformFeedbackVaryings<Iterator>& varyings); 329 }; 330 331 struct SpecializationData 332 { 333 deUint32 index; 334 deUint32 value; 335 336 SpecializationData (void) : index(0), value(0) {} 337 SpecializationData (const deUint32 index_, const deUint32 value_) : index(index_), value(value_) {} 338 }; 339 340 struct ShaderBinary 341 { 342 ShaderBinaryDataType binary; 343 std::vector<ShaderType> shaderTypes; 344 std::vector<std::string> shaderEntryPoints; 345 std::vector<deUint32> specializationIndices; 346 std::vector<deUint32> specializationValues; 347 348 ShaderBinary (void) {} 349 ShaderBinary (const ShaderBinaryDataType binary_) : binary(binary_) 350 { 351 DE_ASSERT(!binary_.empty()); 352 } 353 ShaderBinary (const ShaderBinaryDataType binary_, glu::ShaderType shaderType_) : binary(binary_) 354 { 355 DE_ASSERT(!binary_.empty()); 356 shaderTypes.push_back(shaderType_); 357 shaderEntryPoints.push_back("main"); 358 } 359 360 ShaderBinary& operator<< (const ShaderType& shaderType) 361 { 362 shaderTypes.push_back(shaderType); 363 return *this; 364 } 365 366 ShaderBinary& operator<< (const std::string& entryPoint) 367 { 368 shaderEntryPoints.push_back(entryPoint); 369 return *this; 370 } 371 372 ShaderBinary& operator<< (const SpecializationData& specData) 373 { 374 specializationIndices.push_back(specData.index); 375 specializationValues.push_back(specData.value); 376 return *this; 377 } 378 }; 379 380 struct VertexBinary : public ShaderBinary 381 { 382 VertexBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_VERTEX) {} 383 }; 384 385 struct FragmentBinary : public ShaderBinary 386 { 387 FragmentBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_FRAGMENT) {} 388 }; 389 390 struct GeometryBinary : public ShaderBinary 391 { 392 GeometryBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_GEOMETRY) {} 393 }; 394 395 struct ComputeBinary : public ShaderBinary 396 { 397 ComputeBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_COMPUTE) {} 398 }; 399 400 struct TessellationControlBinary : public ShaderBinary 401 { 402 TessellationControlBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_CONTROL) {} 403 }; 404 405 struct TessellationEvaluationBinary : public ShaderBinary 406 { 407 TessellationEvaluationBinary (const ShaderBinaryDataType binary_) : ShaderBinary(binary_, glu::SHADERTYPE_TESSELLATION_EVALUATION) {} 408 }; 409 410 struct ProgramBinaries 411 { 412 std::vector<ShaderBinary> binaries; 413 414 glw::GLenum binaryFormat; 415 416 ProgramBinaries (void) : binaryFormat(GL_SHADER_BINARY_FORMAT_SPIR_V_ARB) {} 417 ProgramBinaries (glw::GLenum binaryFormat_) : binaryFormat(binaryFormat_) {} 418 419 ProgramBinaries& operator<< (const ShaderBinary& shaderBinary) { binaries.push_back(shaderBinary); return *this; } 420 }; 421 422 template<typename Iterator> 423 inline ProgramSources& ProgramSources::operator<< (const TransformFeedbackVaryings<Iterator>& varyings) 424 { 425 for (Iterator cur = varyings.begin; cur != varyings.end; ++cur) 426 transformFeedbackVaryings.push_back(*cur); 427 return *this; 428 } 429 430 //! Helper for constructing vertex-fragment source pair. 431 inline ProgramSources makeVtxFragSources (const std::string& vertexSrc, const std::string& fragmentSrc) 432 { 433 ProgramSources sources; 434 sources.sources[SHADERTYPE_VERTEX].push_back(vertexSrc); 435 sources.sources[SHADERTYPE_FRAGMENT].push_back(fragmentSrc); 436 return sources; 437 } 438 439 } // glu 440 441 #endif // _GLUSHADERPROGRAM_HPP 442