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