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 && flatshade == other.flatshade;
67 }
68
69 GenericVecType type;
70 bool flatshade;
71 };
72
73 typedef VertexVaryingInfo VertexOutputInfo;
74 typedef VertexVaryingInfo FragmentInputInfo;
75 typedef VertexVaryingInfo GeometryInputInfo;
76 typedef VertexVaryingInfo GeometryOutputInfo;
77
78 /*--------------------------------------------------------------------*//*!
79 * \brief Fragment shader output information
80 *//*--------------------------------------------------------------------*/
81 struct FragmentOutputInfo
82 {
FragmentOutputInforr::FragmentOutputInfo83 FragmentOutputInfo(void)
84 {
85 // sensible defaults
86 type = GENERICVECTYPE_LAST;
87 }
88
89 GenericVecType type;
90 };
91
92 /*--------------------------------------------------------------------*//*!
93 * \brief Vertex shader interface
94 *
95 * Vertex shaders execute shading for set of vertex packets. See VertexPacket
96 * documentation for more details on shading API.
97 *//*--------------------------------------------------------------------*/
98 class VertexShader
99 {
100 public:
VertexShader(size_t numInputs,size_t numOutputs)101 VertexShader(size_t numInputs, size_t numOutputs) : m_inputs(numInputs), m_outputs(numOutputs)
102 {
103 }
104
105 virtual void shadeVertices(const VertexAttrib *inputs, VertexPacket *const *packets,
106 const int numPackets) const = 0;
107
getInputs(void) const108 const std::vector<VertexInputInfo> &getInputs(void) const
109 {
110 return m_inputs;
111 }
getOutputs(void) const112 const std::vector<VertexOutputInfo> &getOutputs(void) const
113 {
114 return m_outputs;
115 }
116
117 protected:
~VertexShader(void)118 virtual ~VertexShader(void)
119 {
120 } // \note Renderer will not delete any objects passed in.
121
122 std::vector<VertexInputInfo> m_inputs;
123 std::vector<VertexOutputInfo> m_outputs;
124 } DE_WARN_UNUSED_TYPE;
125
126 /*--------------------------------------------------------------------*//*!
127 * \brief Fragment shader interface
128 *
129 * Fragment shader executes shading for list of fragment packets. See
130 * FragmentPacket documentation for more details on shading API.
131 *//*--------------------------------------------------------------------*/
132 class FragmentShader
133 {
134 public:
FragmentShader(size_t numInputs,size_t numOutputs)135 FragmentShader(size_t numInputs, size_t numOutputs) : m_inputs(numInputs), m_outputs(numOutputs)
136 {
137 }
138
getInputs(void) const139 const std::vector<FragmentInputInfo> &getInputs(void) const
140 {
141 return m_inputs;
142 }
getOutputs(void) const143 const std::vector<FragmentOutputInfo> &getOutputs(void) const
144 {
145 return m_outputs;
146 }
147
148 virtual void shadeFragments(FragmentPacket *packets, const int numPackets, const FragmentShadingContext &context)
149 const = 0; // \note numPackets must be greater than zero.
150
151 protected:
~FragmentShader(void)152 virtual ~FragmentShader(void)
153 {
154 } // \note Renderer will not delete any objects passed in.
155
156 std::vector<FragmentInputInfo> m_inputs;
157 std::vector<FragmentOutputInfo> m_outputs;
158 } DE_WARN_UNUSED_TYPE;
159
160 /*--------------------------------------------------------------------*//*!
161 * \brief Geometry shader input primitive type
162 *//*--------------------------------------------------------------------*/
163 enum GeometryShaderInputType
164 {
165 GEOMETRYSHADERINPUTTYPE_POINTS = 0,
166 GEOMETRYSHADERINPUTTYPE_LINES,
167 GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY,
168 GEOMETRYSHADERINPUTTYPE_TRIANGLES,
169 GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY,
170
171 GEOMETRYSHADERINPUTTYPE_LAST
172 };
173
174 /*--------------------------------------------------------------------*//*!
175 * \brief Geometry shader output primitive type
176 *//*--------------------------------------------------------------------*/
177 enum GeometryShaderOutputType
178 {
179 GEOMETRYSHADEROUTPUTTYPE_POINTS = 0,
180 GEOMETRYSHADEROUTPUTTYPE_LINE_STRIP,
181 GEOMETRYSHADEROUTPUTTYPE_TRIANGLE_STRIP,
182
183 GEOMETRYSHADEROUTPUTTYPE_LAST
184 };
185
186 /*--------------------------------------------------------------------*//*!
187 * \brief Geometry shader interface
188 *
189 * Geometry shader executes a list of primitive packets and outputs
190 * a new set of vertex packets for new primitives.
191 *//*--------------------------------------------------------------------*/
192 class GeometryShader
193 {
194 public:
195 GeometryShader(size_t numVaryingInputs, size_t numVaryingOutputs, GeometryShaderInputType inputType,
196 GeometryShaderOutputType outputType, size_t numVerticesOut, size_t numInvocations);
197
198 virtual void shadePrimitives(GeometryEmitter &output, int verticesIn, const PrimitivePacket *packets,
199 const int numPackets, int invocationID) const = 0;
200
getInputs(void) const201 const std::vector<GeometryInputInfo> &getInputs(void) const
202 {
203 return m_inputs;
204 }
getOutputs(void) const205 const std::vector<GeometryOutputInfo> &getOutputs(void) const
206 {
207 return m_outputs;
208 }
getInputType(void) const209 inline GeometryShaderInputType getInputType(void) const
210 {
211 return m_inputType;
212 }
getOutputType(void) const213 inline GeometryShaderOutputType getOutputType(void) const
214 {
215 return m_outputType;
216 }
getNumVerticesOut(void) const217 inline size_t getNumVerticesOut(void) const
218 {
219 return m_numVerticesOut;
220 }
getNumInvocations(void) const221 inline size_t getNumInvocations(void) const
222 {
223 return m_numInvocations;
224 }
225
226 protected:
~GeometryShader(void)227 virtual ~GeometryShader(void)
228 {
229 }
230
231 const GeometryShaderInputType m_inputType;
232 const GeometryShaderOutputType m_outputType;
233 const size_t m_numVerticesOut;
234 const size_t m_numInvocations;
235
236 std::vector<GeometryInputInfo> m_inputs;
237 std::vector<GeometryOutputInfo> m_outputs;
238 } DE_WARN_UNUSED_TYPE;
239
240 // Helpers for shader implementations.
241
242 template <class Shader>
243 class VertexShaderLoop : public VertexShader
244 {
245 public:
VertexShaderLoop(const Shader & shader)246 VertexShaderLoop(const Shader &shader) : m_shader(shader)
247 {
248 }
249
250 void shadeVertices(const VertexAttrib *inputs, VertexPacket *packets, const int numPackets) const;
251
252 private:
253 const Shader &m_shader;
254 };
255
256 template <class Shader>
shadeVertices(const VertexAttrib * inputs,VertexPacket * packets,const int numPackets) const257 void VertexShaderLoop<Shader>::shadeVertices(const VertexAttrib *inputs, VertexPacket *packets,
258 const int numPackets) const
259 {
260 for (int ndx = 0; ndx < numPackets; ndx++)
261 m_shader.shadeVertex(inputs, packets[ndx]);
262 }
263
264 template <class Shader>
265 class FragmentShaderLoop : public FragmentShader
266 {
267 public:
FragmentShaderLoop(const Shader & shader)268 FragmentShaderLoop(const Shader &shader) : m_shader(shader)
269 {
270 }
271
272 void shadeFragments(FragmentPacket *packets, const int numPackets) const;
273
274 private:
275 const Shader &m_shader;
276 };
277
278 template <class Shader>
shadeFragments(FragmentPacket * packets,const int numPackets) const279 void FragmentShaderLoop<Shader>::shadeFragments(FragmentPacket *packets, const int numPackets) const
280 {
281 for (int ndx = 0; ndx < numPackets; ndx++)
282 m_shader.shadeFragment(packets[ndx]);
283 }
284
285 } // namespace rr
286
287 #endif // _RRSHADERS_HPP
288