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