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
33namespace sglr
34{
35
36namespace rc
37{
38class Texture1D;
39class Texture2D;
40class TextureCube;
41class Texture2DArray;
42class Texture3D;
43class TextureCubeArray;
44} // rc
45
46class ShaderProgram;
47
48namespace pdec
49{
50
51enum VaryingFlags
52{
53	VARYINGFLAG_NONE		= 0,
54	VARYINGFLAG_FLATSHADE	= (1 << 0),
55};
56
57struct 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
65struct 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
73struct 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
81struct 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
89struct FragmentOutput
90{
91						FragmentOutput				(rr::GenericVecType type_) : type(type_) { }
92
93	rr::GenericVecType	type;
94};
95
96struct 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
104struct VertexSource
105{
106						VertexSource				(const std::string& str) : source(str) { }
107
108	std::string			source;
109};
110
111struct FragmentSource
112{
113						FragmentSource				(const std::string& str) : source(str) { }
114
115	std::string			source;
116};
117
118struct GeometrySource
119{
120						GeometrySource				(const std::string& str) : source(str) { }
121
122	std::string			source;
123};
124
125struct 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
144class ShaderProgramDeclaration
145{
146public:
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
160private:
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
191struct 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
226class ShaderProgram : private rr::VertexShader, private rr::GeometryShader, private rr::FragmentShader
227{
228public:
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
238private:
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;
244protected:
245	std::vector<UniformSlot>				m_uniforms;
246
247private:
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};
256
257} // sglr
258
259#endif // _SGLRSHADERPROGRAM_HPP
260