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 {
VertexAttributesglr::pdec::VertexAttribute59 						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 {
VertexToFragmentVaryingsglr::pdec::VertexToFragmentVarying67 						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 {
VertexToGeometryVaryingsglr::pdec::VertexToGeometryVarying75 						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 {
GeometryToFragmentVaryingsglr::pdec::GeometryToFragmentVarying83 						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 {
FragmentOutputsglr::pdec::FragmentOutput91 						FragmentOutput				(rr::GenericVecType type_) : type(type_) { }
92 
93 	rr::GenericVecType	type;
94 };
95 
96 struct Uniform
97 {
Uniformsglr::pdec::Uniform98 						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 {
VertexSourcesglr::pdec::VertexSource106 						VertexSource				(const std::string& str) : source(str) { }
107 
108 	std::string			source;
109 };
110 
111 struct FragmentSource
112 {
FragmentSourcesglr::pdec::FragmentSource113 						FragmentSource				(const std::string& str) : source(str) { }
114 
115 	std::string			source;
116 };
117 
118 struct GeometrySource
119 {
GeometrySourcesglr::pdec::GeometrySource120 						GeometrySource				(const std::string& str) : source(str) { }
121 
122 	std::string			source;
123 };
124 
125 struct GeometryShaderDeclaration
126 {
GeometryShaderDeclarationsglr::pdec::GeometryShaderDeclaration127 									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:
hasGeometryShader(void) const161 	inline bool								hasGeometryShader				(void) const							{ return m_geometryShaderSet; }
getVertexInputCount(void) const162 	inline size_t							getVertexInputCount				(void) const							{ return m_vertexAttributes.size(); }
getVertexOutputCount(void) const163 	inline size_t							getVertexOutputCount			(void) const							{ return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : m_vertexToFragmentVaryings.size(); }
getFragmentInputCount(void) const164 	inline size_t							getFragmentInputCount			(void) const							{ return hasGeometryShader() ? m_geometryToFragmentVaryings.size() : m_vertexToFragmentVaryings.size(); }
getFragmentOutputCount(void) const165 	inline size_t							getFragmentOutputCount			(void) const							{ return m_fragmentOutputs.size(); }
getGeometryInputCount(void) const166 	inline size_t							getGeometryInputCount			(void) const							{ return hasGeometryShader() ? m_vertexToGeometryVaryings.size() : 0; }
getGeometryOutputCount(void) const167 	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 
UniformSlotsglr::UniformSlot218 	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 
getVertexShader(void) const234 	inline const rr::VertexShader*			getVertexShader		(void) const { return static_cast<const rr::VertexShader*>(this);   }
getFragmentShader(void) const235 	inline const rr::FragmentShader*		getFragmentShader	(void) const { return static_cast<const rr::FragmentShader*>(this); }
getGeometryShader(void) const236 	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