• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
GetSampleCount(uint32_t numSamples)37 SWR_MULTISAMPLE_COUNT GetSampleCount(uint32_t numSamples)
38 {
39     switch(numSamples)
40     {
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;
47     }
48 }
49 
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
55 {
56     INLINE static float X(uint32_t sampleNum) = delete;
57     INLINE static float Y(uint32_t sampleNum) = delete;
58     INLINE static simdscalari FullSampleMask() = delete;
59 
60     static const uint32_t numSamples = 0;
61 };
62 
63 template<>
64 struct MultisampleTraits<SWR_MULTISAMPLE_1X, false>
65 {
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);};
69 
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 };
77 };
78 
79 template<>
80 struct MultisampleTraits<SWR_MULTISAMPLE_1X, true>
81 {
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);};
85 
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 };
93 };
94 
95 template<>
96 struct MultisampleTraits<SWR_MULTISAMPLE_2X, false>
97 {
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()
101     {
102          static const simdscalari mask =_simd_set1_epi32(0x3);
103          return mask;
104     }
105 
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};
113 };
114 
115 template<>
116 struct MultisampleTraits<SWR_MULTISAMPLE_2X, true>
117 {
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()
121     {
122          static const simdscalari mask =_simd_set1_epi32(0x3);
123          return mask;
124     }
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 };
132 };
133 
134 template<>
135 struct MultisampleTraits<SWR_MULTISAMPLE_4X, false>
136 {
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()
140     {
141         static const simdscalari mask = _simd_set1_epi32(0xF);
142         return mask;
143     }
144 
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 };
152 };
153 
154 template<>
155 struct MultisampleTraits<SWR_MULTISAMPLE_4X, true>
156 {
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()
160     {
161         static const simdscalari mask = _simd_set1_epi32(0xF);
162         return mask;
163     }
164 
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 };
172 };
173 
174 template<>
175 struct MultisampleTraits<SWR_MULTISAMPLE_8X, false>
176 {
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()
180     {
181         static const simdscalari mask = _simd_set1_epi32(0xFF);
182         return mask;
183     }
184 
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 };
192 };
193 
194 template<>
195 struct MultisampleTraits<SWR_MULTISAMPLE_8X, true>
196 {
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()
200     {
201         static const simdscalari mask = _simd_set1_epi32(0xFF);
202         return mask;
203     }
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 };
211 };
212 
213 template<>
214 struct MultisampleTraits<SWR_MULTISAMPLE_16X, false>
215 {
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()
219     {
220         static const simdscalari mask = _simd_set1_epi32(0xFFFF);
221         return mask;
222     }
223 
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 };
231 };
232 
233 template<>
234 struct MultisampleTraits<SWR_MULTISAMPLE_16X, true>
235 {
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()
239     {
240         static const simdscalari mask = _simd_set1_epi32(0xFFFF);
241         return mask;
242     }
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 };
250 };
251 
252 INLINE
253 bool isNonStandardPattern(const SWR_MULTISAMPLE_COUNT sampleCount, const SWR_MULTISAMPLE_POS& samplePos)
254 {
255     // detect if we're using standard or center sample patterns
256     const uint32_t *standardPosX, *standardPosY;
257     switch(sampleCount)
258     {
259     case SWR_MULTISAMPLE_1X:
260         standardPosX = MultisampleTraits<SWR_MULTISAMPLE_1X>::samplePosXi;
261         standardPosY = MultisampleTraits<SWR_MULTISAMPLE_1X>::samplePosYi;
262         break;
263     case SWR_MULTISAMPLE_2X:
264         standardPosX = MultisampleTraits<SWR_MULTISAMPLE_2X>::samplePosXi;
265         standardPosY = MultisampleTraits<SWR_MULTISAMPLE_2X>::samplePosYi;
266         break;
267     case SWR_MULTISAMPLE_4X:
268         standardPosX = MultisampleTraits<SWR_MULTISAMPLE_4X>::samplePosXi;
269         standardPosY = MultisampleTraits<SWR_MULTISAMPLE_4X>::samplePosYi;
270         break;
271     case SWR_MULTISAMPLE_8X:
272         standardPosX = MultisampleTraits<SWR_MULTISAMPLE_8X>::samplePosXi;
273         standardPosY = MultisampleTraits<SWR_MULTISAMPLE_8X>::samplePosYi;
274         break;
275     case SWR_MULTISAMPLE_16X:
276         standardPosX = MultisampleTraits<SWR_MULTISAMPLE_16X>::samplePosXi;
277         standardPosY = MultisampleTraits<SWR_MULTISAMPLE_16X>::samplePosYi;
278         break;
279     default:
280         break;
281     }
282 
283     // scan sample pattern for standard or center
284     uint32_t numSamples = GetNumSamples(sampleCount);
285     bool bIsStandard = true;
286     if(numSamples > 1)
287     {
288         for(uint32_t i = 0; i < numSamples; i++)
289         {
290             bIsStandard = (standardPosX[i] == samplePos.Xi(i)) ||
291                 (standardPosY[i] == samplePos.Yi(i));
292             if(!bIsStandard)
293                 break;
294         }
295     }
296     return !bIsStandard;
297 }
298