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
32namespace rr
33{
34
35//! Rasterizer configuration
36enum
37{
38	RASTERIZER_SUBPIXEL_BITS			= 8,
39	RASTERIZER_MAX_SAMPLES_PER_FRAGMENT	= 16
40};
41
42//! Get coverage bit value.
43inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx)
44{
45	const int	numBits		= 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
53inline 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.
61inline 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.
68inline 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
74inline 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)).
80inline 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 *//*--------------------------------------------------------------------*/
98struct EdgeFunction
99{
100	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 *//*--------------------------------------------------------------------*/
127class TriangleRasterizer
128{
129public:
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()
135	FaceType				getVisibleFace			(void) const { return m_face; }
136	void					rasterize				(FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
137
138private:
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} DE_WARN_UNUSED_TYPE;
163
164
165/*--------------------------------------------------------------------*//*!
166 * \brief Single sample line rasterizer
167 *
168 * Line rasterizer implements following features:
169 *  - Rasterization using fixed-point coordinates
170 *  - Depth interpolation
171 *  - Perspective-correct interpolation
172 *
173 * It does not (and will not) implement following:
174 *  - Clipping
175 *  - Multisampled line rasterization
176 *//*--------------------------------------------------------------------*/
177class SingleSampleLineRasterizer
178{
179public:
180									SingleSampleLineRasterizer	(const tcu::IVec4& viewport);
181									~SingleSampleLineRasterizer	(void);
182
183	void							init						(const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
184
185	// only available after init()
186	void							rasterize					(FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
187
188private:
189									SingleSampleLineRasterizer	(const SingleSampleLineRasterizer&); // not allowed
190	SingleSampleLineRasterizer&		operator=					(const SingleSampleLineRasterizer&); // not allowed
191
192	// Constant rasterization state.
193	const tcu::IVec4				m_viewport;
194
195	// Per-line rasterization state.
196	tcu::Vec4						m_v0;
197	tcu::Vec4						m_v1;
198	tcu::IVec2						m_bboxMin;			//!< Bounding box min (inclusive).
199	tcu::IVec2						m_bboxMax;			//!< Bounding box max (inclusive).
200	tcu::IVec2						m_curPos;			//!< Current rasterization position.
201	deInt32							m_curRowFragment;	//!< Current rasterization position of one fragment in column of lineWidth fragments
202	float							m_lineWidth;
203} DE_WARN_UNUSED_TYPE;
204
205
206/*--------------------------------------------------------------------*//*!
207 * \brief Multisampled line rasterizer
208 *
209 * Line rasterizer implements following features:
210 *  - Rasterization using fixed-point coordinates
211 *  - Depth interpolation
212 *  - Perspective-correct interpolation
213 *
214 * It does not (and will not) implement following:
215 *  - Clipping
216 *  - Aliased line rasterization
217 *//*--------------------------------------------------------------------*/
218class MultiSampleLineRasterizer
219{
220public:
221								MultiSampleLineRasterizer	(const int numSamples, const tcu::IVec4& viewport);
222								~MultiSampleLineRasterizer	();
223
224	void						init						(const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
225
226	// only available after init()
227	void						rasterize					(FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
228
229private:
230								MultiSampleLineRasterizer	(const MultiSampleLineRasterizer&); // not allowed
231	MultiSampleLineRasterizer&	operator=					(const MultiSampleLineRasterizer&); // not allowed
232
233	// Constant rasterization state.
234	const int					m_numSamples;
235
236	// Per-line rasterization state.
237	TriangleRasterizer			m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
238	TriangleRasterizer			m_triangleRasterizer1;
239} DE_WARN_UNUSED_TYPE;
240
241
242/*--------------------------------------------------------------------*//*!
243 * \brief Pixel diamond
244 *
245 * Structure representing a diamond a line exits.
246 *//*--------------------------------------------------------------------*/
247struct LineExitDiamond
248{
249	tcu::IVec2	position;
250};
251
252/*--------------------------------------------------------------------*//*!
253 * \brief Line exit diamond generator
254 *
255 * For a given line, generates list of diamonds the line exits using the
256 * line-exit rules of the line rasterization. Does not do scissoring.
257 *
258 * \note Not used by rr, but provided to prevent test cases requiring
259 *       accurate diamonds from abusing SingleSampleLineRasterizer.
260 *//*--------------------------------------------------------------------*/
261class LineExitDiamondGenerator
262{
263public:
264									LineExitDiamondGenerator	(void);
265									~LineExitDiamondGenerator	(void);
266
267	void							init						(const tcu::Vec4& v0, const tcu::Vec4& v1);
268
269	// only available after init()
270	void							rasterize					(LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten);
271
272private:
273									LineExitDiamondGenerator	(const LineExitDiamondGenerator&); // not allowed
274	LineExitDiamondGenerator&		operator=					(const LineExitDiamondGenerator&); // not allowed
275
276	// Per-line rasterization state.
277	tcu::Vec4						m_v0;
278	tcu::Vec4						m_v1;
279	tcu::IVec2						m_bboxMin;			//!< Bounding box min (inclusive).
280	tcu::IVec2						m_bboxMax;			//!< Bounding box max (inclusive).
281	tcu::IVec2						m_curPos;			//!< Current rasterization position.
282};
283
284} // rr
285
286#endif // _RRRASTERIZER_HPP
287