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		= 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 };
    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