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