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 "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