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