• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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		= 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 };
163 
164 /*--------------------------------------------------------------------*//*!
165  * \brief Single sample line rasterizer
166  *
167  * Triangle rasterizer implements following features:
168  *  - Rasterization using fixed-point coordinates
169  *  - Depth interpolation
170  *  - Perspective-correct interpolation
171  *
172  * It does not (and will not) implement following:
173  *  - Clipping
174  *  - Multisampled line rasterization
175  *//*--------------------------------------------------------------------*/
176 class SingleSampleLineRasterizer
177 {
178 public:
179 									SingleSampleLineRasterizer	(const tcu::IVec4& viewport);
180 									~SingleSampleLineRasterizer	();
181 
182 	void							init						(const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
183 
184 	// only available after init()
185 	void							rasterize					(FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
186 
187 private:
188 									SingleSampleLineRasterizer	(const SingleSampleLineRasterizer&); // not allowed
189 	SingleSampleLineRasterizer&		operator=					(const SingleSampleLineRasterizer&); // not allowed
190 
191 	// Constant rasterization state.
192 	const tcu::IVec4				m_viewport;
193 
194 	// Per-line rasterization state.
195 	tcu::Vec4						m_v0;
196 	tcu::Vec4						m_v1;
197 	tcu::IVec2						m_bboxMin;			//!< Bounding box min (inclusive).
198 	tcu::IVec2						m_bboxMax;			//!< Bounding box max (inclusive).
199 	tcu::IVec2						m_curPos;			//!< Current rasterization position.
200 	deInt32							m_curRowFragment;	//!< Current rasterization position of one fragment in column of lineWidth fragments
201 	float							m_lineWidth;
202 };
203 
204 
205 /*--------------------------------------------------------------------*//*!
206  * \brief Multisampled line rasterizer
207  *
208  * Triangle rasterizer implements following features:
209  *  - Rasterization using fixed-point coordinates
210  *  - Depth interpolation
211  *  - Perspective-correct interpolation
212  *
213  * It does not (and will not) implement following:
214  *  - Clipping
215  *  - Aliased line rasterization
216  *//*--------------------------------------------------------------------*/
217 class MultiSampleLineRasterizer
218 {
219 public:
220 								MultiSampleLineRasterizer	(const int numSamples, const tcu::IVec4& viewport);
221 								~MultiSampleLineRasterizer	();
222 
223 	void						init						(const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth);
224 
225 	// only available after init()
226 	void						rasterize					(FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized);
227 
228 private:
229 								MultiSampleLineRasterizer	(const MultiSampleLineRasterizer&); // not allowed
230 	MultiSampleLineRasterizer&	operator=					(const MultiSampleLineRasterizer&); // not allowed
231 
232 	// Constant rasterization state.
233 	const int					m_numSamples;
234 
235 	// Per-line rasterization state.
236 	TriangleRasterizer			m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list
237 	TriangleRasterizer			m_triangleRasterizer1;
238 };
239 
240 } // rr
241 
242 #endif // _RRRASTERIZER_HPP
243