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_SUBPIXEL_BITS = 8,
39 RASTERIZER_MAX_SAMPLES_PER_FRAGMENT = 16
40 };
41
42 //! Get coverage bit value.
getCoverageBit(int numSamples,int x,int y,int sampleNdx)43 inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx)
44 {
45 const int numBits = (int)sizeof(deUint64)*8;
46 const int maxSamples = numBits/4;
47 DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT);
48 DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
49 return 1ull << ((x*2 + y)*numSamples + sampleNdx);
50 }
51
52 //! Get all sample bits for fragment
getCoverageFragmentSampleBits(int numSamples,int x,int y)53 inline deUint64 getCoverageFragmentSampleBits (int numSamples, int x, int y)
54 {
55 DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2));
56 const deUint64 fragMask = (1ull << numSamples) - 1;
57 return fragMask << (x*2 + y)*numSamples;
58 }
59
60 //! Set bit in coverage mask.
setCoverageValue(deUint64 mask,int numSamples,int x,int y,int sampleNdx,bool val)61 inline deUint64 setCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx, bool val)
62 {
63 const deUint64 bit = getCoverageBit(numSamples, x, y, sampleNdx);
64 return val ? (mask | bit) : (mask & ~bit);
65 }
66
67 //! Get coverage bit value in mask.
getCoverageValue(deUint64 mask,int numSamples,int x,int y,int sampleNdx)68 inline bool getCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx)
69 {
70 return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0;
71 }
72
73 //! Test if any sample for fragment is live
getCoverageAnyFragmentSampleLive(deUint64 mask,int numSamples,int x,int y)74 inline bool getCoverageAnyFragmentSampleLive (deUint64 mask, int numSamples, int x, int y)
75 {
76 return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0;
77 }
78
79 //! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)).
getCoverageOffset(int numSamples,int x,int y)80 inline int getCoverageOffset (int numSamples, int x, int y)
81 {
82 return (x*2 + y)*numSamples;
83 }
84
85 /*--------------------------------------------------------------------*//*!
86 * \brief Edge function
87 *
88 * Edge function can be evaluated for point P (in fixed-point coordinates
89 * with SUBPIXEL_BITS fractional part) by computing
90 * D = a*Px + b*Py + c
91 *
92 * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will
93 * be fractional part.
94 *
95 * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored
96 * with SUBPIXEL_BITS*2 fractional bits.
97 *//*--------------------------------------------------------------------*/
98 struct EdgeFunction
99 {
EdgeFunctionrr::EdgeFunction100 inline EdgeFunction (void) : a(0), b(0), c(0), inclusive(false) {}
101
102 deInt64 a;
103 deInt64 b;
104 deInt64 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
132 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2);
133
134 // Following functions are only available after init()
getVisibleFace(void) const135 FaceType getVisibleFace (void) const { return m_face; }
136 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
137
138 private:
139 void rasterizeSingleSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
140
141 template<int NumSamples>
142 void rasterizeMultiSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
143
144 // Constant rasterization state.
145 const tcu::IVec4 m_viewport;
146 const int m_numSamples;
147 const Winding m_winding;
148 const HorizontalFill m_horizontalFill;
149 const VerticalFill m_verticalFill;
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);
182 ~SingleSampleLineRasterizer (void);
183
184 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
185
186 // only available after init()
187 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
188
189 private:
190 SingleSampleLineRasterizer (const SingleSampleLineRasterizer&); // not allowed
191 SingleSampleLineRasterizer& operator= (const SingleSampleLineRasterizer&); // not allowed
192
193 // Constant rasterization state.
194 const tcu::IVec4 m_viewport;
195
196 // Per-line rasterization state.
197 tcu::Vec4 m_v0;
198 tcu::Vec4 m_v1;
199 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
200 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
201 tcu::IVec2 m_curPos; //!< Current rasterization position.
202 deInt32 m_curRowFragment; //!< Current rasterization position of one fragment in column of lineWidth fragments
203 float m_lineWidth;
204 } DE_WARN_UNUSED_TYPE;
205
206
207 /*--------------------------------------------------------------------*//*!
208 * \brief Multisampled line rasterizer
209 *
210 * Line rasterizer implements following features:
211 * - Rasterization using fixed-point coordinates
212 * - Depth interpolation
213 * - Perspective-correct interpolation
214 *
215 * It does not (and will not) implement following:
216 * - Clipping
217 * - Aliased line rasterization
218 *//*--------------------------------------------------------------------*/
219 class MultiSampleLineRasterizer
220 {
221 public:
222 MultiSampleLineRasterizer (const int numSamples, const tcu::IVec4& viewport);
223 ~MultiSampleLineRasterizer ();
224
225 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
226
227 // only available after init()
228 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
229
230 private:
231 MultiSampleLineRasterizer (const MultiSampleLineRasterizer&); // not allowed
232 MultiSampleLineRasterizer& operator= (const MultiSampleLineRasterizer&); // not allowed
233
234 // Constant rasterization state.
235 const int m_numSamples;
236
237 // Per-line rasterization state.
238 TriangleRasterizer m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
239 TriangleRasterizer m_triangleRasterizer1;
240 } DE_WARN_UNUSED_TYPE;
241
242
243 /*--------------------------------------------------------------------*//*!
244 * \brief Pixel diamond
245 *
246 * Structure representing a diamond a line exits.
247 *//*--------------------------------------------------------------------*/
248 struct LineExitDiamond
249 {
250 tcu::IVec2 position;
251 };
252
253 /*--------------------------------------------------------------------*//*!
254 * \brief Line exit diamond generator
255 *
256 * For a given line, generates list of diamonds the line exits using the
257 * line-exit rules of the line rasterization. Does not do scissoring.
258 *
259 * \note Not used by rr, but provided to prevent test cases requiring
260 * accurate diamonds from abusing SingleSampleLineRasterizer.
261 *//*--------------------------------------------------------------------*/
262 class LineExitDiamondGenerator
263 {
264 public:
265 LineExitDiamondGenerator (void);
266 ~LineExitDiamondGenerator (void);
267
268 void init (const tcu::Vec4& v0, const tcu::Vec4& v1);
269
270 // only available after init()
271 void rasterize (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten);
272
273 private:
274 LineExitDiamondGenerator (const LineExitDiamondGenerator&); // not allowed
275 LineExitDiamondGenerator& operator= (const LineExitDiamondGenerator&); // not allowed
276
277 // Per-line rasterization state.
278 tcu::Vec4 m_v0;
279 tcu::Vec4 m_v1;
280 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive).
281 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive).
282 tcu::IVec2 m_curPos; //!< Current rasterization position.
283 };
284
285 } // rr
286
287 #endif // _RRRASTERIZER_HPP
288