1 #ifndef _RRSHADERS_HPP
2 #define _RRSHADERS_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Reference Renderer
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 interfaces.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "rrDefs.hpp"
27 #include "rrVertexAttrib.hpp"
28 #include "rrVertexPacket.hpp"
29 #include "rrFragmentPacket.hpp"
30 #include "rrPrimitivePacket.hpp"
31 #include "rrShadingContext.hpp"
32 #include "deString.h"
33 
34 namespace rr
35 {
36 
37 /*--------------------------------------------------------------------*//*!
38  * \brief Vertex shader input information
39  *//*--------------------------------------------------------------------*/
40 struct VertexInputInfo
41 {
VertexInputInforr::VertexInputInfo42 	VertexInputInfo (void)
43 	{
44 		// sensible defaults
45 		type = GENERICVECTYPE_LAST;
46 	}
47 
48 	GenericVecType	type;
49 };
50 
51 /*--------------------------------------------------------------------*//*!
52  * \brief Shader varying information
53  *//*--------------------------------------------------------------------*/
54 struct VertexVaryingInfo
55 {
VertexVaryingInforr::VertexVaryingInfo56 	VertexVaryingInfo (void)
57 	{
58 		// sensible defaults
59 		type		= GENERICVECTYPE_LAST;
60 		flatshade	= false;
61 	}
62 
63 	// \note used by std::vector<T>::operator==() const
operator ==rr::VertexVaryingInfo64 	bool operator== (const VertexVaryingInfo& other) const
65 	{
66 		return	type == other.type &&
67 				flatshade == other.flatshade;
68 	}
69 
70 	GenericVecType	type;
71 	bool			flatshade;
72 };
73 
74 typedef VertexVaryingInfo VertexOutputInfo;
75 typedef VertexVaryingInfo FragmentInputInfo;
76 typedef VertexVaryingInfo GeometryInputInfo;
77 typedef VertexVaryingInfo GeometryOutputInfo;
78 
79 /*--------------------------------------------------------------------*//*!
80  * \brief Fragment shader output information
81  *//*--------------------------------------------------------------------*/
82 struct FragmentOutputInfo
83 {
FragmentOutputInforr::FragmentOutputInfo84 	FragmentOutputInfo (void)
85 	{
86 		// sensible defaults
87 		type = GENERICVECTYPE_LAST;
88 	}
89 
90 	GenericVecType type;
91 };
92 
93 /*--------------------------------------------------------------------*//*!
94  * \brief Vertex shader interface
95  *
96  * Vertex shaders execute shading for set of vertex packets. See VertexPacket
97  * documentation for more details on shading API.
98  *//*--------------------------------------------------------------------*/
99 class VertexShader
100 {
101 public:
VertexShader(size_t numInputs,size_t numOutputs)102 											VertexShader		(size_t numInputs, size_t numOutputs) : m_inputs(numInputs), m_outputs(numOutputs) {}
103 
104 	virtual void							shadeVertices		(const VertexAttrib* inputs, VertexPacket* const* packets, const int numPackets) const = 0;
105 
getInputs() const106 	const std::vector<VertexInputInfo>&		getInputs() const	{ return m_inputs; }
getOutputs() const107 	const std::vector<VertexOutputInfo>&	getOutputs() const	{ return m_outputs; }
108 
109 protected:
~VertexShader()110 											~VertexShader() {}; // \note Renderer will not delete any objects passed in.
111 
112 	std::vector<VertexInputInfo>			m_inputs;
113 	std::vector<VertexOutputInfo>			m_outputs;
114 } DE_WARN_UNUSED_TYPE;
115 
116 /*--------------------------------------------------------------------*//*!
117  * \brief Fragment shader interface
118  *
119  * Fragment shader executes shading for list of fragment packets. See
120  * FragmentPacket documentation for more details on shading API.
121  *//*--------------------------------------------------------------------*/
122 class FragmentShader
123 {
124 public:
FragmentShader(size_t numInputs,size_t numOutputs)125 											FragmentShader		(size_t numInputs, size_t numOutputs) : m_inputs(numInputs), m_outputs(numOutputs) {}
126 
getInputs() const127 	const std::vector<FragmentInputInfo>&	getInputs() const	{ return m_inputs; }
getOutputs() const128 	const std::vector<FragmentOutputInfo>&	getOutputs() const	{ return m_outputs; }
129 
130 	virtual void							shadeFragments		(FragmentPacket* packets, const int numPackets, const FragmentShadingContext& context) const = 0; // \note numPackets must be greater than zero.
131 
132 protected:
~FragmentShader()133 											~FragmentShader() {}; // \note Renderer will not delete any objects passed in.
134 
135 	std::vector<FragmentInputInfo>			m_inputs;
136 	std::vector<FragmentOutputInfo>			m_outputs;
137 } DE_WARN_UNUSED_TYPE;
138 
139 /*--------------------------------------------------------------------*//*!
140  * \brief Geometry shader input primitive type
141  *//*--------------------------------------------------------------------*/
142 enum GeometryShaderInputType
143 {
144 	GEOMETRYSHADERINPUTTYPE_POINTS = 0,
145 	GEOMETRYSHADERINPUTTYPE_LINES,
146 	GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY,
147 	GEOMETRYSHADERINPUTTYPE_TRIANGLES,
148 	GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY,
149 
150 	GEOMETRYSHADERINPUTTYPE_LAST
151 };
152 
153 /*--------------------------------------------------------------------*//*!
154  * \brief Geometry shader output primitive type
155  *//*--------------------------------------------------------------------*/
156 enum GeometryShaderOutputType
157 {
158 	GEOMETRYSHADEROUTPUTTYPE_POINTS = 0,
159 	GEOMETRYSHADEROUTPUTTYPE_LINE_STRIP,
160 	GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP,
161 
162 	GEOMETRYSHADEROUTPUTTYPE_LAST
163 };
164 
165 /*--------------------------------------------------------------------*//*!
166  * \brief Geometry shader interface
167  *
168  * Geometry shader executes a list of primitive packets and outputs
169  * a new set of vertex packets for new primitives.
170  *//*--------------------------------------------------------------------*/
171 class GeometryShader
172 {
173 public:
174 											GeometryShader		(size_t numVaryingInputs,
175 																 size_t numVaryingOutputs,
176 																 GeometryShaderInputType inputType,
177 																 GeometryShaderOutputType outputType,
178 																 size_t numVerticesOut,
179 																 size_t numInvocations);
180 
181 	virtual void							shadePrimitives		(GeometryEmitter& output, int verticesIn, const PrimitivePacket* packets, const int numPackets, int invocationID) const = 0;
182 
getInputs(void) const183 	const std::vector<GeometryInputInfo>&	getInputs			(void) const { return m_inputs; }
getOutputs(void) const184 	const std::vector<GeometryOutputInfo>&	getOutputs			(void) const { return m_outputs; }
getInputType(void) const185 	inline GeometryShaderInputType			getInputType		(void) const { return m_inputType; }
getOutputType(void) const186 	inline GeometryShaderOutputType			getOutputType		(void) const { return m_outputType; }
getNumVerticesOut(void) const187 	inline size_t							getNumVerticesOut	(void) const { return m_numVerticesOut; }
getNumInvocations(void) const188 	inline size_t							getNumInvocations	(void) const { return m_numInvocations; }
189 
190 protected:
191 	const GeometryShaderInputType			m_inputType;
192 	const GeometryShaderOutputType			m_outputType;
193 	const size_t							m_numVerticesOut;
194 	const size_t							m_numInvocations;
195 
196 	std::vector<GeometryInputInfo>			m_inputs;
197 	std::vector<GeometryOutputInfo>			m_outputs;
198 } DE_WARN_UNUSED_TYPE;
199 
200 // Helpers for shader implementations.
201 
202 template<class Shader>
203 class VertexShaderLoop : public VertexShader
204 {
205 public:
VertexShaderLoop(const Shader & shader)206 					VertexShaderLoop	(const Shader& shader) : m_shader(shader) {}
207 
208 	void			shadeVertices		(const VertexAttrib* inputs, VertexPacket* packets, const int numPackets) const;
209 
210 private:
211 	const Shader&	m_shader;
212 };
213 
214 template<class Shader>
shadeVertices(const VertexAttrib * inputs,VertexPacket * packets,const int numPackets) const215 void VertexShaderLoop<Shader>::shadeVertices (const VertexAttrib* inputs, VertexPacket* packets, const int numPackets) const
216 {
217 	for (int ndx = 0; ndx < numPackets; ndx++)
218 		m_shader.shadeVertex(inputs, packets[ndx]);
219 }
220 
221 template<class Shader>
222 class FragmentShaderLoop : public FragmentShader
223 {
224 public:
FragmentShaderLoop(const Shader & shader)225 					FragmentShaderLoop	(const Shader& shader) : m_shader(shader) {}
226 
227 	void			shadeFragments		(FragmentPacket* packets, const int numPackets) const;
228 
229 private:
230 	const Shader&	m_shader;
231 };
232 
233 template<class Shader>
shadeFragments(FragmentPacket * packets,const int numPackets) const234 void FragmentShaderLoop<Shader>::shadeFragments (FragmentPacket* packets, const int numPackets) const
235 {
236 	for (int ndx = 0; ndx < numPackets; ndx++)
237 		m_shader.shadeFragment(packets[ndx]);
238 }
239 
240 } // rr
241 
242 #endif // _RRSHADERS_HPP
243