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 32namespace rr 33{ 34 35//! Rasterizer configuration 36enum 37{ 38 RASTERIZER_MAX_SAMPLES_PER_FRAGMENT = 16 39}; 40 41//! Get coverage bit value. 42inline deUint64 getCoverageBit (int numSamples, int x, int y, int sampleNdx) 43{ 44 const int numBits = (int)sizeof(deUint64)*8; 45 const int maxSamples = numBits/4; 46 DE_STATIC_ASSERT(maxSamples >= RASTERIZER_MAX_SAMPLES_PER_FRAGMENT); 47 DE_ASSERT(de::inRange(numSamples, 1, maxSamples) && de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2)); 48 return 1ull << ((x*2 + y)*numSamples + sampleNdx); 49} 50 51//! Get all sample bits for fragment 52inline deUint64 getCoverageFragmentSampleBits (int numSamples, int x, int y) 53{ 54 DE_ASSERT(de::inBounds(x, 0, 2) && de::inBounds(y, 0, 2)); 55 const deUint64 fragMask = (1ull << numSamples) - 1; 56 return fragMask << (x*2 + y)*numSamples; 57} 58 59//! Set bit in coverage mask. 60inline deUint64 setCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx, bool val) 61{ 62 const deUint64 bit = getCoverageBit(numSamples, x, y, sampleNdx); 63 return val ? (mask | bit) : (mask & ~bit); 64} 65 66//! Get coverage bit value in mask. 67inline bool getCoverageValue (deUint64 mask, int numSamples, int x, int y, int sampleNdx) 68{ 69 return (mask & getCoverageBit(numSamples, x, y, sampleNdx)) != 0; 70} 71 72//! Test if any sample for fragment is live 73inline bool getCoverageAnyFragmentSampleLive (deUint64 mask, int numSamples, int x, int y) 74{ 75 return (mask & getCoverageFragmentSampleBits(numSamples, x, y)) != 0; 76} 77 78//! Get position of first coverage bit of fragment - equivalent to deClz64(getCoverageFragmentSampleBits(numSamples, x, y)). 79inline int getCoverageOffset (int numSamples, int x, int y) 80{ 81 return (x*2 + y)*numSamples; 82} 83 84/*--------------------------------------------------------------------*//*! 85 * \brief Edge function 86 * 87 * Edge function can be evaluated for point P (in fixed-point coordinates 88 * with SUBPIXEL_BITS fractional part) by computing 89 * D = a*Px + b*Py + c 90 * 91 * D will be fixed-point value where lower (SUBPIXEL_BITS*2) bits will 92 * be fractional part. 93 * 94 * a and b are stored with SUBPIXEL_BITS fractional part, while c is stored 95 * with SUBPIXEL_BITS*2 fractional bits. 96 *//*--------------------------------------------------------------------*/ 97struct EdgeFunction 98{ 99 inline EdgeFunction (void) : a(0), b(0), c(0), inclusive(false) {} 100 101 deInt64 a; 102 deInt64 b; 103 deInt64 c; 104 bool inclusive; //!< True if edge is inclusive according to fill rules. 105}; 106 107/*--------------------------------------------------------------------*//*! 108 * \brief Triangle rasterizer 109 * 110 * Triangle rasterizer implements following features: 111 * - Rasterization using fixed-point coordinates 112 * - 1, 4, and 16 -sample rasterization 113 * - Depth interpolation 114 * - Perspective-correct barycentric computation for interpolation 115 * - Visible face determination 116 * 117 * It does not (and will not) implement following: 118 * - Triangle setup 119 * - Clipping 120 * - Degenerate elimination 121 * - Coordinate transformation (inputs are in screen-space) 122 * - Culling - logic can be implemented outside by querying visible face 123 * - Scissoring (this can be done by controlling viewport rectangle) 124 * - Any per-fragment operations 125 *//*--------------------------------------------------------------------*/ 126class TriangleRasterizer 127{ 128public: 129 TriangleRasterizer (const tcu::IVec4& viewport, const int numSamples, const RasterizationState& state, const int suppixelBits); 130 131 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2); 132 133 // Following functions are only available after init() 134 FaceType getVisibleFace (void) const { return m_face; } 135 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized); 136 137private: 138 void rasterizeSingleSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized); 139 140 template<int NumSamples> 141 void rasterizeMultiSample (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized); 142 143 // Constant rasterization state. 144 const tcu::IVec4 m_viewport; 145 const int m_numSamples; 146 const Winding m_winding; 147 const HorizontalFill m_horizontalFill; 148 const VerticalFill m_verticalFill; 149 const int m_subpixelBits; 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 *//*--------------------------------------------------------------------*/ 178class SingleSampleLineRasterizer 179{ 180public: 181 SingleSampleLineRasterizer (const tcu::IVec4& viewport, const int subpixelBits); 182 ~SingleSampleLineRasterizer (void); 183 184 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth, deUint32 stippleFactor, deUint16 stipplePattern); 185 186 // only available after init() 187 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized); 188 189 void resetStipple () { m_stippleCounter = 0; } 190 191private: 192 SingleSampleLineRasterizer (const SingleSampleLineRasterizer&); // not allowed 193 SingleSampleLineRasterizer& operator= (const SingleSampleLineRasterizer&); // not allowed 194 195 // Constant rasterization state. 196 const tcu::IVec4 m_viewport; 197 const int m_subpixelBits; 198 199 // Per-line rasterization state. 200 tcu::Vec4 m_v0; 201 tcu::Vec4 m_v1; 202 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive). 203 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive). 204 tcu::IVec2 m_curPos; //!< Current rasterization position. 205 deInt32 m_curRowFragment; //!< Current rasterization position of one fragment in column of lineWidth fragments 206 float m_lineWidth; 207 deUint32 m_stippleFactor; 208 deUint16 m_stipplePattern; 209 deUint32 m_stippleCounter; 210} DE_WARN_UNUSED_TYPE; 211 212 213/*--------------------------------------------------------------------*//*! 214 * \brief Multisampled line rasterizer 215 * 216 * Line rasterizer implements following features: 217 * - Rasterization using fixed-point coordinates 218 * - Depth interpolation 219 * - Perspective-correct interpolation 220 * 221 * It does not (and will not) implement following: 222 * - Clipping 223 * - Aliased line rasterization 224 *//*--------------------------------------------------------------------*/ 225class MultiSampleLineRasterizer 226{ 227public: 228 MultiSampleLineRasterizer (const int numSamples, const tcu::IVec4& viewport, const int subpixelBits); 229 ~MultiSampleLineRasterizer (); 230 231 void init (const tcu::Vec4& v0, const tcu::Vec4& v1, float lineWidth); 232 233 // only available after init() 234 void rasterize (FragmentPacket* const fragmentPackets, float* const depthValues, const int maxFragmentPackets, int& numPacketsRasterized); 235 236private: 237 MultiSampleLineRasterizer (const MultiSampleLineRasterizer&); // not allowed 238 MultiSampleLineRasterizer& operator= (const MultiSampleLineRasterizer&); // not allowed 239 240 // Constant rasterization state. 241 const int m_numSamples; 242 243 // Per-line rasterization state. 244 TriangleRasterizer m_triangleRasterizer0; //!< not in array because we want to initialize these in the initialization list 245 TriangleRasterizer m_triangleRasterizer1; 246} DE_WARN_UNUSED_TYPE; 247 248 249/*--------------------------------------------------------------------*//*! 250 * \brief Pixel diamond 251 * 252 * Structure representing a diamond a line exits. 253 *//*--------------------------------------------------------------------*/ 254struct LineExitDiamond 255{ 256 tcu::IVec2 position; 257}; 258 259/*--------------------------------------------------------------------*//*! 260 * \brief Line exit diamond generator 261 * 262 * For a given line, generates list of diamonds the line exits using the 263 * line-exit rules of the line rasterization. Does not do scissoring. 264 * 265 * \note Not used by rr, but provided to prevent test cases requiring 266 * accurate diamonds from abusing SingleSampleLineRasterizer. 267 *//*--------------------------------------------------------------------*/ 268class LineExitDiamondGenerator 269{ 270public: 271 LineExitDiamondGenerator (const int subpixelBits); 272 ~LineExitDiamondGenerator (void); 273 274 void init (const tcu::Vec4& v0, const tcu::Vec4& v1); 275 276 // only available after init() 277 void rasterize (LineExitDiamond* const lineDiamonds, const int maxDiamonds, int& numWritten); 278 279private: 280 LineExitDiamondGenerator (const LineExitDiamondGenerator&); // not allowed 281 LineExitDiamondGenerator& operator= (const LineExitDiamondGenerator&); // not allowed 282 283 const int m_subpixelBits; 284 285 // Per-line rasterization state. 286 tcu::Vec4 m_v0; 287 tcu::Vec4 m_v1; 288 tcu::IVec2 m_bboxMin; //!< Bounding box min (inclusive). 289 tcu::IVec2 m_bboxMax; //!< Bounding box max (inclusive). 290 tcu::IVec2 m_curPos; //!< Current rasterization position. 291}; 292 293} // rr 294 295#endif // _RRRASTERIZER_HPP 296