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 uint32_t GetNumSamples(SWR_MULTISAMPLE_COUNT sampleCount
)
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
];
45 SWR_MULTISAMPLE_COUNT
GetSampleCount(uint32_t numSamples
)
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
;
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
64 INLINE
static float X(uint32_t sampleNum
) = delete;
65 INLINE
static float Y(uint32_t sampleNum
) = delete;
66 INLINE
static simdscalari
FullSampleMask() = delete;
68 static const uint32_t numSamples
= 0;
72 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, false>
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);};
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
};
88 struct MultisampleTraits
<SWR_MULTISAMPLE_1X
, true>
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);};
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
};
104 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, false>
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()
110 static const simdscalari mask
=_simd_set1_epi32(0x3);
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
};
124 struct MultisampleTraits
<SWR_MULTISAMPLE_2X
, true>
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()
130 static const simdscalari mask
=_simd_set1_epi32(0x3);
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
};
143 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, false>
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()
149 static const simdscalari mask
= _simd_set1_epi32(0xF);
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
};
163 struct MultisampleTraits
<SWR_MULTISAMPLE_4X
, true>
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()
169 static const simdscalari mask
= _simd_set1_epi32(0xF);
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
};
183 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, false>
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()
189 static const simdscalari mask
= _simd_set1_epi32(0xFF);
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
};
203 struct MultisampleTraits
<SWR_MULTISAMPLE_8X
, true>
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()
209 static const simdscalari mask
= _simd_set1_epi32(0xFF);
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
};
222 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, false>
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()
228 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
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
};
242 struct MultisampleTraits
<SWR_MULTISAMPLE_16X
, true>
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()
248 static const simdscalari mask
= _simd_set1_epi32(0xFFFF);
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
};
261 bool isNonStandardPattern(const SWR_MULTISAMPLE_COUNT sampleCount
, const SWR_MULTISAMPLE_POS
& samplePos
)
263 // detect if we're using standard or center sample patterns
264 const uint32_t *standardPosX
, *standardPosY
;
267 case SWR_MULTISAMPLE_1X
:
268 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosXi
;
269 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_1X
>::samplePosYi
;
271 case SWR_MULTISAMPLE_2X
:
272 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosXi
;
273 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_2X
>::samplePosYi
;
275 case SWR_MULTISAMPLE_4X
:
276 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosXi
;
277 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_4X
>::samplePosYi
;
279 case SWR_MULTISAMPLE_8X
:
280 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosXi
;
281 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_8X
>::samplePosYi
;
283 case SWR_MULTISAMPLE_16X
:
284 standardPosX
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosXi
;
285 standardPosY
= MultisampleTraits
<SWR_MULTISAMPLE_16X
>::samplePosYi
;
291 // scan sample pattern for standard or center
292 uint32_t numSamples
= GetNumSamples(sampleCount
);
293 bool bIsStandard
= true;
296 for(uint32_t i
= 0; i
< numSamples
; i
++)
298 bIsStandard
= (standardPosX
[i
] == samplePos
.Xi(i
)) ||
299 (standardPosY
[i
] == samplePos
.Yi(i
));