1 /**************************************************************************** 2 * Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 * 23 * @file conservativerast.h 24 * 25 ******************************************************************************/ 26 #pragma once 27 #include <type_traits> 28 #include "common/simdintrin.h" 29 30 enum FixedPointFmt 31 { 32 FP_UNINIT, 33 _16_8, 34 _16_9, 35 _X_16, 36 }; 37 38 ////////////////////////////////////////////////////////////////////////// 39 /// @brief convenience typedefs for supported Fixed Point precisions 40 typedef std::integral_constant<uint32_t, FP_UNINIT> Fixed_Uninit; 41 typedef std::integral_constant<uint32_t, _16_8> Fixed_16_8; 42 typedef std::integral_constant<uint32_t, _16_9> Fixed_16_9; 43 typedef std::integral_constant<uint32_t, _X_16> Fixed_X_16; 44 45 ////////////////////////////////////////////////////////////////////////// 46 /// @struct FixedPointTraits 47 /// @brief holds constants relating to converting between FP and Fixed point 48 /// @tparam FT: fixed precision type 49 template<typename FT> 50 struct FixedPointTraits{}; 51 52 ////////////////////////////////////////////////////////////////////////// 53 /// @brief Fixed_16_8 specialization of FixedPointTraits 54 template<> 55 struct FixedPointTraits<Fixed_16_8> 56 { 57 /// multiplier to go from FP32 to Fixed Point 16.8 58 typedef std::integral_constant<uint32_t, 256> ScaleT; 59 /// number of bits to shift to go from 16.8 fixed => int32 60 typedef std::integral_constant<uint32_t, 8> BitsT; 61 typedef Fixed_16_8 TypeT; 62 }; 63 64 ////////////////////////////////////////////////////////////////////////// 65 /// @brief Fixed_16_9 specialization of FixedPointTraits 66 template<> 67 struct FixedPointTraits<Fixed_16_9> 68 { 69 /// multiplier to go from FP32 to Fixed Point 16.9 70 typedef std::integral_constant<uint32_t, 512> ScaleT; 71 /// number of bits to shift to go from 16.9 fixed => int32 72 typedef std::integral_constant<uint32_t, 9> BitsT; 73 typedef Fixed_16_9 TypeT; 74 }; 75 76 ////////////////////////////////////////////////////////////////////////// 77 /// @brief Fixed_16_9 specialization of FixedPointTraits 78 template<> 79 struct FixedPointTraits<Fixed_X_16> 80 { 81 /// multiplier to go from FP32 to Fixed Point X.16 82 typedef std::integral_constant<uint32_t, 65536> ScaleT; 83 /// number of bits to shift to go from X.16 fixed => int32 84 typedef std::integral_constant<uint32_t, 16> BitsT; 85 typedef Fixed_X_16 TypeT; 86 }; 87 88 ////////////////////////////////////////////////////////////////////////// 89 /// @brief convenience typedefs for conservative rasterization modes 90 typedef std::false_type StandardRastT; 91 typedef std::true_type ConservativeRastT; 92 93 ////////////////////////////////////////////////////////////////////////// 94 /// @brief convenience typedefs for Input Coverage rasterization modes 95 typedef std::integral_constant<uint32_t, SWR_INPUT_COVERAGE_NONE> NoInputCoverageT; 96 typedef std::integral_constant<uint32_t, SWR_INPUT_COVERAGE_NORMAL> OuterConservativeCoverageT; 97 typedef std::integral_constant<uint32_t, SWR_INPUT_COVERAGE_INNER_CONSERVATIVE> InnerConservativeCoverageT; 98 99 ////////////////////////////////////////////////////////////////////////// 100 /// @struct ConservativeRastTraits 101 /// @brief primary ConservativeRastTraits template. Shouldn't be instantiated 102 /// @tparam ConservativeT: type of conservative rasterization 103 template <typename ConservativeT> 104 struct ConservativeRastFETraits {}; 105 106 ////////////////////////////////////////////////////////////////////////// 107 /// @brief StandardRast specialization of ConservativeRastTraits 108 template <> 109 struct ConservativeRastFETraits<StandardRastT> 110 { 111 typedef std::false_type IsConservativeT; 112 }; 113 114 ////////////////////////////////////////////////////////////////////////// 115 /// @brief ConservativeRastT specialization of ConservativeRastTraits 116 template <> 117 struct ConservativeRastFETraits<ConservativeRastT> 118 { 119 typedef std::true_type IsConservativeT; 120 typedef std::integral_constant<uint32_t, 1> BoundingBoxOffsetT; 121 }; 122 123 ////////////////////////////////////////////////////////////////////////// 124 /// @brief convenience typedefs for ConservativeRastFETraits 125 typedef ConservativeRastFETraits<StandardRastT> FEStandardRastT; 126 typedef ConservativeRastFETraits<ConservativeRastT> FEConservativeRastT; 127 128 ////////////////////////////////////////////////////////////////////////// 129 /// @struct ConservativeRastBETraits 130 /// @brief primary ConservativeRastBETraits template. Shouldn't be instantiated; 131 /// default to standard rasterization behavior 132 /// @tparam ConservativeT: type of conservative rasterization 133 /// @tparam InputCoverageT: type of input coverage requested, if any 134 template <typename ConservativeT, typename _InputCoverageT> 135 struct ConservativeRastBETraits { 136 typedef std::false_type IsConservativeT; 137 typedef _InputCoverageT InputCoverageT; 138 typedef FixedPointTraits<Fixed_16_8> ConservativePrecisionT; 139 typedef std::integral_constant<int32_t, 0> ConservativeEdgeOffsetT; 140 typedef std::integral_constant<int32_t, 0> InnerConservativeEdgeOffsetT; 141 }; 142 143 ////////////////////////////////////////////////////////////////////////// 144 /// @brief StandardRastT specialization of ConservativeRastBETraits 145 template <typename _InputCoverageT> 146 struct ConservativeRastBETraits<StandardRastT, _InputCoverageT> 147 { 148 typedef std::false_type IsConservativeT; 149 typedef _InputCoverageT InputCoverageT; 150 typedef FixedPointTraits<Fixed_16_8> ConservativePrecisionT; 151 typedef std::integral_constant<int32_t, 0> ConservativeEdgeOffsetT; 152 typedef std::integral_constant<int32_t, 0> InnerConservativeEdgeOffsetT; 153 }; 154 155 ////////////////////////////////////////////////////////////////////////// 156 /// @brief ConservativeRastT specialization of ConservativeRastBETraits 157 /// with no input coverage 158 template <> 159 struct ConservativeRastBETraits<ConservativeRastT, NoInputCoverageT> 160 { 161 typedef std::true_type IsConservativeT; 162 typedef NoInputCoverageT InputCoverageT; 163 164 typedef FixedPointTraits<Fixed_16_9> ConservativePrecisionT; 165 166 /// offset edge away from pixel center by 1/2 pixel + 1/512, in Fixed 16.9 precision 167 /// this allows the rasterizer to do the 3 edge coverage tests against a single point, instead of 168 /// of having to compare individual edges to pixel corners to check if any part of the triangle 169 /// intersects a pixel 170 typedef std::integral_constant<int32_t, (ConservativePrecisionT::ScaleT::value/2) + 1> ConservativeEdgeOffsetT; 171 typedef std::integral_constant<int32_t, 0> InnerConservativeEdgeOffsetT; 172 }; 173 174 ////////////////////////////////////////////////////////////////////////// 175 /// @brief ConservativeRastT specialization of ConservativeRastBETraits 176 /// with OuterConservativeCoverage 177 template <> 178 struct ConservativeRastBETraits<ConservativeRastT, OuterConservativeCoverageT> 179 { 180 typedef std::true_type IsConservativeT; 181 typedef OuterConservativeCoverageT InputCoverageT; 182 183 typedef FixedPointTraits<Fixed_16_9> ConservativePrecisionT; 184 185 /// offset edge away from pixel center by 1/2 pixel + 1/512, in Fixed 16.9 precision 186 /// this allows the rasterizer to do the 3 edge coverage tests against a single point, instead of 187 /// of having to compare individual edges to pixel corners to check if any part of the triangle 188 /// intersects a pixel 189 typedef std::integral_constant<int32_t, (ConservativePrecisionT::ScaleT::value/2) + 1> ConservativeEdgeOffsetT; 190 typedef std::integral_constant<int32_t, 0> InnerConservativeEdgeOffsetT; 191 192 }; 193 194 ////////////////////////////////////////////////////////////////////////// 195 /// @brief ConservativeRastT specialization of ConservativeRastBETraits 196 /// with InnerConservativeCoverage 197 template <> 198 struct ConservativeRastBETraits<ConservativeRastT, InnerConservativeCoverageT> 199 { 200 typedef std::true_type IsConservativeT; 201 typedef InnerConservativeCoverageT InputCoverageT; 202 203 typedef FixedPointTraits<Fixed_16_9> ConservativePrecisionT; 204 205 /// offset edge away from pixel center by 1/2 pixel + 1/512, in Fixed 16.9 precision 206 /// this allows the rasterizer to do the 3 edge coverage tests against a single point, instead of 207 /// of having to compare individual edges to pixel corners to check if any part of the triangle 208 /// intersects a pixel 209 typedef std::integral_constant<int32_t, (ConservativePrecisionT::ScaleT::value/2) + 1> ConservativeEdgeOffsetT; 210 211 /// undo the outer conservative offset and offset edge towards from pixel center by 1/2 pixel + 1/512, in Fixed 16.9 precision 212 /// this allows the rasterizer to do the 3 edge coverage tests against a single point, instead of 213 /// of having to compare individual edges to pixel corners to check if a pixel is fully covered by a triangle 214 typedef std::integral_constant<int32_t, static_cast<int32_t>(-((ConservativePrecisionT::ScaleT::value/2) + 1) - ConservativeEdgeOffsetT::value)> InnerConservativeEdgeOffsetT; 215 };