1 #ifndef _RRRASTERIZER_HPP
2 #define _RRRASTERIZER_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 Reference rasterizer
24 *//*--------------------------------------------------------------------*/
25
26 #include "rrDefs.hpp"
27 #include "tcuVector.hpp"
28 #include "rrRenderState.hpp"
29 #include "rrFragmentPacket.hpp"
30
31 namespace rr
32 {
33
34 //! Rasterizer configuration
35 enum
36 {
37 RASTERIZER_MAX_SAMPLES_PER_FRAGMENT = 16
38 };
39
40 //! Get coverage bit value.
getCoverageBit(int numSamples,int x,int y,int sampleNdx)41 inline uint64_t getCoverageBit(int numSamples, int x, int y, int sampleNdx)
42 {
43 const int numBits = (int)sizeof(uint64_t) * 8;
44 const int maxSamples = numBits / 4;
45 DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
46 DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
47 return 1ull << ((x * 2 + y) * numSamples + sampleNdx);
48 }
49
50 //! Get all sample bits for fragment
getCoverageFragmentSampleBits(int numSamples,int x,int y)51 inline uint64_t getCoverageFragmentSampleBits(int numSamples, int x, int y)
52 {
53 DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
54 const uint64_t fragMask = (1ull << numSamples) - 1;
55 return fragMask << (x * 2 + y) * numSamples;
56 }
57
58 //! Set bit in coverage mask.
setCoverageValue(uint64_t mask,int numSamples,int x,int y,int sampleNdx,bool val)59 inline uint64_t setCoverageValue(uint64_t mask, int numSamples, int x, int y, int sampleNdx, bool val)
60 {
61 const uint64_t bit = getCoverageBit(numSamples, x, y, sampleNdx);
62 return val ? (mask | bit) : (mask & ~bit);
63 }
64
65 //! Get coverage bit value in mask.
getCoverageValue(uint64_t mask,int numSamples,int x,int y,int sampleNdx)66 inline bool getCoverageValue(uint64_t mask, int numSamples, int x, int y, int sampleNdx)
67 {
68 return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
69 }
70
71 //! Test if any sample for fragment is live
getCoverageAnyFragmentSampleLive(uint64_t mask,int numSamples,int x,int y)72 inline bool getCoverageAnyFragmentSampleLive(uint64_t mask, int numSamples, int x, int y)
73 {
74 return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
75 }
76
77 //! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
getCoverageOffset(int numSamples,int x,int y)78 inline int getCoverageOffset(int numSamples, int x, int y)
79 {
80 return (x * 2 + y) * numSamples;
81 }
82
83 /*--------------------------------------------------------------------*//*!
84 * \brief Edge function
85 *
86 * Edge function can be evaluated for point P (in fixed-point coordinates
87 * with SUBPIXEL_BITS fractional part) by computing
88 * D = a*Px + b*Py + c
89 *
90 * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
91 * be fractional part.
92 *
93 * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
94 * with SUBPIXEL_BITS*2 fractional bits.
95 *//*--------------------------------------------------------------------*/
96 struct EdgeFunction
97 {
EdgeFunctionrr::EdgeFunction98 inline EdgeFunction(void) : a(0), b(0), c(0), inclusive(false)
99 {
100 }
101
102 int64_t a;
103 int64_t b;
104 int64_t c;
105 bool inclusive; //!< True if edge is inclusive according to fill rules.
106 };
107
108 /*--------------------------------------------------------------------*//*!
109 * \brief Triangle rasterizer
110 *
111 * Triangle rasterizer implements following features:
112 * - Rasterization using fixed-point coordinates
113 * - 1, 4, and 16 -sample rasterization
114 * - Depth interpolation
115 * - Perspective-correct barycentric computation for interpolation
116 * - Visible face determination
117 *
118 * It does not (and will not) implement following:
119 * - Triangle setup
120 * - Clipping
121 * - Degenerate elimination
122 * - Coordinate transformation (inputs are in screen-space)
123 * - Culling - logic can be implemented outside by querying visible face
124 * - Scissoring (this can be done by controlling viewport rectangle)
125 * - Any per-fragment operations
126 *//*--------------------------------------------------------------------*/
127 class TriangleRasterizer
128 {
129 public:
130 TriangleRasterizer(const tcu::IVec4 &viewport, const int numSamples, const RasterizationState &state,
131 const int suppixelBits);
132
133 void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, const tcu::Vec4 &v2);
134
135 // Following functions are only available after init()
getVisibleFace(void) const136 FaceType getVisibleFace(void) const
137 {
138 return m_face;
139 }
140 void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
141 int &numPacketsRasterized);
142
143 private:
144 void rasterizeSingleSample(FragmentPacket *const fragmentPackets, float *const depthValues,
145 const int maxFragmentPackets, int &numPacketsRasterized);
146
147 template <int NumSamples>
148 void rasterizeMultiSample(FragmentPacket *const fragmentPackets, float *const depthValues,
149 const int maxFragmentPackets, int &numPacketsRasterized);
150
151 // Constant rasterization state.
152 const tcu::IVec4 m_viewport;
153 const int m_numSamples;
154 const Winding m_winding;
155 const HorizontalFill m_horizontalFill;
156 const VerticalFill m_verticalFill;
157 const int m_subpixelBits;
158
159 // Per-triangle rasterization state.
160 tcu::Vec4 m_v0;
161 tcu::Vec4 m_v1;
162 tcu::Vec4 m_v2;
163 EdgeFunction m_edge01;
164 EdgeFunction m_edge12;
165 EdgeFunction m_edge20;
166 FaceType m_face; //!< Triangle orientation, eg. visible face.
167 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
168 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
169 tcu::IVec2 m_curPos; //!< Current rasterization position.
170 ViewportOrientation m_viewportOrientation; //!< Direction of +x+y axis
171 } DE_WARN_UNUSED_TYPE;
172
173 /*--------------------------------------------------------------------*//*!
174 * \brief Single sample line rasterizer
175 *
176 * Line rasterizer implements following features:
177 * - Rasterization using fixed-point coordinates
178 * - Depth interpolation
179 * - Perspective-correct interpolation
180 *
181 * It does not (and will not) implement following:
182 * - Clipping
183 * - Multisampled line rasterization
184 *//*--------------------------------------------------------------------*/
185 class SingleSampleLineRasterizer
186 {
187 public:
188 SingleSampleLineRasterizer(const tcu::IVec4 &viewport, const int subpixelBits);
189 ~SingleSampleLineRasterizer(void);
190
191 void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, float lineWidth, uint32_t stippleFactor,
192 uint16_t stipplePattern);
193
194 // only available after init()
195 void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
196 int &numPacketsRasterized);
197
resetStipple()198 void resetStipple()
199 {
200 m_stippleCounter = 0;
201 }
202
203 private:
204 SingleSampleLineRasterizer(const SingleSampleLineRasterizer &); // not allowed
205 SingleSampleLineRasterizer &operator=(const SingleSampleLineRasterizer &); // not allowed
206
207 // Constant rasterization state.
208 const tcu::IVec4 m_viewport;
209 const int m_subpixelBits;
210
211 // Per-line rasterization state.
212 tcu::Vec4 m_v0;
213 tcu::Vec4 m_v1;
214 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
215 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
216 tcu::IVec2 m_curPos; //!< Current rasterization position.
217 int32_t m_curRowFragment; //!< Current rasterization position of one fragment in column of lineWidth fragments
218 float m_lineWidth;
219 uint32_t m_stippleFactor;
220 uint16_t m_stipplePattern;
221 uint32_t m_stippleCounter;
222 } DE_WARN_UNUSED_TYPE;
223
224 /*--------------------------------------------------------------------*//*!
225 * \brief Multisampled line rasterizer
226 *
227 * Line rasterizer implements following features:
228 * - Rasterization using fixed-point coordinates
229 * - Depth interpolation
230 * - Perspective-correct interpolation
231 *
232 * It does not (and will not) implement following:
233 * - Clipping
234 * - Aliased line rasterization
235 *//*--------------------------------------------------------------------*/
236 class MultiSampleLineRasterizer
237 {
238 public:
239 MultiSampleLineRasterizer(const int numSamples, const tcu::IVec4 &viewport, const int subpixelBits);
240 ~MultiSampleLineRasterizer();
241
242 void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1, float lineWidth);
243
244 // only available after init()
245 void rasterize(FragmentPacket *const fragmentPackets, float *const depthValues, const int maxFragmentPackets,
246 int &numPacketsRasterized);
247
248 private:
249 MultiSampleLineRasterizer(const MultiSampleLineRasterizer &); // not allowed
250 MultiSampleLineRasterizer &operator=(const MultiSampleLineRasterizer &); // not allowed
251
252 // Constant rasterization state.
253 const int m_numSamples;
254
255 // Per-line rasterization state.
256 TriangleRasterizer
257 m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
258 TriangleRasterizer m_triangleRasterizer1;
259 } DE_WARN_UNUSED_TYPE;
260
261 /*--------------------------------------------------------------------*//*!
262 * \brief Pixel diamond
263 *
264 * Structure representing a diamond a line exits.
265 *//*--------------------------------------------------------------------*/
266 struct LineExitDiamond
267 {
268 tcu::IVec2 position;
269 };
270
271 /*--------------------------------------------------------------------*//*!
272 * \brief Line exit diamond generator
273 *
274 * For a given line, generates list of diamonds the line exits using the
275 * line-exit rules of the line rasterization. Does not do scissoring.
276 *
277 * \note Not used by rr, but provided to prevent test cases requiring
278 * accurate diamonds from abusing SingleSampleLineRasterizer.
279 *//*--------------------------------------------------------------------*/
280 class LineExitDiamondGenerator
281 {
282 public:
283 LineExitDiamondGenerator(const int subpixelBits);
284 ~LineExitDiamondGenerator(void);
285
286 void init(const tcu::Vec4 &v0, const tcu::Vec4 &v1);
287
288 // only available after init()
289 void rasterize(LineExitDiamond *const lineDiamonds, const int maxDiamonds, int &numWritten);
290
291 private:
292 LineExitDiamondGenerator(const LineExitDiamondGenerator &); // not allowed
293 LineExitDiamondGenerator &operator=(const LineExitDiamondGenerator &); // not allowed
294
295 const int m_subpixelBits;
296
297 // Per-line rasterization state.
298 tcu::Vec4 m_v0;
299 tcu::Vec4 m_v1;
300 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
301 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
302 tcu::IVec2 m_curPos; //!< Current rasterization position.
303 };
304
305 } // namespace rr
306
307 #endif // _RRRASTERIZER_HPP
308