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
)
41 case 1: return SWR_MULTISAMPLE_1X
;
42 case 2: return SWR_MULTISAMPLE_2X
;
43 case 4: return SWR_MULTISAMPLE_4X
;
44 case 8: return SWR_MULTISAMPLE_8X
;
45 case 16: return SWR_MULTISAMPLE_16X
;
46 default: assert(0); return SWR_MULTISAMPLE_1X
;
50 // hardcoded offsets based on Direct3d standard multisample positions
51 // 8 x 8 pixel grid ranging from (0, 0) to (15, 15), with (0, 0) = UL pixel corner
52 // coords are 0.8 fixed point offsets from (0, 0)
53 template<SWR_MULTISAMPLE_COUNT sampleCount
, bool isCenter
= false>
54 struct MultisampleTraits
56 INLINE
static float X(uint32_t sampleNum
) = delete;
57 INLINE
static float Y(uint32_t sampleNum
) = delete;
58 INLINE
static simdscalari
FullSampleMask() = delete;
60 static const uint32_t numSamples
= 0;
64 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, false>
66 INLINE
static float X(uint32_t sampleNum
) {return samplePosX
[sampleNum
];};
67 INLINE
static float Y(uint32_t sampleNum
) {return samplePosY
[sampleNum
];};
68 INLINE
static simdscalari
FullSampleMask(){return _simd_set1_epi32(0x1);};
70 static const uint32_t numSamples
= 1;
71 static const uint32_t numCoverageSamples
= 1;
72 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_1X
;
73 static constexpr uint32_t samplePosXi
[1] = { 0x80 };
74 static constexpr uint32_t samplePosYi
[1] = { 0x80 };
75 static constexpr float samplePosX
[1] = { 0.5f
};
76 static constexpr float samplePosY
[1] = { 0.5f
};
80 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, true>
82 INLINE
static float X(uint32_t sampleNum
) {return 0.5f
;};
83 INLINE
static float Y(uint32_t sampleNum
) {return 0.5f
;};
84 INLINE
static simdscalari
FullSampleMask(){return _simd_set1_epi32(0x1);};
86 static const uint32_t numSamples
= 1;
87 static const uint32_t numCoverageSamples
= 1;
88 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_1X
;
89 static constexpr uint32_t samplePosXi
[1] = { 0x80 };
90 static constexpr uint32_t samplePosYi
[1] = { 0x80 };
91 static constexpr float samplePosX
[1] = { 0.5f
};
92 static constexpr float samplePosY
[1] = { 0.5f
};
96 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, false>
98 INLINE
static float X(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosX
[sampleNum
]; };
99 INLINE
static float Y(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosY
[sampleNum
]; };
100 INLINE
static simdscalari
FullSampleMask()
102 static const simdscalari mask
=_simd_set1_epi32(0x3);
106 static const uint32_t numSamples
= 2;
107 static const uint32_t numCoverageSamples
= 2;
108 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_2X
;
109 static constexpr uint32_t samplePosXi
[2] = { 0xC0, 0x40 };
110 static constexpr uint32_t samplePosYi
[2] = { 0xC0, 0x40 };
111 static constexpr float samplePosX
[2] = {0.75f
, 0.25f
};
112 static constexpr float samplePosY
[2] = {0.75f
, 0.25f
};
116 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, true>
118 INLINE
static float X(uint32_t sampleNum
) {return 0.5f
;};
119 INLINE
static float Y(uint32_t sampleNum
) {return 0.5f
;};
120 INLINE
static simdscalari
FullSampleMask()
122 static const simdscalari mask
=_simd_set1_epi32(0x3);
125 static const uint32_t numSamples
= 2;
126 static const uint32_t numCoverageSamples
= 1;
127 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_2X
;
128 static constexpr uint32_t samplePosXi
[2] = { 0x80 , 0x80 };
129 static constexpr uint32_t samplePosYi
[2] = { 0x80 , 0x80 };
130 static constexpr float samplePosX
[2] = { 0.5f
, 0.5f
};
131 static constexpr float samplePosY
[2] = { 0.5f
, 0.5f
};
135 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, false>
137 INLINE
static float X(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosX
[sampleNum
]; };
138 INLINE
static float Y(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosY
[sampleNum
]; };
139 INLINE
static simdscalari
FullSampleMask()
141 static const simdscalari mask
= _simd_set1_epi32(0xF);
145 static const uint32_t numSamples
= 4;
146 static const uint32_t numCoverageSamples
= 4;
147 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_4X
;
148 static constexpr uint32_t samplePosXi
[4] = { 0x60, 0xE0, 0x20, 0xA0 };
149 static constexpr uint32_t samplePosYi
[4] = { 0x20, 0x60, 0xA0, 0xE0 };
150 static constexpr float samplePosX
[4] = { 0.375f
, 0.875f
, 0.125f
, 0.625f
};
151 static constexpr float samplePosY
[4] = { 0.125f
, 0.375f
, 0.625f
, 0.875f
};
155 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, true>
157 INLINE
static float X(uint32_t sampleNum
) {return 0.5f
;};
158 INLINE
static float Y(uint32_t sampleNum
) {return 0.5f
;};
159 INLINE
static simdscalari
FullSampleMask()
161 static const simdscalari mask
= _simd_set1_epi32(0xF);
165 static const uint32_t numSamples
= 4;
166 static const uint32_t numCoverageSamples
= 1;
167 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_4X
;
168 static constexpr uint32_t samplePosXi
[4] = { 0x80, 0x80, 0x80, 0x80 };
169 static constexpr uint32_t samplePosYi
[4] = { 0x80, 0x80, 0x80, 0x80 };
170 static constexpr float samplePosX
[4] = { 0.5f
, 0.5f
, 0.5f
, 0.5f
};
171 static constexpr float samplePosY
[4] = { 0.5f
, 0.5f
, 0.5f
, 0.5f
};
175 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, false>
177 INLINE
static float X(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosX
[sampleNum
]; };
178 INLINE
static float Y(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosY
[sampleNum
]; };
179 INLINE
static simdscalari
FullSampleMask()
181 static const simdscalari mask
= _simd_set1_epi32(0xFF);
185 static const uint32_t numSamples
= 8;
186 static const uint32_t numCoverageSamples
= 8;
187 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_8X
;
188 static constexpr uint32_t samplePosXi
[8] = { 0x90, 0x70, 0xD0, 0x50, 0x30, 0x10, 0xB0, 0xF0 };
189 static constexpr uint32_t samplePosYi
[8] = { 0x50, 0xB0, 0x90, 0x30, 0xD0, 0x70, 0xF0, 0x10 };
190 static constexpr float samplePosX
[8] = { 0.5625f
, 0.4375f
, 0.8125f
, 0.3125f
, 0.1875f
, 0.0625f
, 0.6875f
, 0.9375f
};
191 static constexpr float samplePosY
[8] = { 0.3125f
, 0.6875f
, 0.5625f
, 0.1875f
, 0.8125f
, 0.4375f
, 0.9375f
, 0.0625f
};
195 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, true>
197 INLINE
static float X(uint32_t sampleNum
) {return 0.5f
;};
198 INLINE
static float Y(uint32_t sampleNum
) {return 0.5f
;};
199 INLINE
static simdscalari
FullSampleMask()
201 static const simdscalari mask
= _simd_set1_epi32(0xFF);
204 static const uint32_t numSamples
= 8;
205 static const uint32_t numCoverageSamples
= 1;
206 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_8X
;
207 static constexpr uint32_t samplePosXi
[8] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
208 static constexpr uint32_t samplePosYi
[8] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
209 static constexpr float samplePosX
[8] = { 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
};
210 static constexpr float samplePosY
[8] = { 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
, 0.5f
};
214 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, false>
216 INLINE
static float X(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosX
[sampleNum
]; };
217 INLINE
static float Y(uint32_t sampleNum
) { SWR_ASSERT(sampleNum
< numSamples
); return samplePosY
[sampleNum
]; };
218 INLINE
static simdscalari
FullSampleMask()
220 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
224 static const uint32_t numSamples
= 16;
225 static const uint32_t numCoverageSamples
= 16;
226 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_16X
;
227 static constexpr uint32_t samplePosXi
[16] = { 0x90, 0x70, 0x50, 0xC0, 0x30, 0xA0, 0xD0, 0xB0, 0x60, 0x80, 0x40, 0x20, 0x00, 0xF0, 0xE0, 0x10 };
228 static constexpr uint32_t samplePosYi
[16] = { 0x90, 0x50, 0xA0, 0x70, 0x60, 0xD0, 0xB0, 0x30, 0xE0, 0x10, 0x20, 0xC0, 0x80, 0x40, 0xF0, 0x00 };
229 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
};
230 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
};
234 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, true>
236 INLINE
static float X(uint32_t sampleNum
) {return 0.5f
;};
237 INLINE
static float Y(uint32_t sampleNum
) {return 0.5f
;};
238 INLINE
static simdscalari
FullSampleMask()
240 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
243 static const uint32_t numSamples
= 16;
244 static const uint32_t numCoverageSamples
= 1;
245 static const SWR_MULTISAMPLE_COUNT sampleCount
= SWR_MULTISAMPLE_16X
;
246 static constexpr uint32_t samplePosXi
[16] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
247 static constexpr uint32_t samplePosYi
[16] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
248 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
};
249 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
};
253 bool isNonStandardPattern(const SWR_MULTISAMPLE_COUNT sampleCount
, const SWR_MULTISAMPLE_POS
& samplePos
)
255 // detect if we're using standard or center sample patterns
256 const uint32_t *standardPosX
, *standardPosY
;
259 case SWR_MULTISAMPLE_1X
:
260 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosXi
;
261 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosYi
;
263 case SWR_MULTISAMPLE_2X
:
264 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosXi
;
265 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosYi
;
267 case SWR_MULTISAMPLE_4X
:
268 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosXi
;
269 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosYi
;
271 case SWR_MULTISAMPLE_8X
:
272 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosXi
;
273 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosYi
;
275 case SWR_MULTISAMPLE_16X
:
276 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosXi
;
277 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosYi
;
283 // scan sample pattern for standard or center
284 uint32_t numSamples
= GetNumSamples(sampleCount
);
285 bool bIsStandard
= true;
288 for(uint32_t i
= 0; i
< numSamples
; i
++)
290 bIsStandard
= (standardPosX
[i
] == samplePos
.Xi(i
)) ||
291 (standardPosY
[i
] == samplePos
.Yi(i
));