1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
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:
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
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
25 * @brief Declaration for the macrotile binner
27 ******************************************************************************/
29 #include "conservativeRast.h"
31 //////////////////////////////////////////////////////////////////////////
32 /// @brief Offsets added to post-viewport vertex positions based on
34 static const simdscalar g_pixelOffsets
[SWR_PIXEL_LOCATION_UL
+ 1] =
36 _simd_set1_ps(0.0f
), // SWR_PIXEL_LOCATION_CENTER
37 _simd_set1_ps(0.5f
), // SWR_PIXEL_LOCATION_UL
40 #if USE_SIMD16_FRONTEND
41 static const simd16scalar g_pixelOffsets_simd16
[SWR_PIXEL_LOCATION_UL
+ 1] =
43 _simd16_set1_ps(0.0f
), // SWR_PIXEL_LOCATION_CENTER
44 _simd16_set1_ps(0.5f
), // SWR_PIXEL_LOCATION_UL
48 //////////////////////////////////////////////////////////////////////////
49 /// @brief Convert the X,Y coords of a triangle to the requested Fixed
50 /// Point precision from FP32.
51 template <typename PT
= FixedPointTraits
<Fixed_16_8
>>
52 INLINE simdscalari
fpToFixedPointVertical(const simdscalar vIn
)
54 simdscalar vFixed
= _simd_mul_ps(vIn
, _simd_set1_ps(PT::ScaleT::value
));
55 return _simd_cvtps_epi32(vFixed
);
58 #if USE_SIMD16_FRONTEND
59 template <typename PT
= FixedPointTraits
<Fixed_16_8
>>
60 INLINE simd16scalari
fpToFixedPointVertical(const simd16scalar vIn
)
62 simd16scalar vFixed
= _simd16_mul_ps(vIn
, _simd16_set1_ps(PT::ScaleT::value
));
63 return _simd16_cvtps_epi32(vFixed
);
67 //////////////////////////////////////////////////////////////////////////
68 /// @brief Helper function to set the X,Y coords of a triangle to the
69 /// requested Fixed Point precision from FP32.
70 /// @param tri: simdvector[3] of FP triangle verts
71 /// @param vXi: fixed point X coords of tri verts
72 /// @param vYi: fixed point Y coords of tri verts
73 INLINE
static void FPToFixedPoint(const simdvector
* const tri
, simdscalari(&vXi
)[3], simdscalari(&vYi
)[3])
75 vXi
[0] = fpToFixedPointVertical(tri
[0].x
);
76 vYi
[0] = fpToFixedPointVertical(tri
[0].y
);
77 vXi
[1] = fpToFixedPointVertical(tri
[1].x
);
78 vYi
[1] = fpToFixedPointVertical(tri
[1].y
);
79 vXi
[2] = fpToFixedPointVertical(tri
[2].x
);
80 vYi
[2] = fpToFixedPointVertical(tri
[2].y
);
83 #if USE_SIMD16_FRONTEND
84 INLINE
static void FPToFixedPoint(const simd16vector
* const tri
, simd16scalari(&vXi
)[3], simd16scalari(&vYi
)[3])
86 vXi
[0] = fpToFixedPointVertical(tri
[0].x
);
87 vYi
[0] = fpToFixedPointVertical(tri
[0].y
);
88 vXi
[1] = fpToFixedPointVertical(tri
[1].x
);
89 vYi
[1] = fpToFixedPointVertical(tri
[1].y
);
90 vXi
[2] = fpToFixedPointVertical(tri
[2].x
);
91 vYi
[2] = fpToFixedPointVertical(tri
[2].y
);
95 //////////////////////////////////////////////////////////////////////////
96 /// @brief Calculate bounding box for current triangle
97 /// @tparam CT: ConservativeRastFETraits type
98 /// @param vX: fixed point X position for triangle verts
99 /// @param vY: fixed point Y position for triangle verts
100 /// @param bbox: fixed point bbox
101 /// *Note*: expects vX, vY to be in the correct precision for the type
102 /// of rasterization. This avoids unnecessary FP->fixed conversions.
103 template <typename CT
>
104 INLINE
void calcBoundingBoxIntVertical(const simdvector
* const tri
, simdscalari(&vX
)[3], simdscalari(&vY
)[3], simdBBox
&bbox
)
106 simdscalari vMinX
= vX
[0];
107 vMinX
= _simd_min_epi32(vMinX
, vX
[1]);
108 vMinX
= _simd_min_epi32(vMinX
, vX
[2]);
110 simdscalari vMaxX
= vX
[0];
111 vMaxX
= _simd_max_epi32(vMaxX
, vX
[1]);
112 vMaxX
= _simd_max_epi32(vMaxX
, vX
[2]);
114 simdscalari vMinY
= vY
[0];
115 vMinY
= _simd_min_epi32(vMinY
, vY
[1]);
116 vMinY
= _simd_min_epi32(vMinY
, vY
[2]);
118 simdscalari vMaxY
= vY
[0];
119 vMaxY
= _simd_max_epi32(vMaxY
, vY
[1]);
120 vMaxY
= _simd_max_epi32(vMaxY
, vY
[2]);
128 #if USE_SIMD16_FRONTEND
129 template <typename CT
>
130 INLINE
void calcBoundingBoxIntVertical(const simd16vector
* const tri
, simd16scalari(&vX
)[3], simd16scalari(&vY
)[3], simd16BBox
&bbox
)
132 simd16scalari vMinX
= vX
[0];
134 vMinX
= _simd16_min_epi32(vMinX
, vX
[1]);
135 vMinX
= _simd16_min_epi32(vMinX
, vX
[2]);
137 simd16scalari vMaxX
= vX
[0];
139 vMaxX
= _simd16_max_epi32(vMaxX
, vX
[1]);
140 vMaxX
= _simd16_max_epi32(vMaxX
, vX
[2]);
142 simd16scalari vMinY
= vY
[0];
144 vMinY
= _simd16_min_epi32(vMinY
, vY
[1]);
145 vMinY
= _simd16_min_epi32(vMinY
, vY
[2]);
147 simd16scalari vMaxY
= vY
[0];
149 vMaxY
= _simd16_max_epi32(vMaxY
, vY
[1]);
150 vMaxY
= _simd16_max_epi32(vMaxY
, vY
[2]);
159 //////////////////////////////////////////////////////////////////////////
160 /// @brief FEConservativeRastT specialization of calcBoundingBoxIntVertical
161 /// Offsets BBox for conservative rast
163 INLINE
void calcBoundingBoxIntVertical
<FEConservativeRastT
>(const simdvector
* const tri
, simdscalari(&vX
)[3], simdscalari(&vY
)[3], simdBBox
&bbox
)
165 // FE conservative rast traits
166 typedef FEConservativeRastT CT
;
168 simdscalari vMinX
= vX
[0];
169 vMinX
= _simd_min_epi32(vMinX
, vX
[1]);
170 vMinX
= _simd_min_epi32(vMinX
, vX
[2]);
172 simdscalari vMaxX
= vX
[0];
173 vMaxX
= _simd_max_epi32(vMaxX
, vX
[1]);
174 vMaxX
= _simd_max_epi32(vMaxX
, vX
[2]);
176 simdscalari vMinY
= vY
[0];
177 vMinY
= _simd_min_epi32(vMinY
, vY
[1]);
178 vMinY
= _simd_min_epi32(vMinY
, vY
[2]);
180 simdscalari vMaxY
= vY
[0];
181 vMaxY
= _simd_max_epi32(vMaxY
, vY
[1]);
182 vMaxY
= _simd_max_epi32(vMaxY
, vY
[2]);
184 /// Bounding box needs to be expanded by 1/512 before snapping to 16.8 for conservative rasterization
185 /// expand bbox by 1/256; coverage will be correctly handled in the rasterizer.
186 bbox
.xmin
= _simd_sub_epi32(vMinX
, _simd_set1_epi32(CT::BoundingBoxOffsetT::value
));
187 bbox
.xmax
= _simd_add_epi32(vMaxX
, _simd_set1_epi32(CT::BoundingBoxOffsetT::value
));
188 bbox
.ymin
= _simd_sub_epi32(vMinY
, _simd_set1_epi32(CT::BoundingBoxOffsetT::value
));
189 bbox
.ymax
= _simd_add_epi32(vMaxY
, _simd_set1_epi32(CT::BoundingBoxOffsetT::value
));
192 #if USE_SIMD16_FRONTEND
194 INLINE
void calcBoundingBoxIntVertical
<FEConservativeRastT
>(const simd16vector
* const tri
, simd16scalari(&vX
)[3], simd16scalari(&vY
)[3], simd16BBox
&bbox
)
196 // FE conservative rast traits
197 typedef FEConservativeRastT CT
;
199 simd16scalari vMinX
= vX
[0];
200 vMinX
= _simd16_min_epi32(vMinX
, vX
[1]);
201 vMinX
= _simd16_min_epi32(vMinX
, vX
[2]);
203 simd16scalari vMaxX
= vX
[0];
204 vMaxX
= _simd16_max_epi32(vMaxX
, vX
[1]);
205 vMaxX
= _simd16_max_epi32(vMaxX
, vX
[2]);
207 simd16scalari vMinY
= vY
[0];
208 vMinY
= _simd16_min_epi32(vMinY
, vY
[1]);
209 vMinY
= _simd16_min_epi32(vMinY
, vY
[2]);
211 simd16scalari vMaxY
= vY
[0];
212 vMaxY
= _simd16_max_epi32(vMaxY
, vY
[1]);
213 vMaxY
= _simd16_max_epi32(vMaxY
, vY
[2]);
215 /// Bounding box needs to be expanded by 1/512 before snapping to 16.8 for conservative rasterization
216 /// expand bbox by 1/256; coverage will be correctly handled in the rasterizer.
217 bbox
.xmin
= _simd16_sub_epi32(vMinX
, _simd16_set1_epi32(CT::BoundingBoxOffsetT::value
));
218 bbox
.xmax
= _simd16_add_epi32(vMaxX
, _simd16_set1_epi32(CT::BoundingBoxOffsetT::value
));
219 bbox
.ymin
= _simd16_sub_epi32(vMinY
, _simd16_set1_epi32(CT::BoundingBoxOffsetT::value
));
220 bbox
.ymax
= _simd16_add_epi32(vMaxY
, _simd16_set1_epi32(CT::BoundingBoxOffsetT::value
));