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 ******************************************************************************/
30 #include "format_traits.h"
32 //////////////////////////////////////////////////////////////////////////
33 /// @brief convenience typedef for testing for single sample case
34 typedef std::integral_constant
<int, 1> SingleSampleT
;
37 SWR_MULTISAMPLE_COUNT
GetSampleCount(uint32_t numSamples
)
42 return SWR_MULTISAMPLE_1X
;
44 return SWR_MULTISAMPLE_2X
;
46 return SWR_MULTISAMPLE_4X
;
48 return SWR_MULTISAMPLE_8X
;
50 return SWR_MULTISAMPLE_16X
;
53 return SWR_MULTISAMPLE_1X
;
57 // hardcoded offsets based on Direct3d standard multisample positions
58 // 8 x 8 pixel grid ranging from (0, 0) to (15, 15), with (0, 0) = UL pixel corner
59 // coords are 0.8 fixed point offsets from (0, 0)
60 template <SWR_MULTISAMPLE_COUNT sampleCount
, bool isCenter
= false>
61 struct MultisampleTraits
63 INLINE
static float X(uint32_t sampleNum
) = delete;
64 INLINE
static float Y(uint32_t sampleNum
) = delete;
65 INLINE
static simdscalari
FullSampleMask() = delete;
67 static const uint32_t numSamples
= 0;
71 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, false>
73 INLINE
static float X(uint32_t sampleNum
) { return samplePosX
[sampleNum
]; };
74 INLINE
static float Y(uint32_t sampleNum
) { return samplePosY
[sampleNum
]; };
75 INLINE
static simdscalari
FullSampleMask() { return _simd_set1_epi32(0x1); };
77 static const uint32_t numSamples
= 1;
78 static const uint32_t numCoverageSamples
= 1;
79 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_1X
;
80 static constexpr uint32_t samplePosXi
[1] = {0x80};
81 static constexpr uint32_t samplePosYi
[1] = {0x80};
82 static constexpr float samplePosX
[1] = {0.5f
};
83 static constexpr float samplePosY
[1] = {0.5f
};
87 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, true>
89 INLINE
static float X(uint32_t sampleNum
) { return 0.5f
; };
90 INLINE
static float Y(uint32_t sampleNum
) { return 0.5f
; };
91 INLINE
static simdscalari
FullSampleMask() { return _simd_set1_epi32(0x1); };
93 static const uint32_t numSamples
= 1;
94 static const uint32_t numCoverageSamples
= 1;
95 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_1X
;
96 static constexpr uint32_t samplePosXi
[1] = {0x80};
97 static constexpr uint32_t samplePosYi
[1] = {0x80};
98 static constexpr float samplePosX
[1] = {0.5f
};
99 static constexpr float samplePosY
[1] = {0.5f
};
103 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, false>
105 INLINE
static float X(uint32_t sampleNum
)
107 SWR_ASSERT(sampleNum
< numSamples
);
108 return samplePosX
[sampleNum
];
110 INLINE
static float Y(uint32_t sampleNum
)
112 SWR_ASSERT(sampleNum
< numSamples
);
113 return samplePosY
[sampleNum
];
115 INLINE
static simdscalari
FullSampleMask()
117 static const simdscalari mask
= _simd_set1_epi32(0x3);
121 static const uint32_t numSamples
= 2;
122 static const uint32_t numCoverageSamples
= 2;
123 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_2X
;
124 static constexpr uint32_t samplePosXi
[2] = {0xC0, 0x40};
125 static constexpr uint32_t samplePosYi
[2] = {0xC0, 0x40};
126 static constexpr float samplePosX
[2] = {0.75f
, 0.25f
};
127 static constexpr float samplePosY
[2] = {0.75f
, 0.25f
};
131 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, true>
133 INLINE
static float X(uint32_t sampleNum
) { return 0.5f
; };
134 INLINE
static float Y(uint32_t sampleNum
) { return 0.5f
; };
135 INLINE
static simdscalari
FullSampleMask()
137 static const simdscalari mask
= _simd_set1_epi32(0x3);
140 static const uint32_t numSamples
= 2;
141 static const uint32_t numCoverageSamples
= 1;
142 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_2X
;
143 static constexpr uint32_t samplePosXi
[2] = {0x80, 0x80};
144 static constexpr uint32_t samplePosYi
[2] = {0x80, 0x80};
145 static constexpr float samplePosX
[2] = {0.5f
, 0.5f
};
146 static constexpr float samplePosY
[2] = {0.5f
, 0.5f
};
150 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, false>
152 INLINE
static float X(uint32_t sampleNum
)
154 SWR_ASSERT(sampleNum
< numSamples
);
155 return samplePosX
[sampleNum
];
157 INLINE
static float Y(uint32_t sampleNum
)
159 SWR_ASSERT(sampleNum
< numSamples
);
160 return samplePosY
[sampleNum
];
162 INLINE
static simdscalari
FullSampleMask()
164 static const simdscalari mask
= _simd_set1_epi32(0xF);
168 static const uint32_t numSamples
= 4;
169 static const uint32_t numCoverageSamples
= 4;
170 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_4X
;
171 static constexpr uint32_t samplePosXi
[4] = {0x60, 0xE0, 0x20, 0xA0};
172 static constexpr uint32_t samplePosYi
[4] = {0x20, 0x60, 0xA0, 0xE0};
173 static constexpr float samplePosX
[4] = {0.375f
, 0.875f
, 0.125f
, 0.625f
};
174 static constexpr float samplePosY
[4] = {0.125f
, 0.375f
, 0.625f
, 0.875f
};
178 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, true>
180 INLINE
static float X(uint32_t sampleNum
) { return 0.5f
; };
181 INLINE
static float Y(uint32_t sampleNum
) { return 0.5f
; };
182 INLINE
static simdscalari
FullSampleMask()
184 static const simdscalari mask
= _simd_set1_epi32(0xF);
188 static const uint32_t numSamples
= 4;
189 static const uint32_t numCoverageSamples
= 1;
190 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_4X
;
191 static constexpr uint32_t samplePosXi
[4] = {0x80, 0x80, 0x80, 0x80};
192 static constexpr uint32_t samplePosYi
[4] = {0x80, 0x80, 0x80, 0x80};
193 static constexpr float samplePosX
[4] = {0.5f
, 0.5f
, 0.5f
, 0.5f
};
194 static constexpr float samplePosY
[4] = {0.5f
, 0.5f
, 0.5f
, 0.5f
};
198 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, false>
200 INLINE
static float X(uint32_t sampleNum
)
202 SWR_ASSERT(sampleNum
< numSamples
);
203 return samplePosX
[sampleNum
];
205 INLINE
static float Y(uint32_t sampleNum
)
207 SWR_ASSERT(sampleNum
< numSamples
);
208 return samplePosY
[sampleNum
];
210 INLINE
static simdscalari
FullSampleMask()
212 static const simdscalari mask
= _simd_set1_epi32(0xFF);
216 static const uint32_t numSamples
= 8;
217 static const uint32_t numCoverageSamples
= 8;
218 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_8X
;
219 static constexpr uint32_t samplePosXi
[8] = {0x90, 0x70, 0xD0, 0x50, 0x30, 0x10, 0xB0, 0xF0};
220 static constexpr uint32_t samplePosYi
[8] = {0x50, 0xB0, 0x90, 0x30, 0xD0, 0x70, 0xF0, 0x10};
221 static constexpr float samplePosX
[8] = {
222 0.5625f
, 0.4375f
, 0.8125f
, 0.3125f
, 0.1875f
, 0.0625f
, 0.6875f
, 0.9375f
};
223 static constexpr float samplePosY
[8] = {
224 0.3125f
, 0.6875f
, 0.5625f
, 0.1875f
, 0.8125f
, 0.4375f
, 0.9375f
, 0.0625f
};
228 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, true>
230 INLINE
static float X(uint32_t sampleNum
) { return 0.5f
; };
231 INLINE
static float Y(uint32_t sampleNum
) { return 0.5f
; };
232 INLINE
static simdscalari
FullSampleMask()
234 static const simdscalari mask
= _simd_set1_epi32(0xFF);
237 static const uint32_t numSamples
= 8;
238 static const uint32_t numCoverageSamples
= 1;
239 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_8X
;
240 static constexpr uint32_t samplePosXi
[8] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
241 static constexpr uint32_t samplePosYi
[8] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80};
242 static constexpr float samplePosX
[8] = {0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
};
243 static constexpr float samplePosY
[8] = {0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
};
247 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, false>
249 INLINE
static float X(uint32_t sampleNum
)
251 SWR_ASSERT(sampleNum
< numSamples
);
252 return samplePosX
[sampleNum
];
254 INLINE
static float Y(uint32_t sampleNum
)
256 SWR_ASSERT(sampleNum
< numSamples
);
257 return samplePosY
[sampleNum
];
259 INLINE
static simdscalari
FullSampleMask()
261 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
265 static const uint32_t numSamples
= 16;
266 static const uint32_t numCoverageSamples
= 16;
267 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_16X
;
268 static constexpr uint32_t samplePosXi
[16] = {0x90,
284 static constexpr uint32_t samplePosYi
[16] = {0x90,
300 static constexpr float samplePosX
[16] = {0.5625f
,
316 static constexpr float samplePosY
[16] = {0.5625f
,
335 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, true>
337 INLINE
static float X(uint32_t sampleNum
) { return 0.5f
; };
338 INLINE
static float Y(uint32_t sampleNum
) { return 0.5f
; };
339 INLINE
static simdscalari
FullSampleMask()
341 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
344 static const uint32_t numSamples
= 16;
345 static const uint32_t numCoverageSamples
= 1;
346 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_16X
;
347 static constexpr uint32_t samplePosXi
[16] = {0x80,
363 static constexpr uint32_t samplePosYi
[16] = {0x80,
379 static constexpr float samplePosX
[16] = {0.5f
,
395 static constexpr float samplePosY
[16] = {0.5f
,
414 bool isNonStandardPattern(const SWR_MULTISAMPLE_COUNT sampleCount
,
415 const SWR_MULTISAMPLE_POS
& samplePos
)
417 // detect if we're using standard or center sample patterns
418 const uint32_t *standardPosX
, *standardPosY
;
421 case SWR_MULTISAMPLE_1X
:
422 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosXi
;
423 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosYi
;
425 case SWR_MULTISAMPLE_2X
:
426 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosXi
;
427 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosYi
;
429 case SWR_MULTISAMPLE_4X
:
430 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosXi
;
431 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosYi
;
433 case SWR_MULTISAMPLE_8X
:
434 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosXi
;
435 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosYi
;
437 case SWR_MULTISAMPLE_16X
:
438 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosXi
;
439 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosYi
;
445 // scan sample pattern for standard or center
446 uint32_t numSamples
= GetNumSamples(sampleCount
);
447 bool bIsStandard
= true;
450 for (uint32_t i
= 0; i
< numSamples
; i
++)
453 (standardPosX
[i
] == samplePos
.Xi(i
)) || (standardPosY
[i
] == samplePos
.Yi(i
));