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 } 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  *//*--------------------------------------------------------------------*/
    177 class SingleSampleLineRasterizer
    178 {
    179 public:
    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 
    188 private:
    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  *//*--------------------------------------------------------------------*/
    218 class MultiSampleLineRasterizer
    219 {
    220 public:
    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 
    229 private:
    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  *//*--------------------------------------------------------------------*/
    247 struct 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  *//*--------------------------------------------------------------------*/
    261 class LineExitDiamondGenerator
    262 {
    263 public:
    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 
    272 private:
    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