1 /****************************************************************************
2 * Copyright (C) 2014-2015 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 binner.h
24 *
25 * @brief Declaration for the macrotile binner
26 *
27 ******************************************************************************/
28 #include "state.h"
29 #include "conservativeRast.h"
30 #include "utils.h"
31 //////////////////////////////////////////////////////////////////////////
32 /// @brief Offsets added to post-viewport vertex positions based on
33 /// raster state.
34 ///
35 /// Can't use templated variable because we must stick with C++11 features.
36 /// Template variables were introduced with C++14
37 template <typename SIMD_T>
38 struct SwrPixelOffsets
39 {
40 public:
GetOffsetSwrPixelOffsets41 INLINE static typename SIMD_T::Float GetOffset(uint32_t loc)
42 {
43 SWR_ASSERT(loc <= 1);
44
45 return SIMD_T::set1_ps(loc ? 0.5f : 0.0f);
46 }
47 };
48
49 //////////////////////////////////////////////////////////////////////////
50 /// @brief Convert the X,Y coords of a triangle to the requested Fixed
51 /// Point precision from FP32.
52 template <typename SIMD_T, typename PT = FixedPointTraits<Fixed_16_8>>
fpToFixedPointVertical(const typename SIMD_T::Float & vIn)53 INLINE typename SIMD_T::Integer fpToFixedPointVertical(const typename SIMD_T::Float &vIn)
54 {
55 return SIMD_T::cvtps_epi32(SIMD_T::mul_ps(vIn, SIMD_T::set1_ps(PT::ScaleT::value)));
56 }
57
58 //////////////////////////////////////////////////////////////////////////
59 /// @brief Helper function to set the X,Y coords of a triangle to the
60 /// requested Fixed Point precision from FP32.
61 /// @param tri: simdvector[3] of FP triangle verts
62 /// @param vXi: fixed point X coords of tri verts
63 /// @param vYi: fixed point Y coords of tri verts
64 template <typename SIMD_T>
FPToFixedPoint(const typename SIMD_T::Vec4 * const tri,typename SIMD_T::Integer (& vXi)[3],typename SIMD_T::Integer (& vYi)[3])65 INLINE static void FPToFixedPoint(const typename SIMD_T::Vec4 *const tri, typename SIMD_T::Integer(&vXi)[3], typename SIMD_T::Integer(&vYi)[3])
66 {
67 vXi[0] = fpToFixedPointVertical<SIMD_T>(tri[0].x);
68 vYi[0] = fpToFixedPointVertical<SIMD_T>(tri[0].y);
69 vXi[1] = fpToFixedPointVertical<SIMD_T>(tri[1].x);
70 vYi[1] = fpToFixedPointVertical<SIMD_T>(tri[1].y);
71 vXi[2] = fpToFixedPointVertical<SIMD_T>(tri[2].x);
72 vYi[2] = fpToFixedPointVertical<SIMD_T>(tri[2].y);
73 }
74
75 //////////////////////////////////////////////////////////////////////////
76 /// @brief Calculate bounding box for current triangle
77 /// @tparam CT: ConservativeRastFETraits type
78 /// @param vX: fixed point X position for triangle verts
79 /// @param vY: fixed point Y position for triangle verts
80 /// @param bbox: fixed point bbox
81 /// *Note*: expects vX, vY to be in the correct precision for the type
82 /// of rasterization. This avoids unnecessary FP->fixed conversions.
83 template <typename SIMD_T, typename CT>
calcBoundingBoxIntVertical(const typename SIMD_T::Integer (& vX)[3],const typename SIMD_T::Integer (& vY)[3],SIMDBBOX_T<SIMD_T> & bbox)84 INLINE void calcBoundingBoxIntVertical(const typename SIMD_T::Integer(&vX)[3], const typename SIMD_T::Integer(&vY)[3], SIMDBBOX_T<SIMD_T> &bbox)
85 {
86 typename SIMD_T::Integer vMinX = vX[0];
87
88 vMinX = SIMD_T::min_epi32(vMinX, vX[1]);
89 vMinX = SIMD_T::min_epi32(vMinX, vX[2]);
90
91 typename SIMD_T::Integer vMaxX = vX[0];
92
93 vMaxX = SIMD_T::max_epi32(vMaxX, vX[1]);
94 vMaxX = SIMD_T::max_epi32(vMaxX, vX[2]);
95
96 typename SIMD_T::Integer vMinY = vY[0];
97
98 vMinY = SIMD_T::min_epi32(vMinY, vY[1]);
99 vMinY = SIMD_T::min_epi32(vMinY, vY[2]);
100
101 typename SIMD_T::Integer vMaxY = vY[0];
102
103 vMaxY = SIMD_T::max_epi32(vMaxY, vY[1]);
104 vMaxY = SIMD_T::max_epi32(vMaxY, vY[2]);
105
106 if (CT::BoundingBoxOffsetT::value != 0)
107 {
108 /// Bounding box needs to be expanded by 1/512 before snapping to 16.8 for conservative rasterization
109 /// expand bbox by 1/256; coverage will be correctly handled in the rasterizer.
110
111 const typename SIMD_T::Integer value = SIMD_T::set1_epi32(CT::BoundingBoxOffsetT::value);
112
113 vMinX = SIMD_T::sub_epi32(vMinX, value);
114 vMaxX = SIMD_T::add_epi32(vMaxX, value);
115 vMinY = SIMD_T::sub_epi32(vMinY, value);
116 vMaxY = SIMD_T::add_epi32(vMaxY, value);
117 }
118
119 bbox.xmin = vMinX;
120 bbox.xmax = vMaxX;
121 bbox.ymin = vMinY;
122 bbox.ymax = vMaxY;
123 }
124
125 //////////////////////////////////////////////////////////////////////////
126 /// @brief Gather scissor rect data based on per-prim viewport indices.
127 /// @param pScissorsInFixedPoint - array of scissor rects in 16.8 fixed point.
128 /// @param pViewportIndex - array of per-primitive vewport indexes.
129 /// @param scisXmin - output vector of per-prmitive scissor rect Xmin data.
130 /// @param scisYmin - output vector of per-prmitive scissor rect Ymin data.
131 /// @param scisXmax - output vector of per-prmitive scissor rect Xmax data.
132 /// @param scisYmax - output vector of per-prmitive scissor rect Ymax data.
133 //
134 /// @todo: Look at speeding this up -- weigh against corresponding costs in rasterizer.
GatherScissors(const SWR_RECT * pScissorsInFixedPoint,const uint32_t * pViewportIndex,simdscalari & scisXmin,simdscalari & scisYmin,simdscalari & scisXmax,simdscalari & scisYmax)135 static void GatherScissors(const SWR_RECT *pScissorsInFixedPoint, const uint32_t *pViewportIndex,
136 simdscalari &scisXmin, simdscalari &scisYmin, simdscalari &scisXmax, simdscalari &scisYmax)
137 {
138 scisXmin = _simd_set_epi32(
139 pScissorsInFixedPoint[pViewportIndex[7]].xmin,
140 pScissorsInFixedPoint[pViewportIndex[6]].xmin,
141 pScissorsInFixedPoint[pViewportIndex[5]].xmin,
142 pScissorsInFixedPoint[pViewportIndex[4]].xmin,
143 pScissorsInFixedPoint[pViewportIndex[3]].xmin,
144 pScissorsInFixedPoint[pViewportIndex[2]].xmin,
145 pScissorsInFixedPoint[pViewportIndex[1]].xmin,
146 pScissorsInFixedPoint[pViewportIndex[0]].xmin);
147 scisYmin = _simd_set_epi32(
148 pScissorsInFixedPoint[pViewportIndex[7]].ymin,
149 pScissorsInFixedPoint[pViewportIndex[6]].ymin,
150 pScissorsInFixedPoint[pViewportIndex[5]].ymin,
151 pScissorsInFixedPoint[pViewportIndex[4]].ymin,
152 pScissorsInFixedPoint[pViewportIndex[3]].ymin,
153 pScissorsInFixedPoint[pViewportIndex[2]].ymin,
154 pScissorsInFixedPoint[pViewportIndex[1]].ymin,
155 pScissorsInFixedPoint[pViewportIndex[0]].ymin);
156 scisXmax = _simd_set_epi32(
157 pScissorsInFixedPoint[pViewportIndex[7]].xmax,
158 pScissorsInFixedPoint[pViewportIndex[6]].xmax,
159 pScissorsInFixedPoint[pViewportIndex[5]].xmax,
160 pScissorsInFixedPoint[pViewportIndex[4]].xmax,
161 pScissorsInFixedPoint[pViewportIndex[3]].xmax,
162 pScissorsInFixedPoint[pViewportIndex[2]].xmax,
163 pScissorsInFixedPoint[pViewportIndex[1]].xmax,
164 pScissorsInFixedPoint[pViewportIndex[0]].xmax);
165 scisYmax = _simd_set_epi32(
166 pScissorsInFixedPoint[pViewportIndex[7]].ymax,
167 pScissorsInFixedPoint[pViewportIndex[6]].ymax,
168 pScissorsInFixedPoint[pViewportIndex[5]].ymax,
169 pScissorsInFixedPoint[pViewportIndex[4]].ymax,
170 pScissorsInFixedPoint[pViewportIndex[3]].ymax,
171 pScissorsInFixedPoint[pViewportIndex[2]].ymax,
172 pScissorsInFixedPoint[pViewportIndex[1]].ymax,
173 pScissorsInFixedPoint[pViewportIndex[0]].ymax);
174 }
175
GatherScissors(const SWR_RECT * pScissorsInFixedPoint,const uint32_t * pViewportIndex,simd16scalari & scisXmin,simd16scalari & scisYmin,simd16scalari & scisXmax,simd16scalari & scisYmax)176 static void GatherScissors(const SWR_RECT *pScissorsInFixedPoint, const uint32_t *pViewportIndex,
177 simd16scalari &scisXmin, simd16scalari &scisYmin, simd16scalari &scisXmax, simd16scalari &scisYmax)
178 {
179 scisXmin = _simd16_set_epi32(
180 pScissorsInFixedPoint[pViewportIndex[15]].xmin,
181 pScissorsInFixedPoint[pViewportIndex[14]].xmin,
182 pScissorsInFixedPoint[pViewportIndex[13]].xmin,
183 pScissorsInFixedPoint[pViewportIndex[12]].xmin,
184 pScissorsInFixedPoint[pViewportIndex[11]].xmin,
185 pScissorsInFixedPoint[pViewportIndex[10]].xmin,
186 pScissorsInFixedPoint[pViewportIndex[9]].xmin,
187 pScissorsInFixedPoint[pViewportIndex[8]].xmin,
188 pScissorsInFixedPoint[pViewportIndex[7]].xmin,
189 pScissorsInFixedPoint[pViewportIndex[6]].xmin,
190 pScissorsInFixedPoint[pViewportIndex[5]].xmin,
191 pScissorsInFixedPoint[pViewportIndex[4]].xmin,
192 pScissorsInFixedPoint[pViewportIndex[3]].xmin,
193 pScissorsInFixedPoint[pViewportIndex[2]].xmin,
194 pScissorsInFixedPoint[pViewportIndex[1]].xmin,
195 pScissorsInFixedPoint[pViewportIndex[0]].xmin);
196
197 scisYmin = _simd16_set_epi32(
198 pScissorsInFixedPoint[pViewportIndex[15]].ymin,
199 pScissorsInFixedPoint[pViewportIndex[14]].ymin,
200 pScissorsInFixedPoint[pViewportIndex[13]].ymin,
201 pScissorsInFixedPoint[pViewportIndex[12]].ymin,
202 pScissorsInFixedPoint[pViewportIndex[11]].ymin,
203 pScissorsInFixedPoint[pViewportIndex[10]].ymin,
204 pScissorsInFixedPoint[pViewportIndex[9]].ymin,
205 pScissorsInFixedPoint[pViewportIndex[8]].ymin,
206 pScissorsInFixedPoint[pViewportIndex[7]].ymin,
207 pScissorsInFixedPoint[pViewportIndex[6]].ymin,
208 pScissorsInFixedPoint[pViewportIndex[5]].ymin,
209 pScissorsInFixedPoint[pViewportIndex[4]].ymin,
210 pScissorsInFixedPoint[pViewportIndex[3]].ymin,
211 pScissorsInFixedPoint[pViewportIndex[2]].ymin,
212 pScissorsInFixedPoint[pViewportIndex[1]].ymin,
213 pScissorsInFixedPoint[pViewportIndex[0]].ymin);
214
215 scisXmax = _simd16_set_epi32(
216 pScissorsInFixedPoint[pViewportIndex[15]].xmax,
217 pScissorsInFixedPoint[pViewportIndex[14]].xmax,
218 pScissorsInFixedPoint[pViewportIndex[13]].xmax,
219 pScissorsInFixedPoint[pViewportIndex[12]].xmax,
220 pScissorsInFixedPoint[pViewportIndex[11]].xmax,
221 pScissorsInFixedPoint[pViewportIndex[10]].xmax,
222 pScissorsInFixedPoint[pViewportIndex[9]].xmax,
223 pScissorsInFixedPoint[pViewportIndex[8]].xmax,
224 pScissorsInFixedPoint[pViewportIndex[7]].xmax,
225 pScissorsInFixedPoint[pViewportIndex[6]].xmax,
226 pScissorsInFixedPoint[pViewportIndex[5]].xmax,
227 pScissorsInFixedPoint[pViewportIndex[4]].xmax,
228 pScissorsInFixedPoint[pViewportIndex[3]].xmax,
229 pScissorsInFixedPoint[pViewportIndex[2]].xmax,
230 pScissorsInFixedPoint[pViewportIndex[1]].xmax,
231 pScissorsInFixedPoint[pViewportIndex[0]].xmax);
232
233 scisYmax = _simd16_set_epi32(
234 pScissorsInFixedPoint[pViewportIndex[15]].ymax,
235 pScissorsInFixedPoint[pViewportIndex[14]].ymax,
236 pScissorsInFixedPoint[pViewportIndex[13]].ymax,
237 pScissorsInFixedPoint[pViewportIndex[12]].ymax,
238 pScissorsInFixedPoint[pViewportIndex[11]].ymax,
239 pScissorsInFixedPoint[pViewportIndex[10]].ymax,
240 pScissorsInFixedPoint[pViewportIndex[9]].ymax,
241 pScissorsInFixedPoint[pViewportIndex[8]].ymax,
242 pScissorsInFixedPoint[pViewportIndex[7]].ymax,
243 pScissorsInFixedPoint[pViewportIndex[6]].ymax,
244 pScissorsInFixedPoint[pViewportIndex[5]].ymax,
245 pScissorsInFixedPoint[pViewportIndex[4]].ymax,
246 pScissorsInFixedPoint[pViewportIndex[3]].ymax,
247 pScissorsInFixedPoint[pViewportIndex[2]].ymax,
248 pScissorsInFixedPoint[pViewportIndex[1]].ymax,
249 pScissorsInFixedPoint[pViewportIndex[0]].ymax);
250 }