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 33namespace tcu 34{ 35class TestLog; 36} 37 38namespace glu 39{ 40 41class RenderContext; 42 43/*--------------------------------------------------------------------*//*! 44 * \brief Shader information (compile status, log, etc.). 45 *//*--------------------------------------------------------------------*/ 46struct 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 *//*--------------------------------------------------------------------*/ 60struct 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 *//*--------------------------------------------------------------------*/ 72struct ShaderProgramInfo 73{ 74 glu::ProgramInfo program; 75 std::vector<glu::ShaderInfo> shaders; 76}; 77 78/*--------------------------------------------------------------------*//*! 79 * \brief Shader object. 80 *//*--------------------------------------------------------------------*/ 81class Shader 82{ 83public: 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 101private: 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 *//*--------------------------------------------------------------------*/ 113class Program 114{ 115public: 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 142private: 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 *//*--------------------------------------------------------------------*/ 155class ProgramPipeline 156{ 157public: 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 167private: 168 ProgramPipeline (const ProgramPipeline& other); 169 ProgramPipeline& operator= (const ProgramPipeline& other); 170 171 const glw::Functions& m_gl; 172 deUint32 m_pipeline; 173}; 174 175struct 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 *//*--------------------------------------------------------------------*/ 183class ShaderProgram 184{ 185public: 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 198private: 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 209deUint32 getGLShaderType (ShaderType shaderType); 210deUint32 getGLShaderTypeBit (ShaderType shaderType); 211qpShaderType getLogShaderType (ShaderType shaderType); 212 213tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderInfo& shaderInfo); 214tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgramInfo& shaderProgramInfo); 215tcu::TestLog& operator<< (tcu::TestLog& log, const ProgramSources& sources); 216tcu::TestLog& operator<< (tcu::TestLog& log, const Shader& shader); 217tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderProgram& program); 218 219// ProgramSources utilities and implementation. 220 221struct 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 230struct TransformFeedbackMode 231{ 232 deUint32 mode; 233 234 TransformFeedbackMode (void) : mode(0) {} 235 TransformFeedbackMode (deUint32 mode_) : mode(mode_) {} 236}; 237 238struct TransformFeedbackVarying 239{ 240 std::string name; 241 242 explicit TransformFeedbackVarying (const std::string& name_) : name(name_) {} 243}; 244 245struct ProgramSeparable 246{ 247 bool separable; 248 explicit ProgramSeparable (bool separable_) : separable(separable_) {} 249}; 250 251template<typename Iterator> 252struct TransformFeedbackVaryings 253{ 254 Iterator begin; 255 Iterator end; 256 257 TransformFeedbackVaryings (Iterator begin_, Iterator end_) : begin(begin_), end(end_) {} 258}; 259 260struct 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 269struct VertexSource : public ShaderSource 270{ 271 VertexSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_VERTEX, source_) {} 272}; 273 274struct FragmentSource : public ShaderSource 275{ 276 FragmentSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_FRAGMENT, source_) {} 277}; 278 279struct GeometrySource : public ShaderSource 280{ 281 GeometrySource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_GEOMETRY, source_) {} 282}; 283 284struct ComputeSource : public ShaderSource 285{ 286 ComputeSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_COMPUTE, source_) {} 287}; 288 289struct TessellationControlSource : public ShaderSource 290{ 291 TessellationControlSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_CONTROL, source_) {} 292}; 293 294struct TessellationEvaluationSource : public ShaderSource 295{ 296 TessellationEvaluationSource (const std::string& source_) : ShaderSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, source_) {} 297}; 298 299struct 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 320template<typename Iterator> 321inline 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. 329inline 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