swr/rast: code cleanup (no functional change)
[mesa.git] / src / gallium / drivers / swr / rasterizer / core / multisample.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 multisample.h
24 *
25 ******************************************************************************/
26
27 #pragma once
28
29 #include "context.h"
30 #include "format_traits.h"
31
32 //////////////////////////////////////////////////////////////////////////
33 /// @brief convenience typedef for testing for single sample case
34 typedef std::integral_constant<int, 1> SingleSampleT;
35
36 INLINE
37 uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount)
38 {
39 static const uint32_t sampleCountLUT[SWR_MULTISAMPLE_TYPE_COUNT] {1, 2, 4, 8, 16};
40 assert(sampleCount < SWR_MULTISAMPLE_TYPE_COUNT);
41 return sampleCountLUT[sampleCount];
42 }
43
44 INLINE
45 SWR_MULTISAMPLE_COUNT GetSampleCount(uint32_t numSamples)
46 {
47 switch(numSamples)
48 {
49 case 1: return SWR_MULTISAMPLE_1X;
50 case 2: return SWR_MULTISAMPLE_2X;
51 case 4: return SWR_MULTISAMPLE_4X;
52 case 8: return SWR_MULTISAMPLE_8X;
53 case 16: return SWR_MULTISAMPLE_16X;
54 default: assert(0); return SWR_MULTISAMPLE_1X;
55 }
56 }
57
58 // hardcoded offsets based on Direct3d standard multisample positions
59 // 8 x 8 pixel grid ranging from (0, 0) to (15, 15), with (0, 0) = UL pixel corner
60 // coords are 0.8 fixed point offsets from (0, 0)
61 template<SWR_MULTISAMPLE_COUNT sampleCount, bool isCenter = false>
62 struct MultisampleTraits
63 {
64 INLINE static float X(uint32_t sampleNum) = delete;
65 INLINE static float Y(uint32_t sampleNum) = delete;
66 INLINE static simdscalari FullSampleMask() = delete;
67
68 static const uint32_t numSamples = 0;
69 };
70
71 template<>
72 struct MultisampleTraits<SWR_MULTISAMPLE_1X, false>
73 {
74 INLINE static float X(uint32_t sampleNum) {return samplePosX[sampleNum];};
75 INLINE static float Y(uint32_t sampleNum) {return samplePosY[sampleNum];};
76 INLINE static simdscalari FullSampleMask(){return _simd_set1_epi32(0x1);};
77
78 static const uint32_t numSamples = 1;
79 static const uint32_t numCoverageSamples = 1;
80 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_1X;
81 static constexpr uint32_t samplePosXi[1] = { 0x80 };
82 static constexpr uint32_t samplePosYi[1] = { 0x80 };
83 static constexpr float samplePosX[1] = { 0.5f };
84 static constexpr float samplePosY[1] = { 0.5f };
85 };
86
87 template<>
88 struct MultisampleTraits<SWR_MULTISAMPLE_1X, true>
89 {
90 INLINE static float X(uint32_t sampleNum) {return 0.5f;};
91 INLINE static float Y(uint32_t sampleNum) {return 0.5f;};
92 INLINE static simdscalari FullSampleMask(){return _simd_set1_epi32(0x1);};
93
94 static const uint32_t numSamples = 1;
95 static const uint32_t numCoverageSamples = 1;
96 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_1X;
97 static constexpr uint32_t samplePosXi[1] = { 0x80 };
98 static constexpr uint32_t samplePosYi[1] = { 0x80 };
99 static constexpr float samplePosX[1] = { 0.5f };
100 static constexpr float samplePosY[1] = { 0.5f };
101 };
102
103 template<>
104 struct MultisampleTraits<SWR_MULTISAMPLE_2X, false>
105 {
106 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
107 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
108 INLINE static simdscalari FullSampleMask()
109 {
110 static const simdscalari mask =_simd_set1_epi32(0x3);
111 return mask;
112 }
113
114 static const uint32_t numSamples = 2;
115 static const uint32_t numCoverageSamples = 2;
116 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_2X;
117 static constexpr uint32_t samplePosXi[2] = { 0xC0, 0x40 };
118 static constexpr uint32_t samplePosYi[2] = { 0xC0, 0x40 };
119 static constexpr float samplePosX[2] = {0.75f, 0.25f};
120 static constexpr float samplePosY[2] = {0.75f, 0.25f};
121 };
122
123 template<>
124 struct MultisampleTraits<SWR_MULTISAMPLE_2X, true>
125 {
126 INLINE static float X(uint32_t sampleNum) {return 0.5f;};
127 INLINE static float Y(uint32_t sampleNum) {return 0.5f;};
128 INLINE static simdscalari FullSampleMask()
129 {
130 static const simdscalari mask =_simd_set1_epi32(0x3);
131 return mask;
132 }
133 static const uint32_t numSamples = 2;
134 static const uint32_t numCoverageSamples = 1;
135 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_2X;
136 static constexpr uint32_t samplePosXi[2] = { 0x80 , 0x80 };
137 static constexpr uint32_t samplePosYi[2] = { 0x80 , 0x80 };
138 static constexpr float samplePosX[2] = { 0.5f, 0.5f };
139 static constexpr float samplePosY[2] = { 0.5f, 0.5f };
140 };
141
142 template<>
143 struct MultisampleTraits<SWR_MULTISAMPLE_4X, false>
144 {
145 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
146 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
147 INLINE static simdscalari FullSampleMask()
148 {
149 static const simdscalari mask = _simd_set1_epi32(0xF);
150 return mask;
151 }
152
153 static const uint32_t numSamples = 4;
154 static const uint32_t numCoverageSamples = 4;
155 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_4X;
156 static constexpr uint32_t samplePosXi[4] = { 0x60, 0xE0, 0x20, 0xA0 };
157 static constexpr uint32_t samplePosYi[4] = { 0x20, 0x60, 0xA0, 0xE0 };
158 static constexpr float samplePosX[4] = { 0.375f, 0.875f, 0.125f, 0.625f };
159 static constexpr float samplePosY[4] = { 0.125f, 0.375f, 0.625f, 0.875f };
160 };
161
162 template<>
163 struct MultisampleTraits<SWR_MULTISAMPLE_4X, true>
164 {
165 INLINE static float X(uint32_t sampleNum) {return 0.5f;};
166 INLINE static float Y(uint32_t sampleNum) {return 0.5f;};
167 INLINE static simdscalari FullSampleMask()
168 {
169 static const simdscalari mask = _simd_set1_epi32(0xF);
170 return mask;
171 }
172
173 static const uint32_t numSamples = 4;
174 static const uint32_t numCoverageSamples = 1;
175 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_4X;
176 static constexpr uint32_t samplePosXi[4] = { 0x80, 0x80, 0x80, 0x80 };
177 static constexpr uint32_t samplePosYi[4] = { 0x80, 0x80, 0x80, 0x80 };
178 static constexpr float samplePosX[4] = { 0.5f, 0.5f, 0.5f, 0.5f };
179 static constexpr float samplePosY[4] = { 0.5f, 0.5f, 0.5f, 0.5f };
180 };
181
182 template<>
183 struct MultisampleTraits<SWR_MULTISAMPLE_8X, false>
184 {
185 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
186 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
187 INLINE static simdscalari FullSampleMask()
188 {
189 static const simdscalari mask = _simd_set1_epi32(0xFF);
190 return mask;
191 }
192
193 static const uint32_t numSamples = 8;
194 static const uint32_t numCoverageSamples = 8;
195 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_8X;
196 static constexpr uint32_t samplePosXi[8] = { 0x90, 0x70, 0xD0, 0x50, 0x30, 0x10, 0xB0, 0xF0 };
197 static constexpr uint32_t samplePosYi[8] = { 0x50, 0xB0, 0x90, 0x30, 0xD0, 0x70, 0xF0, 0x10 };
198 static constexpr float samplePosX[8] = { 0.5625f, 0.4375f, 0.8125f, 0.3125f, 0.1875f, 0.0625f, 0.6875f, 0.9375f };
199 static constexpr float samplePosY[8] = { 0.3125f, 0.6875f, 0.5625f, 0.1875f, 0.8125f, 0.4375f, 0.9375f, 0.0625f };
200 };
201
202 template<>
203 struct MultisampleTraits<SWR_MULTISAMPLE_8X, true>
204 {
205 INLINE static float X(uint32_t sampleNum) {return 0.5f;};
206 INLINE static float Y(uint32_t sampleNum) {return 0.5f;};
207 INLINE static simdscalari FullSampleMask()
208 {
209 static const simdscalari mask = _simd_set1_epi32(0xFF);
210 return mask;
211 }
212 static const uint32_t numSamples = 8;
213 static const uint32_t numCoverageSamples = 1;
214 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_8X;
215 static constexpr uint32_t samplePosXi[8] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
216 static constexpr uint32_t samplePosYi[8] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
217 static constexpr float samplePosX[8] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };
218 static constexpr float samplePosY[8] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };
219 };
220
221 template<>
222 struct MultisampleTraits<SWR_MULTISAMPLE_16X, false>
223 {
224 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
225 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
226 INLINE static simdscalari FullSampleMask()
227 {
228 static const simdscalari mask = _simd_set1_epi32(0xFFFF);
229 return mask;
230 }
231
232 static const uint32_t numSamples = 16;
233 static const uint32_t numCoverageSamples = 16;
234 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_16X;
235 static constexpr uint32_t samplePosXi[16] = { 0x90, 0x70, 0x50, 0xC0, 0x30, 0xA0, 0xD0, 0xB0, 0x60, 0x80, 0x40, 0x20, 0x00, 0xF0, 0xE0, 0x10 };
236 static constexpr uint32_t samplePosYi[16] = { 0x90, 0x50, 0xA0, 0x70, 0x60, 0xD0, 0xB0, 0x30, 0xE0, 0x10, 0x20, 0xC0, 0x80, 0x40, 0xF0, 0x00 };
237 static constexpr float samplePosX[16] = { 0.5625f, 0.4375f, 0.3125f, 0.7500f, 0.1875f, 0.6250f, 0.8125f, 0.6875f, 0.3750f, 0.5000f, 0.2500f, 0.1250f, 0.0000f, 0.9375f, 0.8750f, 0.0625f };
238 static constexpr float samplePosY[16] = { 0.5625f, 0.3125f, 0.6250f, 0.4375f, 0.3750f, 0.8125f, 0.6875f, 0.1875f, 0.8750f, 0.0625f, 0.1250f, 0.7500f, 0.5000f, 0.2500f, 0.9375f, 0.0000f };
239 };
240
241 template<>
242 struct MultisampleTraits<SWR_MULTISAMPLE_16X, true>
243 {
244 INLINE static float X(uint32_t sampleNum) {return 0.5f;};
245 INLINE static float Y(uint32_t sampleNum) {return 0.5f;};
246 INLINE static simdscalari FullSampleMask()
247 {
248 static const simdscalari mask = _simd_set1_epi32(0xFFFF);
249 return mask;
250 }
251 static const uint32_t numSamples = 16;
252 static const uint32_t numCoverageSamples = 1;
253 static const SWR_MULTISAMPLE_COUNT sampleCount = SWR_MULTISAMPLE_16X;
254 static constexpr uint32_t samplePosXi[16] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
255 static constexpr uint32_t samplePosYi[16] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
256 static constexpr float samplePosX[16] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };
257 static constexpr float samplePosY[16] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };
258 };
259
260 INLINE
261 bool isNonStandardPattern(const SWR_MULTISAMPLE_COUNT sampleCount, const SWR_MULTISAMPLE_POS& samplePos)
262 {
263 // detect if we're using standard or center sample patterns
264 const uint32_t *standardPosX, *standardPosY;
265 switch(sampleCount)
266 {
267 case SWR_MULTISAMPLE_1X:
268 standardPosX = MultisampleTraits<SWR_MULTISAMPLE_1X>::samplePosXi;
269 standardPosY = MultisampleTraits<SWR_MULTISAMPLE_1X>::samplePosYi;
270 break;
271 case SWR_MULTISAMPLE_2X:
272 standardPosX = MultisampleTraits<SWR_MULTISAMPLE_2X>::samplePosXi;
273 standardPosY = MultisampleTraits<SWR_MULTISAMPLE_2X>::samplePosYi;
274 break;
275 case SWR_MULTISAMPLE_4X:
276 standardPosX = MultisampleTraits<SWR_MULTISAMPLE_4X>::samplePosXi;
277 standardPosY = MultisampleTraits<SWR_MULTISAMPLE_4X>::samplePosYi;
278 break;
279 case SWR_MULTISAMPLE_8X:
280 standardPosX = MultisampleTraits<SWR_MULTISAMPLE_8X>::samplePosXi;
281 standardPosY = MultisampleTraits<SWR_MULTISAMPLE_8X>::samplePosYi;
282 break;
283 case SWR_MULTISAMPLE_16X:
284 standardPosX = MultisampleTraits<SWR_MULTISAMPLE_16X>::samplePosXi;
285 standardPosY = MultisampleTraits<SWR_MULTISAMPLE_16X>::samplePosYi;
286 break;
287 default:
288 break;
289 }
290
291 // scan sample pattern for standard or center
292 uint32_t numSamples = GetNumSamples(sampleCount);
293 bool bIsStandard = true;
294 if(numSamples > 1)
295 {
296 for(uint32_t i = 0; i < numSamples; i++)
297 {
298 bIsStandard = (standardPosX[i] == samplePos.Xi(i)) ||
299 (standardPosY[i] == samplePos.Yi(i));
300 if(!bIsStandard)
301 break;
302 }
303 }
304 return !bIsStandard;
305 }