gallium/swr: add OpenSWR rasterizer
[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 INLINE
33 uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount)
34 {
35 static const uint32_t sampleCountLUT[SWR_MULTISAMPLE_TYPE_MAX] {1, 2, 4, 8, 16};
36 assert(sampleCount < SWR_MULTISAMPLE_TYPE_MAX);
37 return sampleCountLUT[sampleCount];
38 }
39
40 INLINE
41 SWR_MULTISAMPLE_COUNT GetSampleCount(uint32_t numSamples)
42 {
43 switch(numSamples)
44 {
45 case 1: return SWR_MULTISAMPLE_1X;
46 case 2: return SWR_MULTISAMPLE_2X;
47 case 4: return SWR_MULTISAMPLE_4X;
48 case 8: return SWR_MULTISAMPLE_8X;
49 case 16: return SWR_MULTISAMPLE_16X;
50 default: assert(0); return SWR_MULTISAMPLE_1X;
51 }
52 }
53
54 // hardcoded offsets based on Direct3d standard multisample positions
55 // 8 x 8 pixel grid ranging from (0, 0) to (15, 15), with (0, 0) = UL pixel corner
56 // coords are 0.8 fixed point offsets from (0, 0)
57 template<SWR_MULTISAMPLE_COUNT sampleCount>
58 struct MultisampleTraits
59 {
60 INLINE static __m128i vXi(uint32_t sampleNum) = delete;
61 INLINE static __m128i vYi(uint32_t sampleNum) = delete;
62 INLINE static simdscalar vX(uint32_t sampleNum) = delete;
63 INLINE static simdscalar vY(uint32_t sampleNum) = delete;
64 INLINE static float X(uint32_t sampleNum) = delete;
65 INLINE static float Y(uint32_t sampleNum) = delete;
66 INLINE static __m128i TileSampleOffsetsX() = delete;
67 INLINE static __m128i TileSampleOffsetsY() = delete;
68 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum) = delete;
69 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum) = delete;
70 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum) = delete;
71 INLINE static simdscalari FullSampleMask() = delete;
72
73 static const uint32_t numSamples = 0;
74 };
75
76 template<>
77 struct MultisampleTraits<SWR_MULTISAMPLE_1X>
78 {
79 INLINE static __m128i vXi(uint32_t sampleNum)
80 {
81 static const __m128i X = _mm_set1_epi32(samplePosXi);
82 return X;
83 }
84
85 INLINE static __m128i vYi(uint32_t sampleNum)
86 {
87 static const __m128i Y = _mm_set1_epi32(samplePosYi);
88 return Y;
89 }
90
91 INLINE static simdscalar vX(uint32_t sampleNum)
92 {
93 static const simdscalar X = _simd_set1_ps(0.5f);
94 return X;
95 }
96
97 INLINE static simdscalar vY(uint32_t sampleNum)
98 {
99 static const simdscalar Y = _simd_set1_ps(0.5f);
100 return Y;
101 }
102
103 INLINE static float X(uint32_t sampleNum) {return samplePosX;};
104 INLINE static float Y(uint32_t sampleNum) {return samplePosY;};
105
106 INLINE static __m128i TileSampleOffsetsX()
107 {
108 static const uint32_t bboxLeftEdge = 0x80;
109 static const uint32_t bboxRightEdge = 0x80;
110 // BR, BL, UR, UL
111 static const __m128i tileSampleOffsetX = _mm_set_epi32(bboxRightEdge, bboxLeftEdge, bboxRightEdge, bboxLeftEdge);
112 return tileSampleOffsetX;
113 }
114
115 INLINE static __m128i TileSampleOffsetsY()
116 {
117 static const uint32_t bboxTopEdge = 0x80;
118 static const uint32_t bboxBottomEdge = 0x80;
119 // BR, BL, UR, UL
120 static const __m128i tileSampleOffsetY = _mm_set_epi32(bboxBottomEdge, bboxBottomEdge, bboxTopEdge, bboxTopEdge);
121 return tileSampleOffsetY;
122 }
123
124 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum)
125 {
126 return 0;
127 }
128
129 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum)
130 {
131 return 0;
132 }
133
134 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum)
135 {
136 return 0;
137 }
138
139 INLINE static simdscalari FullSampleMask(){return _simd_set1_epi32(0x1);};
140
141 static const uint32_t samplePosXi {0x80};
142 static const uint32_t samplePosYi {0x80};
143 static const float samplePosX;
144 static const float samplePosY;
145 static const uint32_t numSamples = 1;
146 };
147
148 template<>
149 struct MultisampleTraits<SWR_MULTISAMPLE_2X>
150 {
151 INLINE static __m128i vXi(uint32_t sampleNum)
152 {
153 SWR_ASSERT(sampleNum < numSamples);
154 static const __m128i X[numSamples] {_mm_set1_epi32(samplePosXi[0]), _mm_set1_epi32(samplePosXi[1])};
155 return X[sampleNum];
156 }
157
158 INLINE static __m128i vYi(uint32_t sampleNum)
159 {
160 SWR_ASSERT(sampleNum < numSamples);
161 static const __m128i Y[numSamples] {_mm_set1_epi32(samplePosYi[0]), _mm_set1_epi32(samplePosYi[1])};
162 return Y[sampleNum];
163 }
164
165 INLINE static simdscalar vX(uint32_t sampleNum)
166 {
167 static const simdscalar X[numSamples] {_simd_set1_ps(0.75f), _simd_set1_ps(0.25f)};
168 assert(sampleNum < numSamples);
169 return X[sampleNum];
170 }
171
172 INLINE static simdscalar vY(uint32_t sampleNum)
173 {
174 static const simdscalar Y[numSamples] {_simd_set1_ps(0.75f), _simd_set1_ps(0.25f)};
175 assert(sampleNum < numSamples);
176 return Y[sampleNum];
177 }
178
179 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
180 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
181
182 INLINE static __m128i TileSampleOffsetsX()
183 {
184 static const uint32_t bboxLeftEdge = 0x40;
185 static const uint32_t bboxRightEdge = 0xC0;
186 // BR, BL, UR, UL
187 static const __m128i tileSampleOffsetX = _mm_set_epi32(bboxRightEdge, bboxLeftEdge, bboxRightEdge, bboxLeftEdge);
188 return tileSampleOffsetX;
189 }
190
191 INLINE static __m128i TileSampleOffsetsY()
192 {
193 static const uint32_t bboxTopEdge = 0x40;
194 static const uint32_t bboxBottomEdge = 0xC0;
195 // BR, BL, UR, UL
196 static const __m128i tileSampleOffsetY = _mm_set_epi32(bboxBottomEdge, bboxBottomEdge, bboxTopEdge, bboxTopEdge);
197 return tileSampleOffsetY;
198 }
199
200 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum)
201 {
202 static const uint32_t RasterTileColorOffsets[numSamples]
203 { 0,
204 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8)
205 };
206 assert(sampleNum < numSamples);
207 return RasterTileColorOffsets[sampleNum];
208 }
209
210 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum)
211 {
212 static const uint32_t RasterTileDepthOffsets[numSamples]
213 { 0,
214 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8)
215 };
216 assert(sampleNum < numSamples);
217 return RasterTileDepthOffsets[sampleNum];
218 }
219
220 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum)
221 {
222 static const uint32_t RasterTileStencilOffsets[numSamples]
223 { 0,
224 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8)
225 };
226 assert(sampleNum < numSamples);
227 return RasterTileStencilOffsets[sampleNum];
228 }
229
230 INLINE static simdscalari FullSampleMask()
231 {
232 static const simdscalari mask =_simd_set1_epi32(0x3);
233 return mask;
234 }
235
236 static const uint32_t samplePosXi[2];
237 static const uint32_t samplePosYi[2];
238 static const float samplePosX[2];
239 static const float samplePosY[2];
240 static const uint32_t numSamples = 2;
241 };
242
243 template<>
244 struct MultisampleTraits<SWR_MULTISAMPLE_4X>
245 {
246 INLINE static __m128i vXi(uint32_t sampleNum)
247 {
248 static const __m128i X[numSamples]
249 {_mm_set1_epi32(samplePosXi[0]), _mm_set1_epi32(samplePosXi[1]), _mm_set1_epi32(samplePosXi[2]), _mm_set1_epi32(samplePosXi[3])};
250 SWR_ASSERT(sampleNum < numSamples);
251 return X[sampleNum];
252 }
253
254 INLINE static __m128i vYi(uint32_t sampleNum)
255 {
256 static const __m128i Y[numSamples]
257 {_mm_set1_epi32(samplePosYi[0]), _mm_set1_epi32(samplePosYi[1]), _mm_set1_epi32(samplePosYi[2]), _mm_set1_epi32(samplePosYi[3])};
258 SWR_ASSERT(sampleNum < numSamples);
259 return Y[sampleNum];
260 }
261
262 INLINE static simdscalar vX(uint32_t sampleNum)
263 {
264 static const simdscalar X[numSamples]
265 {_simd_set1_ps(0.375f), _simd_set1_ps(0.875), _simd_set1_ps(0.125), _simd_set1_ps(0.625)};
266 assert(sampleNum < numSamples);
267 return X[sampleNum];
268 }
269
270 INLINE static simdscalar vY(uint32_t sampleNum)
271 {
272 static const simdscalar Y[numSamples]
273 {_simd_set1_ps(0.125), _simd_set1_ps(0.375f), _simd_set1_ps(0.625), _simd_set1_ps(0.875)};
274 assert(sampleNum < numSamples);
275 return Y[sampleNum];
276 }
277
278 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
279 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
280
281 INLINE static __m128i TileSampleOffsetsX()
282 {
283 static const uint32_t bboxLeftEdge = 0x20;
284 static const uint32_t bboxRightEdge = 0xE0;
285 // BR, BL, UR, UL
286 static const __m128i tileSampleOffsetX = _mm_set_epi32(bboxRightEdge, bboxLeftEdge, bboxRightEdge, bboxLeftEdge);
287 return tileSampleOffsetX;
288 }
289
290 INLINE static __m128i TileSampleOffsetsY()
291 {
292 static const uint32_t bboxTopEdge = 0x20;
293 static const uint32_t bboxBottomEdge = 0xE0;
294 // BR, BL, UR, UL
295 static const __m128i tileSampleOffsetY = _mm_set_epi32(bboxBottomEdge, bboxBottomEdge, bboxTopEdge, bboxTopEdge);
296 return tileSampleOffsetY;
297 }
298
299 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum)
300 {
301 static const uint32_t RasterTileColorOffsets[numSamples]
302 { 0,
303 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8),
304 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 2,
305 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 3,
306 };
307 assert(sampleNum < numSamples);
308 return RasterTileColorOffsets[sampleNum];
309 }
310
311 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum)
312 {
313 static const uint32_t RasterTileDepthOffsets[numSamples]
314 { 0,
315 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8),
316 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 2,
317 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 3,
318 };
319 assert(sampleNum < numSamples);
320 return RasterTileDepthOffsets[sampleNum];
321 }
322
323 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum)
324 {
325 static const uint32_t RasterTileStencilOffsets[numSamples]
326 { 0,
327 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8),
328 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 2,
329 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 3,
330 };
331 assert(sampleNum < numSamples);
332 return RasterTileStencilOffsets[sampleNum];
333 }
334
335 INLINE static simdscalari FullSampleMask()
336 {
337 static const simdscalari mask = _simd_set1_epi32(0xF);
338 return mask;
339 }
340
341 static const uint32_t samplePosXi[4];
342 static const uint32_t samplePosYi[4];
343 static const float samplePosX[4];
344 static const float samplePosY[4];
345 static const uint32_t numSamples = 4;
346 };
347
348 template<>
349 struct MultisampleTraits<SWR_MULTISAMPLE_8X>
350 {
351 INLINE static __m128i vXi(uint32_t sampleNum)
352 {
353 static const __m128i X[numSamples]
354 {_mm_set1_epi32(samplePosXi[0]), _mm_set1_epi32(samplePosXi[1]), _mm_set1_epi32(samplePosXi[2]), _mm_set1_epi32(samplePosXi[3]),
355 _mm_set1_epi32(samplePosXi[4]), _mm_set1_epi32(samplePosXi[5]), _mm_set1_epi32(samplePosXi[6]), _mm_set1_epi32(samplePosXi[7])};
356 SWR_ASSERT(sampleNum < numSamples);
357 return X[sampleNum];
358 }
359
360 INLINE static __m128i vYi(uint32_t sampleNum)
361 {
362 static const __m128i Y[numSamples]
363 {_mm_set1_epi32(samplePosYi[0]), _mm_set1_epi32(samplePosYi[1]), _mm_set1_epi32(samplePosYi[2]), _mm_set1_epi32(samplePosYi[3]),
364 _mm_set1_epi32(samplePosYi[4]), _mm_set1_epi32(samplePosYi[5]), _mm_set1_epi32(samplePosYi[6]), _mm_set1_epi32(samplePosYi[7])};
365 SWR_ASSERT(sampleNum < numSamples);
366 return Y[sampleNum];
367 }
368
369 INLINE static simdscalar vX(uint32_t sampleNum)
370 {
371 static const simdscalar X[numSamples]
372 {_simd_set1_ps(0.5625), _simd_set1_ps(0.4375), _simd_set1_ps(0.8125), _simd_set1_ps(0.3125),
373 _simd_set1_ps(0.1875), _simd_set1_ps(0.0625), _simd_set1_ps(0.6875), _simd_set1_ps(0.9375)};
374 assert(sampleNum < numSamples);
375 return X[sampleNum];
376 }
377
378 INLINE static simdscalar vY(uint32_t sampleNum)
379 {
380 static const simdscalar Y[numSamples]
381 {_simd_set1_ps(0.3125), _simd_set1_ps(0.6875), _simd_set1_ps(0.5625), _simd_set1_ps(0.1875),
382 _simd_set1_ps(0.8125), _simd_set1_ps(0.4375), _simd_set1_ps(0.9375), _simd_set1_ps(0.0625)};
383 assert(sampleNum < numSamples);
384 return Y[sampleNum];
385 }
386
387 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
388 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
389
390 INLINE static __m128i TileSampleOffsetsX()
391 {
392 static const uint32_t bboxLeftEdge = 0x10;
393 static const uint32_t bboxRightEdge = 0xF0;
394 // BR, BL, UR, UL
395 static const __m128i tileSampleOffsetX = _mm_set_epi32(bboxRightEdge, bboxLeftEdge, bboxRightEdge, bboxLeftEdge);
396 return tileSampleOffsetX;
397 }
398
399 INLINE static __m128i TileSampleOffsetsY()
400 {
401 static const uint32_t bboxTopEdge = 0x10;
402 static const uint32_t bboxBottomEdge = 0xF0;
403 // BR, BL, UR, UL
404 static const __m128i tileSampleOffsetY = _mm_set_epi32(bboxBottomEdge, bboxBottomEdge, bboxTopEdge, bboxTopEdge);
405 return tileSampleOffsetY;
406 }
407
408 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum)
409 {
410 static const uint32_t RasterTileColorOffsets[numSamples]
411 { 0,
412 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8),
413 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 2,
414 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 3,
415 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 4,
416 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 5,
417 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 6,
418 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 7,
419 };
420 assert(sampleNum < numSamples);
421 return RasterTileColorOffsets[sampleNum];
422 }
423
424 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum)
425 {
426 static const uint32_t RasterTileDepthOffsets[numSamples]
427 { 0,
428 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8),
429 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 2,
430 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 3,
431 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 4,
432 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 5,
433 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 6,
434 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 7,
435 };
436 assert(sampleNum < numSamples);
437 return RasterTileDepthOffsets[sampleNum];
438 }
439
440 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum)
441 {
442 static const uint32_t RasterTileStencilOffsets[numSamples]
443 { 0,
444 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8),
445 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 2,
446 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 3,
447 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 4,
448 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 5,
449 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 6,
450 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 7,
451 };
452 assert(sampleNum < numSamples);
453 return RasterTileStencilOffsets[sampleNum];
454 }
455
456 INLINE static simdscalari FullSampleMask()
457 {
458 static const simdscalari mask = _simd_set1_epi32(0xFF);
459 return mask;
460 }
461
462 static const uint32_t samplePosXi[8];
463 static const uint32_t samplePosYi[8];
464 static const float samplePosX[8];
465 static const float samplePosY[8];
466 static const uint32_t numSamples = 8;
467 };
468
469 template<>
470 struct MultisampleTraits<SWR_MULTISAMPLE_16X>
471 {
472 INLINE static __m128i vXi(uint32_t sampleNum)
473 {
474 static const __m128i X[numSamples]
475 {_mm_set1_epi32(samplePosXi[0]), _mm_set1_epi32(samplePosXi[1]), _mm_set1_epi32(samplePosXi[2]), _mm_set1_epi32(samplePosXi[3]),
476 _mm_set1_epi32(samplePosXi[4]), _mm_set1_epi32(samplePosXi[5]), _mm_set1_epi32(samplePosXi[6]), _mm_set1_epi32(samplePosXi[7]),
477 _mm_set1_epi32(samplePosXi[8]), _mm_set1_epi32(samplePosXi[9]), _mm_set1_epi32(samplePosXi[10]), _mm_set1_epi32(samplePosXi[11]),
478 _mm_set1_epi32(samplePosXi[12]), _mm_set1_epi32(samplePosXi[13]), _mm_set1_epi32(samplePosXi[14]), _mm_set1_epi32(samplePosXi[15])};
479 SWR_ASSERT(sampleNum < numSamples);
480 return X[sampleNum];
481 }
482
483 INLINE static __m128i vYi(uint32_t sampleNum)
484 {
485 static const __m128i Y[numSamples]
486 {_mm_set1_epi32(samplePosYi[0]), _mm_set1_epi32(samplePosYi[1]), _mm_set1_epi32(samplePosYi[2]), _mm_set1_epi32(samplePosYi[3]),
487 _mm_set1_epi32(samplePosYi[4]), _mm_set1_epi32(samplePosYi[5]), _mm_set1_epi32(samplePosYi[6]), _mm_set1_epi32(samplePosYi[7]),
488 _mm_set1_epi32(samplePosYi[8]), _mm_set1_epi32(samplePosYi[9]), _mm_set1_epi32(samplePosYi[10]), _mm_set1_epi32(samplePosYi[11]),
489 _mm_set1_epi32(samplePosYi[12]), _mm_set1_epi32(samplePosYi[13]), _mm_set1_epi32(samplePosYi[14]), _mm_set1_epi32(samplePosYi[15])};
490 SWR_ASSERT(sampleNum < numSamples);
491 return Y[sampleNum];
492 }
493
494 INLINE static simdscalar vX(uint32_t sampleNum)
495 {
496 static const simdscalar X[numSamples]
497 {_simd_set1_ps(0.5625), _simd_set1_ps(0.4375), _simd_set1_ps(0.3125), _simd_set1_ps(0.7500),
498 _simd_set1_ps(0.1875), _simd_set1_ps(0.6250), _simd_set1_ps(0.8125), _simd_set1_ps(0.6875),
499 _simd_set1_ps(0.3750), _simd_set1_ps(0.5000), _simd_set1_ps(0.2500), _simd_set1_ps(0.1250),
500 _simd_set1_ps(0.0000), _simd_set1_ps(0.9375), _simd_set1_ps(0.8750), _simd_set1_ps(0.0625)};
501 assert(sampleNum < numSamples);
502 return X[sampleNum];
503 }
504
505 INLINE static simdscalar vY(uint32_t sampleNum)
506 {
507 static const simdscalar Y[numSamples]
508 {_simd_set1_ps(0.5625), _simd_set1_ps(0.3125), _simd_set1_ps(0.6250), _simd_set1_ps(0.4375),
509 _simd_set1_ps(0.3750), _simd_set1_ps(0.8125), _simd_set1_ps(0.6875), _simd_set1_ps(0.1875),
510 _simd_set1_ps(0.8750), _simd_set1_ps(0.0625), _simd_set1_ps(0.1250), _simd_set1_ps(0.7500),
511 _simd_set1_ps(0.5000), _simd_set1_ps(0.2500), _simd_set1_ps(0.9375), _simd_set1_ps(0.0000)};
512 assert(sampleNum < numSamples);
513 return Y[sampleNum];
514 }
515
516 INLINE static float X(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosX[sampleNum]; };
517 INLINE static float Y(uint32_t sampleNum) { SWR_ASSERT(sampleNum < numSamples); return samplePosY[sampleNum]; };
518
519 INLINE static __m128i TileSampleOffsetsX()
520 {
521 static const uint32_t bboxLeftEdge = 0x00;
522 static const uint32_t bboxRightEdge = 0xF0;
523 // BR, BL, UR, UL
524 static const __m128i tileSampleOffsetX = _mm_set_epi32(bboxRightEdge, bboxLeftEdge, bboxRightEdge, bboxLeftEdge);
525 return tileSampleOffsetX;
526 }
527
528 INLINE static __m128i TileSampleOffsetsY()
529 {
530 static const uint32_t bboxTopEdge = 0x00;
531 static const uint32_t bboxBottomEdge = 0xF0;
532 // BR, BL, UR, UL
533 static const __m128i tileSampleOffsetY = _mm_set_epi32(bboxBottomEdge, bboxBottomEdge, bboxTopEdge, bboxTopEdge);
534 return tileSampleOffsetY;
535 }
536
537 INLINE static uint32_t RasterTileColorOffset(uint32_t sampleNum)
538 {
539 static const uint32_t RasterTileColorOffsets[numSamples]
540 { 0,
541 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8),
542 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 2,
543 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 3,
544 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 4,
545 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 5,
546 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 6,
547 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 7,
548 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 8,
549 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 9,
550 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 10,
551 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 11,
552 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 12,
553 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 13,
554 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 14,
555 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_COLOR_HOT_TILE_FORMAT>::bpp / 8) * 15,
556 };
557 assert(sampleNum < numSamples);
558 return RasterTileColorOffsets[sampleNum];
559 }
560
561 INLINE static uint32_t RasterTileDepthOffset(uint32_t sampleNum)
562 {
563 static const uint32_t RasterTileDepthOffsets[numSamples]
564 { 0,
565 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8),
566 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 2,
567 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 3,
568 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 4,
569 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 5,
570 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 6,
571 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 7,
572 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 8,
573 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 9,
574 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 10,
575 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 11,
576 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 12,
577 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 13,
578 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 14,
579 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_DEPTH_HOT_TILE_FORMAT>::bpp / 8) * 15,
580 };
581 assert(sampleNum < numSamples);
582 return RasterTileDepthOffsets[sampleNum];
583 }
584
585 INLINE static uint32_t RasterTileStencilOffset(uint32_t sampleNum)
586 {
587 static const uint32_t RasterTileStencilOffsets[numSamples]
588 { 0,
589 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8),
590 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 2,
591 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 3,
592 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 4,
593 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 5,
594 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 6,
595 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 7,
596 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 8,
597 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 9,
598 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 10,
599 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 11,
600 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 12,
601 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 13,
602 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 14,
603 (KNOB_TILE_X_DIM * KNOB_TILE_Y_DIM * FormatTraits<KNOB_STENCIL_HOT_TILE_FORMAT>::bpp / 8) * 15,
604 };
605 assert(sampleNum < numSamples);
606 return RasterTileStencilOffsets[sampleNum];
607 }
608
609 INLINE static simdscalari FullSampleMask()
610 {
611 static const simdscalari mask = _simd_set1_epi32(0xFFFF);
612 return mask;
613 }
614
615 static const uint32_t samplePosXi[16];
616 static const uint32_t samplePosYi[16];
617 static const float samplePosX[16];
618 static const float samplePosY[16];
619 static const uint32_t numSamples = 16;
620 };