Home | History | Annotate | Download | only in referencerenderer
      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.
     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
     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.
     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.
     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
     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)).
     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 {
    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  *//*--------------------------------------------------------------------*/
    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()
    135 	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