Home | History | Annotate | Download | only in opengl
      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