swr/rast: allow early-z if shader uses depth value
[mesa.git] / src / gallium / drivers / swr / rasterizer / core / binner.h
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 static const simdscalar g_pixelOffsets[SWR_PIXEL_LOCATION_UL + 1] =
35 {
36 _simd_set1_ps(0.0f), // SWR_PIXEL_LOCATION_CENTER
37 _simd_set1_ps(0.5f), // SWR_PIXEL_LOCATION_UL
38 };
39
40 #if USE_SIMD16_FRONTEND
41 static const simd16scalar g_pixelOffsets_simd16[SWR_PIXEL_LOCATION_UL + 1] =
42 {
43 _simd16_set1_ps(0.0f), // SWR_PIXEL_LOCATION_CENTER
44 _simd16_set1_ps(0.5f), // SWR_PIXEL_LOCATION_UL
45 };
46
47 #endif
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)
53 {
54 simdscalar vFixed = _simd_mul_ps(vIn, _simd_set1_ps(PT::ScaleT::value));
55 return _simd_cvtps_epi32(vFixed);
56 }
57
58 #if USE_SIMD16_FRONTEND
59 template <typename PT = FixedPointTraits<Fixed_16_8>>
60 INLINE simd16scalari fpToFixedPointVertical(const simd16scalar vIn)
61 {
62 simd16scalar vFixed = _simd16_mul_ps(vIn, _simd16_set1_ps(PT::ScaleT::value));
63 return _simd16_cvtps_epi32(vFixed);
64 }
65
66 #endif
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])
74 {
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);
81 }
82
83 #if USE_SIMD16_FRONTEND
84 INLINE static void FPToFixedPoint(const simd16vector * const tri, simd16scalari(&vXi)[3], simd16scalari(&vYi)[3])
85 {
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);
92 }
93
94 #endif
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)
105 {
106 simdscalari vMinX = vX[0];
107 vMinX = _simd_min_epi32(vMinX, vX[1]);
108 vMinX = _simd_min_epi32(vMinX, vX[2]);
109
110 simdscalari vMaxX = vX[0];
111 vMaxX = _simd_max_epi32(vMaxX, vX[1]);
112 vMaxX = _simd_max_epi32(vMaxX, vX[2]);
113
114 simdscalari vMinY = vY[0];
115 vMinY = _simd_min_epi32(vMinY, vY[1]);
116 vMinY = _simd_min_epi32(vMinY, vY[2]);
117
118 simdscalari vMaxY = vY[0];
119 vMaxY = _simd_max_epi32(vMaxY, vY[1]);
120 vMaxY = _simd_max_epi32(vMaxY, vY[2]);
121
122 bbox.xmin = vMinX;
123 bbox.xmax = vMaxX;
124 bbox.ymin = vMinY;
125 bbox.ymax = vMaxY;
126 }
127
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)
131 {
132 simd16scalari vMinX = vX[0];
133
134 vMinX = _simd16_min_epi32(vMinX, vX[1]);
135 vMinX = _simd16_min_epi32(vMinX, vX[2]);
136
137 simd16scalari vMaxX = vX[0];
138
139 vMaxX = _simd16_max_epi32(vMaxX, vX[1]);
140 vMaxX = _simd16_max_epi32(vMaxX, vX[2]);
141
142 simd16scalari vMinY = vY[0];
143
144 vMinY = _simd16_min_epi32(vMinY, vY[1]);
145 vMinY = _simd16_min_epi32(vMinY, vY[2]);
146
147 simd16scalari vMaxY = vY[0];
148
149 vMaxY = _simd16_max_epi32(vMaxY, vY[1]);
150 vMaxY = _simd16_max_epi32(vMaxY, vY[2]);
151
152 bbox.xmin = vMinX;
153 bbox.xmax = vMaxX;
154 bbox.ymin = vMinY;
155 bbox.ymax = vMaxY;
156 }
157
158 #endif
159 //////////////////////////////////////////////////////////////////////////
160 /// @brief FEConservativeRastT specialization of calcBoundingBoxIntVertical
161 /// Offsets BBox for conservative rast
162 template <>
163 INLINE void calcBoundingBoxIntVertical<FEConservativeRastT>(const simdvector * const tri, simdscalari(&vX)[3], simdscalari(&vY)[3], simdBBox &bbox)
164 {
165 // FE conservative rast traits
166 typedef FEConservativeRastT CT;
167
168 simdscalari vMinX = vX[0];
169 vMinX = _simd_min_epi32(vMinX, vX[1]);
170 vMinX = _simd_min_epi32(vMinX, vX[2]);
171
172 simdscalari vMaxX = vX[0];
173 vMaxX = _simd_max_epi32(vMaxX, vX[1]);
174 vMaxX = _simd_max_epi32(vMaxX, vX[2]);
175
176 simdscalari vMinY = vY[0];
177 vMinY = _simd_min_epi32(vMinY, vY[1]);
178 vMinY = _simd_min_epi32(vMinY, vY[2]);
179
180 simdscalari vMaxY = vY[0];
181 vMaxY = _simd_max_epi32(vMaxY, vY[1]);
182 vMaxY = _simd_max_epi32(vMaxY, vY[2]);
183
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));
190 }
191
192 #if USE_SIMD16_FRONTEND
193 template <>
194 INLINE void calcBoundingBoxIntVertical<FEConservativeRastT>(const simd16vector * const tri, simd16scalari(&vX)[3], simd16scalari(&vY)[3], simd16BBox &bbox)
195 {
196 // FE conservative rast traits
197 typedef FEConservativeRastT CT;
198
199 simd16scalari vMinX = vX[0];
200 vMinX = _simd16_min_epi32(vMinX, vX[1]);
201 vMinX = _simd16_min_epi32(vMinX, vX[2]);
202
203 simd16scalari vMaxX = vX[0];
204 vMaxX = _simd16_max_epi32(vMaxX, vX[1]);
205 vMaxX = _simd16_max_epi32(vMaxX, vX[2]);
206
207 simd16scalari vMinY = vY[0];
208 vMinY = _simd16_min_epi32(vMinY, vY[1]);
209 vMinY = _simd16_min_epi32(vMinY, vY[2]);
210
211 simd16scalari vMaxY = vY[0];
212 vMaxY = _simd16_max_epi32(vMaxY, vY[1]);
213 vMaxY = _simd16_max_epi32(vMaxY, vY[2]);
214
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));
221 }
222
223 #endif