Home | History | Annotate | Download | only in simplereference
      1 #ifndef _SGLRSHADERPROGRAM_HPP
      2 #define _SGLRSHADERPROGRAM_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 SGLR shader program.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "rrShaders.hpp"
     28 #include "gluShaderUtil.hpp"
     29 
     30 #include <vector>
     31 #include <string>
     32 
     33 namespace sglr
     34 {
     35 
     36 namespace rc
     37 {
     38 class Texture1D;
     39 class Texture2D;
     40 class TextureCube;
     41 class Texture2DArray;
     42 class Texture3D;
     43 class TextureCubeArray;
     44 } // rc
     45 
     46 class ShaderProgram;
     47 
     48 namespace pdec
     49 {
     50 
     51 enum VaryingFlags
     52 {
     53 	VARYINGFLAG_NONE		= 0,
     54 	VARYINGFLAG_FLATSHADE	= (1 << 0),
     55 };
     56 
     57 struct VertexAttribute
     58 {
     59 						VertexAttribute				(const std::string& name_, rr::GenericVecType type_) : name(name_), type(type_) { }
     60 
     61 	std::string			name;
     62 	rr::GenericVecType	type;
     63 };
     64 
     65 struct VertexToFragmentVarying
     66 {
     67 						VertexToFragmentVarying		(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { }
     68 
     69 	rr::GenericVecType	type;
     70 	bool				flatshade;
     71 };
     72 
     73 struct VertexToGeometryVarying
     74 {
     75 						VertexToGeometryVarying		(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { }
     76 
     77 	rr::GenericVecType	type;
     78 	bool				flatshade;
     79 };
     80 
     81 struct GeometryToFragmentVarying
     82 {
     83 						GeometryToFragmentVarying	(rr::GenericVecType type_, int flags = VARYINGFLAG_NONE) : type(type_), flatshade((flags & VARYINGFLAG_FLATSHADE) != 0) { }
     84 
     85 	rr::GenericVecType	type;
     86 	bool				flatshade;
     87 };
     88 
     89 struct FragmentOutput
     90 {
     91 						FragmentOutput				(rr::GenericVecType type_) : type(type_) { }
     92 
     93 	rr::GenericVecType	type;
     94 };
     95 
     96 struct Uniform
     97 {
     98 						Uniform						(const std::string& name_, glu::DataType type_) : name(name_), type(type_) { }
     99 
    100 	std::string			name;
    101 	glu::DataType		type;
    102 };
    103 
    104 struct VertexSource
    105 {
    106 						VertexSource				(const std::string& str) : source(str) { }
    107 
    108 	std::string			source;
    109 };
    110 
    111 struct FragmentSource
    112 {
    113 						FragmentSource				(const std::string& str) : source(str) { }
    114 
    115 	std::string			source;
    116 };
    117 
    118 struct GeometrySource
    119 {
    120 						GeometrySource				(const std::string& str) : source(str) { }
    121 
    122 	std::string			source;
    123 };
    124 
    125 struct GeometryShaderDeclaration
    126 {
    127 									GeometryShaderDeclaration	(rr::GeometryShaderInputType inputType_,
    128 																 rr::GeometryShaderOutputType outputType_,
    129 																 size_t numOutputVertices_,
    130 																 size_t numInvocations_ = 1)
    131 									: inputType			(inputType_)
    132 									, outputType		(outputType_)
    133 									, numOutputVertices	(numOutputVertices_)
    134 									, numInvocations	(numInvocations_)
    135 									{
    136 									}
    137 
    138 	rr::GeometryShaderInputType		inputType;
    139 	rr::GeometryShaderOutputType	outputType;
    140 	size_t							numOutputVertices;
    141 	size_t							numInvocations;
    142 };
    143 
    144 class ShaderProgramDeclaration
    145 {
    146 public:
    147 											ShaderProgramDeclaration		(void);
    148 
    149 	ShaderProgramDeclaration&				operator<<						(const VertexAttribute&);
    150 	ShaderProgramDeclaration&				operator<<						(const VertexToFragmentVarying&);
    151 	ShaderProgramDeclaration&				operator<<						(const VertexToGeometryVarying&);
    152 	ShaderProgramDeclaration&				operator<<						(const GeometryToFragmentVarying&);
    153 	ShaderProgramDeclaration&				operator<<						(const FragmentOutput&);
    154 	ShaderProgramDeclaration&				operator<<						(const Uniform&);
    155 	ShaderProgramDeclaration&				operator<<						(const VertexSource&);
    156 	ShaderProgramDeclaration&				operator<<						(const FragmentSource&);
    157 	ShaderProgramDeclaration&				operator<<						(const GeometrySource&);
    158 	ShaderProgramDeclaration&				operator<<						(const GeometryShaderDeclaration&);
    159 
    160 private:
    161 	inline bool								hasGeometryShader				(void) const							{ return m_geometryShaderSet; }
    162 	inline size_t							getVertexInputCount				(void) const							{ return m_vertexAttributes.size(); }
    163 	inline size_t							getVertexOutputCount			(void) const							{ return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : m_vertexToFragmentVaryings.size(); }
    164 	inline size_t							getFragmentInputCount			(void) const							{ return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : m_vertexToFragmentVaryings.size(); }
    165 	inline size_t							getFragmentOutputCount			(void) const							{ return m_fragmentOutputs.size(); }
    166 	inline size_t							getGeometryInputCount			(void) const							{ return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : 0; }
    167 	inline size_t							getGeometryOutputCount			(void) const							{ return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : 0; }
    168 
    169 	bool									valid							(void) const;
    170 
    171 	std::vector<VertexAttribute>			m_vertexAttributes;
    172 	std::vector<VertexToFragmentVarying>	m_vertexToFragmentVaryings;
    173 	std::vector<VertexToGeometryVarying>	m_vertexToGeometryVaryings;
    174 	std::vector<GeometryToFragmentVarying>	m_geometryToFragmentVaryings;
    175 	std::vector<FragmentOutput>				m_fragmentOutputs;
    176 	std::vector<Uniform>					m_uniforms;
    177 	std::string								m_vertexSource;
    178 	std::string								m_fragmentSource;
    179 	std::string								m_geometrySource;
    180 	GeometryShaderDeclaration				m_geometryDecl;
    181 
    182 	bool									m_vertexShaderSet;
    183 	bool									m_fragmentShaderSet;
    184 	bool									m_geometryShaderSet;
    185 
    186 	friend class ::sglr::ShaderProgram;
    187 };
    188 
    189 } // pdec
    190 
    191 struct UniformSlot
    192 {
    193 	std::string		name;
    194 	glu::DataType	type;
    195 
    196 	union
    197 	{
    198 		deInt32		i;
    199 		deInt32		i4[4];
    200 		float		f;
    201 		float		f4[4];
    202 		float		m3[3*3];	//!< row major, can be fed directly to tcu::Matrix constructor
    203 		float		m4[4*4];	//!< row major, can be fed directly to tcu::Matrix constructor
    204 	} value;
    205 
    206 	union
    207 	{
    208 		const void*					ptr;
    209 
    210 		const rc::Texture1D*		tex1D;
    211 		const rc::Texture2D*		tex2D;
    212 		const rc::TextureCube*		texCube;
    213 		const rc::Texture2DArray*	tex2DArray;
    214 		const rc::Texture3D*		tex3D;
    215 		const rc::TextureCubeArray*	texCubeArray;
    216 	} sampler;
    217 
    218 	inline UniformSlot (void)
    219 		: type(glu::TYPE_LAST)
    220 	{
    221 		value.i = 0;
    222 		sampler.ptr = DE_NULL;
    223 	}
    224 };
    225 
    226 class ShaderProgram : private rr::VertexShader, private rr::GeometryShader, private rr::FragmentShader
    227 {
    228 public:
    229 											ShaderProgram		(const pdec::ShaderProgramDeclaration&);
    230 	virtual									~ShaderProgram		(void);
    231 
    232 	const UniformSlot&						getUniformByName	(const char* name) const;
    233 
    234 	inline const rr::VertexShader*			getVertexShader		(void) const { return static_cast<const rr::VertexShader*>(this);   }
    235 	inline const rr::FragmentShader*		getFragmentShader	(void) const { return static_cast<const rr::FragmentShader*>(this); }
    236 	inline const rr::GeometryShader*		getGeometryShader	(void) const { return static_cast<const rr::GeometryShader*>(this); }
    237 
    238 private:
    239 	virtual void							shadeVertices		(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const = 0;
    240 	virtual void							shadeFragments		(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const = 0;
    241 	virtual void							shadePrimitives		(rr::GeometryEmitter& output, int verticesIn, const rr::PrimitivePacket* packets, const int numPackets, int invocationID) const;
    242 
    243 	std::vector<std::string>				m_attributeNames;
    244 protected:
    245 	std::vector<UniformSlot>				m_uniforms;
    246 
    247 private:
    248 	const std::string						m_vertSrc;
    249 	const std::string						m_fragSrc;
    250 	const std::string						m_geomSrc;
    251 	const bool								m_hasGeometryShader;
    252 
    253 	friend class ReferenceContext;	// for uniform access
    254 	friend class GLContext;			// for source string access
    255 } DE_WARN_UNUSED_TYPE;
    256 
    257 } // sglr
    258 
    259 #endif // _SGLRSHADERPROGRAM_HPP
    260