• 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 Convert.h
24 *
25 * @brief Conversion utility functions
26 *
27 ******************************************************************************/
28 #pragma once
29 
30 #if defined(_MSC_VER)
31 // disable "potential divide by 0"
32 #pragma warning(disable: 4723)
33 #endif
34 
35 #include <cmath>
36 
37 //////////////////////////////////////////////////////////////////////////
38 /// @brief Convert an IEEE 754 16-bit float to an 32-bit single precision
39 ///        float
40 /// @param val - 16-bit float
41 /// @todo Maybe move this outside of this file into a header?
ConvertSmallFloatTo32(UINT val)42 static INLINE float ConvertSmallFloatTo32(UINT val)
43 {
44     UINT result;
45     if ((val & 0x7fff) == 0)
46     {
47         result = ((uint32_t)(val & 0x8000)) << 16;
48     }
49     else if ((val & 0x7c00) == 0x7c00)
50     {
51         result = ((val & 0x3ff) == 0) ? 0x7f800000 : 0x7fc00000;
52         result |= ((uint32_t)val & 0x8000) << 16;
53     }
54     else
55     {
56         uint32_t sign = (val & 0x8000) << 16;
57         uint32_t mant = (val & 0x3ff) << 13;
58         uint32_t exp = (val >> 10) & 0x1f;
59         if ((exp == 0) && (mant != 0)) // Adjust exponent and mantissa for denormals
60         {
61             mant <<= 1;
62             while (mant < (0x400 << 13))
63             {
64                 exp--;
65                 mant <<= 1;
66             }
67             mant &= (0x3ff << 13);
68         }
69         exp = ((exp - 15 + 127) & 0xff) << 23;
70         result = sign | exp | mant;
71     }
72 
73     return *(float*)&result;
74 }
75 
76 //////////////////////////////////////////////////////////////////////////
77 /// @brief Convert an IEEE 754 32-bit single precision float to an
78 ///        unsigned small float with 5 exponent bits and a variable
79 ///        number of mantissa bits.
80 /// @param val - 32-bit float
81 /// @todo Maybe move this outside of this file into a header?
82 template<UINT numMantissaBits>
Convert32ToSmallFloat(float val)83 static UINT Convert32ToSmallFloat(float val)
84 {
85     uint32_t sign, exp, mant;
86     uint32_t roundBits;
87 
88     // Extract the sign, exponent, and mantissa
89     UINT uf = *(UINT*)&val;
90 
91     sign = (uf & 0x80000000) >> 31;
92     exp = (uf & 0x7F800000) >> 23;
93     mant = uf & 0x007FFFFF;
94 
95     // 10/11 bit floats are unsigned.  Negative values are clamped to 0.
96     if (sign != 0)
97     {
98         exp = mant = 0;
99     }
100     // Check for out of range
101     else if ((exp == 0xFF) && (mant != 0)) // NaN
102     {
103         exp = 0x1F;
104         mant = 1 << numMantissaBits;
105     }
106     else if ((exp == 0xFF) && (mant == 0)) // INF
107     {
108         exp = 0x1F;
109         mant = 0;
110     }
111     else if (exp > (0x70 + 0x1E)) // Too big to represent
112     {
113         exp = 0x1Eu;
114         mant = (1 << numMantissaBits) - 1;  // 0x3F for 6 bit mantissa.
115     }
116     else if ((exp <= 0x70) && (exp >= 0x66)) // It's a denorm
117     {
118         mant |= 0x00800000;
119         for (; exp <= 0x70; mant >>= 1, exp++)
120             ;
121         exp = 0;
122         mant = mant >> (23 - numMantissaBits);
123     }
124     else if (exp < 0x66) // Too small to represent -> Zero
125     {
126         exp = 0;
127         mant = 0;
128     }
129     else
130     {
131         // Saves bits that will be shifted off for rounding
132         roundBits = mant & 0x1FFFu;
133         // convert exponent and mantissa to 16 bit format
134         exp = exp - 0x70u;
135         mant = mant >> (23 - numMantissaBits);
136 
137         // Essentially RTZ, but round up if off by only 1 lsb
138         if (roundBits == 0x1FFFu)
139         {
140             mant++;
141             // check for overflow
142             if ((mant & (0x3 << numMantissaBits)) != 0) // 0x60 = 0x3 << (num Mantissa Bits)
143                 exp++;
144             // make sure only the needed bits are used
145             mant &= (1 << numMantissaBits) - 1;
146         }
147     }
148 
149     UINT tmpVal = (exp << numMantissaBits) | mant;
150     return tmpVal;
151 }
152 
153 #if KNOB_ARCH == KNOB_ARCH_AVX
154 //////////////////////////////////////////////////////////////////////////
155 /// @brief Convert an IEEE 754 32-bit single precision float to an
156 ///        16 bit float with 5 exponent bits and a variable
157 ///        number of mantissa bits.
158 /// @param val - 32-bit float
159 /// @todo Maybe move this outside of this file into a header?
Convert32To16Float(float val)160 static uint16_t Convert32To16Float(float val)
161 {
162     uint32_t sign, exp, mant;
163     uint32_t roundBits;
164 
165     // Extract the sign, exponent, and mantissa
166     uint32_t uf = *(uint32_t*)&val;
167     sign = (uf & 0x80000000) >> 31;
168     exp = (uf & 0x7F800000) >> 23;
169     mant = uf & 0x007FFFFF;
170 
171     // Check for out of range
172     if (std::isnan(val))
173     {
174         exp = 0x1F;
175         mant = 0x200;
176         sign = 1;                     // set the sign bit for NANs
177     }
178     else if (std::isinf(val))
179     {
180         exp = 0x1f;
181         mant = 0x0;
182     }
183     else if (exp > (0x70 + 0x1E)) // Too big to represent -> max representable value
184     {
185         exp = 0x1E;
186         mant = 0x3FF;
187     }
188     else if ((exp <= 0x70) && (exp >= 0x66)) // It's a denorm
189     {
190         mant |= 0x00800000;
191         for (; exp <= 0x70; mant >>= 1, exp++)
192             ;
193         exp = 0;
194         mant = mant >> 13;
195     }
196     else if (exp < 0x66) // Too small to represent -> Zero
197     {
198         exp = 0;
199         mant = 0;
200     }
201     else
202     {
203         // Saves bits that will be shifted off for rounding
204         roundBits = mant & 0x1FFFu;
205         // convert exponent and mantissa to 16 bit format
206         exp = exp - 0x70;
207         mant = mant >> 13;
208 
209         // Essentially RTZ, but round up if off by only 1 lsb
210         if (roundBits == 0x1FFFu)
211         {
212             mant++;
213             // check for overflow
214             if ((mant & 0xC00u) != 0)
215                 exp++;
216             // make sure only the needed bits are used
217             mant &= 0x3FF;
218         }
219     }
220 
221     uint32_t tmpVal = (sign << 15) | (exp << 10) | mant;
222     return (uint16_t)tmpVal;
223 }
224 #endif
225 
226 //////////////////////////////////////////////////////////////////////////
227 /// @brief Retrieve color from hot tile source which is always float.
228 /// @param pDstPixel - Pointer to destination pixel.
229 /// @param srcPixel - Pointer to source pixel (pre-swizzled according to dest).
230 template<SWR_FORMAT DstFormat>
ConvertPixelFromFloat(uint8_t * pDstPixel,const float srcPixel[4])231 static void ConvertPixelFromFloat(
232     uint8_t* pDstPixel,
233     const float srcPixel[4])
234 {
235     uint32_t outColor[4] = { 0 };  // typeless bits
236 
237     // Store component
238     for (UINT comp = 0; comp < FormatTraits<DstFormat>::numComps; ++comp)
239     {
240         SWR_TYPE type = FormatTraits<DstFormat>::GetType(comp);
241 
242         float src = srcPixel[comp];
243 
244         switch (type)
245         {
246         case SWR_TYPE_UNORM:
247         {
248             // Force NaN to 0. IEEE standard, comparisons involving NaN always evaluate to false.
249             src = (src != src) ? 0.0f : src;
250 
251             // Clamp [0, 1]
252             src = std::max(src, 0.0f);
253             src = std::min(src, 1.0f);
254 
255             // SRGB
256             if (FormatTraits<DstFormat>::isSRGB && comp != 3)
257             {
258                 src = (src <= 0.0031308f) ? (12.92f * src) : (1.055f * powf(src, (1.0f / 2.4f)) - 0.055f);
259             }
260 
261             // Float scale to integer scale.
262             UINT scale = (1 << FormatTraits<DstFormat>::GetBPC(comp)) - 1;
263             src = (float)scale * src;
264             src = roundf(src);
265             outColor[comp] = (UINT)src; // Drop fractional part.
266             break;
267         }
268         case SWR_TYPE_SNORM:
269         {
270             SWR_ASSERT(!FormatTraits<DstFormat>::isSRGB);
271 
272             // Force NaN to 0. IEEE standard, comparisons involving NaN always evaluate to false.
273             src = (src != src) ? 0.0f : src;
274 
275             // Clamp [-1, 1]
276             src = std::max(src, -1.0f);
277             src = std::min(src, 1.0f);
278 
279             // Float scale to integer scale.
280             UINT scale = (1 << (FormatTraits<DstFormat>::GetBPC(comp) - 1)) - 1;
281             src = (float)scale * src;
282 
283             // Round
284             src += (src >= 0) ? 0.5f : -0.5f;
285 
286             INT out = (INT)src;
287 
288             outColor[comp] = *(UINT*)&out;
289 
290             break;
291         }
292         case SWR_TYPE_UINT:
293         {
294             ///@note The *(UINT*)& is currently necessary as the hot tile appears to always be float.
295             //       However, the number in the hot tile should be unsigned integer. So doing this
296             //       to preserve bits intead of doing a float -> integer conversion.
297             if (FormatTraits<DstFormat>::GetBPC(comp) == 32)
298             {
299                 outColor[comp] = *(UINT*)&src;
300             }
301             else
302             {
303                 outColor[comp] = *(UINT*)&src;
304                 UINT max = (1 << FormatTraits<DstFormat>::GetBPC(comp)) - 1;  // 2^numBits - 1
305 
306                 outColor[comp] = std::min(max, outColor[comp]);
307             }
308             break;
309         }
310         case SWR_TYPE_SINT:
311         {
312             if (FormatTraits<DstFormat>::GetBPC(comp) == 32)
313             {
314                 outColor[comp] = *(UINT*)&src;
315             }
316             else
317             {
318                 INT out = *(INT*)&src;  // Hot tile format is SINT?
319                 INT max = (1 << (FormatTraits<DstFormat>::GetBPC(comp) - 1)) - 1;
320                 INT min = -1 - max;
321 
322                 ///@note The output is unsigned integer (bag of bits) and so performing
323                 //       the clamping here based on range of output component. Also, manually adding
324                 //       the sign bit in the appropriate spot. Maybe a better way?
325                 out = std::max(out, min);
326                 out = std::min(out, max);
327 
328                 outColor[comp] = *(UINT*)&out;
329             }
330             break;
331         }
332         case SWR_TYPE_FLOAT:
333         {
334             if (FormatTraits<DstFormat>::GetBPC(comp) == 16)
335             {
336                 // Convert from 32-bit float to 16-bit float using _mm_cvtps_ph
337                 // @todo 16bit float instruction support is orthogonal to avx support.  need to
338                 // add check for F16C support instead.
339 #if KNOB_ARCH >= KNOB_ARCH_AVX2
340                 __m128 src128 = _mm_set1_ps(src);
341                 __m128i srci128 = _mm_cvtps_ph(src128, _MM_FROUND_TRUNC);
342                 UINT value = _mm_extract_epi16(srci128, 0);
343 #else
344                 UINT value = Convert32To16Float(src);
345 #endif
346 
347                 outColor[comp] = value;
348             }
349             else if (FormatTraits<DstFormat>::GetBPC(comp) == 11)
350             {
351                 outColor[comp] = Convert32ToSmallFloat<6>(src);
352             }
353             else if (FormatTraits<DstFormat>::GetBPC(comp) == 10)
354             {
355                 outColor[comp] = Convert32ToSmallFloat<5>(src);
356             }
357             else
358             {
359                 outColor[comp] = *(UINT*)&src;
360             }
361 
362             break;
363         }
364         default:
365             SWR_INVALID("Invalid type: %d", type);
366             break;
367         }
368     }
369 
370     typename FormatTraits<DstFormat>::FormatT* pPixel = (typename FormatTraits<DstFormat>::FormatT*)pDstPixel;
371 
372     switch (FormatTraits<DstFormat>::numComps)
373     {
374     case 4:
375         pPixel->a = outColor[3];
376     case 3:
377         pPixel->b = outColor[2];
378     case 2:
379         pPixel->g = outColor[1];
380     case 1:
381         pPixel->r = outColor[0];
382         break;
383     default:
384         SWR_INVALID("Invalid # of comps: %d", FormatTraits<DstFormat>::numComps);
385     }
386 }
387 
388 //////////////////////////////////////////////////////////////////////////
389 /// @brief Convert pixel in any format to float32
390 /// @param pDstPixel - Pointer to destination pixel.
391 /// @param srcPixel - Pointer to source pixel
392 template<SWR_FORMAT SrcFormat>
ConvertPixelToFloat(float dstPixel[4],const uint8_t * pSrc)393 INLINE static void ConvertPixelToFloat(
394     float dstPixel[4],
395     const uint8_t* pSrc)
396 {
397     uint32_t srcColor[4];  // typeless bits
398 
399     // unpack src pixel
400     typename FormatTraits<SrcFormat>::FormatT* pPixel = (typename FormatTraits<SrcFormat>::FormatT*)pSrc;
401 
402     // apply format defaults
403     for (uint32_t comp = 0; comp < 4; ++comp)
404     {
405         uint32_t def = FormatTraits<SrcFormat>::GetDefault(comp);
406         dstPixel[comp] = *(float*)&def;
407     }
408 
409     // load format data
410     switch (FormatTraits<SrcFormat>::numComps)
411     {
412     case 4:
413         srcColor[3] = pPixel->a;
414     case 3:
415         srcColor[2] = pPixel->b;
416     case 2:
417         srcColor[1] = pPixel->g;
418     case 1:
419         srcColor[0] = pPixel->r;
420         break;
421     default:
422         SWR_INVALID("Invalid # of comps: %d", FormatTraits<SrcFormat>::numComps);
423     }
424 
425     // Convert components
426     for (uint32_t comp = 0; comp < FormatTraits<SrcFormat>::numComps; ++comp)
427     {
428         SWR_TYPE type = FormatTraits<SrcFormat>::GetType(comp);
429 
430         uint32_t src = srcColor[comp];
431 
432         switch (type)
433         {
434         case SWR_TYPE_UNORM:
435         {
436             float dst;
437             if (FormatTraits<SrcFormat>::isSRGB && comp != 3)
438             {
439                 dst = *(float*)&srgb8Table[src];
440             }
441             else
442             {
443                 // component sizes > 16 must use fp divide to maintain ulp requirements
444                 if (FormatTraits<SrcFormat>::GetBPC(comp) > 16)
445                 {
446                     dst = (float)src / (float)((1 << FormatTraits<SrcFormat>::GetBPC(comp)) - 1);
447                 }
448                 else
449                 {
450                     const float scale = (1.0f / (float)((1 << FormatTraits<SrcFormat>::GetBPC(comp)) - 1));
451                     dst = (float)src * scale;
452                 }
453             }
454             dstPixel[FormatTraits<SrcFormat>::swizzle(comp)] = dst;
455             break;
456         }
457         case SWR_TYPE_SNORM:
458         {
459             SWR_ASSERT(!FormatTraits<SrcFormat>::isSRGB);
460 
461             float dst;
462             if (src == 0x10)
463             {
464                 dst = -1.0f;
465             }
466             else
467             {
468                 switch (FormatTraits<SrcFormat>::GetBPC(comp))
469                 {
470                 case 8:
471                     dst = (float)((int8_t)src);
472                     break;
473                 case 16:
474                     dst = (float)((int16_t)src);
475                     break;
476                 case 32:
477                     dst = (float)((int32_t)src);
478                     break;
479                 default:
480                     assert(0 && "attempted to load from SNORM with unsupported bpc");
481                     dst = 0.0f;
482                     break;
483                 }
484                 dst = dst * (1.0f / ((1 << (FormatTraits<SrcFormat>::GetBPC(comp) - 1)) - 1));
485             }
486             dstPixel[FormatTraits<SrcFormat>::swizzle(comp)] = dst;
487             break;
488         }
489         case SWR_TYPE_UINT:
490         {
491             uint32_t dst = (uint32_t)src;
492             dstPixel[FormatTraits<SrcFormat>::swizzle(comp)] = *(float*)&dst;
493             break;
494         }
495         case SWR_TYPE_SINT:
496         {
497             int dst;
498             switch (FormatTraits<SrcFormat>::GetBPC(comp))
499             {
500             case 8:
501                 dst = (int8_t)src;
502                 break;
503             case 16:
504                 dst = (int16_t)src;
505                 break;
506             case 32:
507                 dst = (int32_t)src;
508                 break;
509             default:
510                 assert(0 && "attempted to load from SINT with unsupported bpc");
511                 dst = 0;
512                 break;
513             }
514             dstPixel[FormatTraits<SrcFormat>::swizzle(comp)] = *(float*)&dst;
515             break;
516         }
517         case SWR_TYPE_FLOAT:
518         {
519             float dst;
520             if (FormatTraits<SrcFormat>::GetBPC(comp) == 16)
521             {
522 #if KNOB_ARCH >= KNOB_ARCH_AVX2
523                 // Convert from 16-bit float to 32-bit float using _mm_cvtph_ps
524                 // @todo 16bit float instruction support is orthogonal to avx support.  need to
525                 // add check for F16C support instead.
526                 __m128i src128 = _mm_set1_epi32(src);
527                 __m128 res = _mm_cvtph_ps(src128);
528                 _mm_store_ss(&dst, res);
529 #else
530                 dst = ConvertSmallFloatTo32(src);
531 #endif
532             }
533             else if (FormatTraits<SrcFormat>::GetBPC(comp) == 11)
534             {
535                 dst = ConvertSmallFloatTo32(src << 4);
536             }
537             else if (FormatTraits<SrcFormat>::GetBPC(comp) == 10)
538             {
539                 dst = ConvertSmallFloatTo32(src << 5);
540             }
541             else
542             {
543                 dst = *(float*)&src;
544             }
545 
546             dstPixel[FormatTraits<SrcFormat>::swizzle(comp)] = *(float*)&dst;
547             break;
548         }
549         default:
550             SWR_INVALID("Invalid type: %d", type);
551             break;
552         }
553     }
554 }
555 
556 // non-templated version of conversion functions
ConvertPixelFromFloat(SWR_FORMAT format,uint8_t * pDst,const float srcPixel[4])557 INLINE static void ConvertPixelFromFloat(
558     SWR_FORMAT format,
559     uint8_t* pDst,
560     const float srcPixel[4])
561 {
562     switch (format)
563     {
564     case R32G32B32A32_FLOAT: ConvertPixelFromFloat<R32G32B32A32_FLOAT>(pDst, srcPixel); break;
565     case R32G32B32A32_SINT: ConvertPixelFromFloat<R32G32B32A32_SINT>(pDst, srcPixel); break;
566     case R32G32B32A32_UINT: ConvertPixelFromFloat<R32G32B32A32_UINT>(pDst, srcPixel); break;
567     case R32G32B32X32_FLOAT: ConvertPixelFromFloat<R32G32B32X32_FLOAT>(pDst, srcPixel); break;
568     case R32G32B32A32_SSCALED: ConvertPixelFromFloat<R32G32B32A32_SSCALED>(pDst, srcPixel); break;
569     case R32G32B32A32_USCALED: ConvertPixelFromFloat<R32G32B32A32_USCALED>(pDst, srcPixel); break;
570     case R32G32B32_FLOAT: ConvertPixelFromFloat<R32G32B32_FLOAT>(pDst, srcPixel); break;
571     case R32G32B32_SINT: ConvertPixelFromFloat<R32G32B32_SINT>(pDst, srcPixel); break;
572     case R32G32B32_UINT: ConvertPixelFromFloat<R32G32B32_UINT>(pDst, srcPixel); break;
573     case R32G32B32_SSCALED: ConvertPixelFromFloat<R32G32B32_SSCALED>(pDst, srcPixel); break;
574     case R32G32B32_USCALED: ConvertPixelFromFloat<R32G32B32_USCALED>(pDst, srcPixel); break;
575     case R16G16B16A16_UNORM: ConvertPixelFromFloat<R16G16B16A16_UNORM>(pDst, srcPixel); break;
576     case R16G16B16A16_SNORM: ConvertPixelFromFloat<R16G16B16A16_SNORM>(pDst, srcPixel); break;
577     case R16G16B16A16_SINT: ConvertPixelFromFloat<R16G16B16A16_SINT>(pDst, srcPixel); break;
578     case R16G16B16A16_UINT: ConvertPixelFromFloat<R16G16B16A16_UINT>(pDst, srcPixel); break;
579     case R16G16B16A16_FLOAT: ConvertPixelFromFloat<R16G16B16A16_FLOAT>(pDst, srcPixel); break;
580     case R32G32_FLOAT: ConvertPixelFromFloat<R32G32_FLOAT>(pDst, srcPixel); break;
581     case R32G32_SINT: ConvertPixelFromFloat<R32G32_SINT>(pDst, srcPixel); break;
582     case R32G32_UINT: ConvertPixelFromFloat<R32G32_UINT>(pDst, srcPixel); break;
583     case R32_FLOAT_X8X24_TYPELESS: ConvertPixelFromFloat<R32_FLOAT_X8X24_TYPELESS>(pDst, srcPixel); break;
584     case X32_TYPELESS_G8X24_UINT: ConvertPixelFromFloat<X32_TYPELESS_G8X24_UINT>(pDst, srcPixel); break;
585     case L32A32_FLOAT: ConvertPixelFromFloat<L32A32_FLOAT>(pDst, srcPixel); break;
586     case R16G16B16X16_UNORM: ConvertPixelFromFloat<R16G16B16X16_UNORM>(pDst, srcPixel); break;
587     case R16G16B16X16_FLOAT: ConvertPixelFromFloat<R16G16B16X16_FLOAT>(pDst, srcPixel); break;
588     case L32X32_FLOAT: ConvertPixelFromFloat<L32X32_FLOAT>(pDst, srcPixel); break;
589     case I32X32_FLOAT: ConvertPixelFromFloat<I32X32_FLOAT>(pDst, srcPixel); break;
590     case R16G16B16A16_SSCALED: ConvertPixelFromFloat<R16G16B16A16_SSCALED>(pDst, srcPixel); break;
591     case R16G16B16A16_USCALED: ConvertPixelFromFloat<R16G16B16A16_USCALED>(pDst, srcPixel); break;
592     case R32G32_SSCALED: ConvertPixelFromFloat<R32G32_SSCALED>(pDst, srcPixel); break;
593     case R32G32_USCALED: ConvertPixelFromFloat<R32G32_USCALED>(pDst, srcPixel); break;
594     case B8G8R8A8_UNORM: ConvertPixelFromFloat<B8G8R8A8_UNORM>(pDst, srcPixel); break;
595     case B8G8R8A8_UNORM_SRGB: ConvertPixelFromFloat<B8G8R8A8_UNORM_SRGB>(pDst, srcPixel); break;
596     case R10G10B10A2_UNORM: ConvertPixelFromFloat<R10G10B10A2_UNORM>(pDst, srcPixel); break;
597     case R10G10B10A2_UNORM_SRGB: ConvertPixelFromFloat<R10G10B10A2_UNORM_SRGB>(pDst, srcPixel); break;
598     case R10G10B10A2_UINT: ConvertPixelFromFloat<R10G10B10A2_UINT>(pDst, srcPixel); break;
599     case R8G8B8A8_UNORM: ConvertPixelFromFloat<R8G8B8A8_UNORM>(pDst, srcPixel); break;
600     case R8G8B8A8_UNORM_SRGB: ConvertPixelFromFloat<R8G8B8A8_UNORM_SRGB>(pDst, srcPixel); break;
601     case R8G8B8A8_SNORM: ConvertPixelFromFloat<R8G8B8A8_SNORM>(pDst, srcPixel); break;
602     case R8G8B8A8_SINT: ConvertPixelFromFloat<R8G8B8A8_SINT>(pDst, srcPixel); break;
603     case R8G8B8A8_UINT: ConvertPixelFromFloat<R8G8B8A8_UINT>(pDst, srcPixel); break;
604     case R16G16_UNORM: ConvertPixelFromFloat<R16G16_UNORM>(pDst, srcPixel); break;
605     case R16G16_SNORM: ConvertPixelFromFloat<R16G16_SNORM>(pDst, srcPixel); break;
606     case R16G16_SINT: ConvertPixelFromFloat<R16G16_SINT>(pDst, srcPixel); break;
607     case R16G16_UINT: ConvertPixelFromFloat<R16G16_UINT>(pDst, srcPixel); break;
608     case R16G16_FLOAT: ConvertPixelFromFloat<R16G16_FLOAT>(pDst, srcPixel); break;
609     case B10G10R10A2_UNORM: ConvertPixelFromFloat<B10G10R10A2_UNORM>(pDst, srcPixel); break;
610     case B10G10R10A2_UNORM_SRGB: ConvertPixelFromFloat<B10G10R10A2_UNORM_SRGB>(pDst, srcPixel); break;
611     case R11G11B10_FLOAT: ConvertPixelFromFloat<R11G11B10_FLOAT>(pDst, srcPixel); break;
612     case R10G10B10_FLOAT_A2_UNORM: ConvertPixelFromFloat<R10G10B10_FLOAT_A2_UNORM>(pDst, srcPixel); break;
613     case R32_SINT: ConvertPixelFromFloat<R32_SINT>(pDst, srcPixel); break;
614     case R32_UINT: ConvertPixelFromFloat<R32_UINT>(pDst, srcPixel); break;
615     case R32_FLOAT: ConvertPixelFromFloat<R32_FLOAT>(pDst, srcPixel); break;
616     case R24_UNORM_X8_TYPELESS: ConvertPixelFromFloat<R24_UNORM_X8_TYPELESS>(pDst, srcPixel); break;
617     case X24_TYPELESS_G8_UINT: ConvertPixelFromFloat<X24_TYPELESS_G8_UINT>(pDst, srcPixel); break;
618     case L32_UNORM: ConvertPixelFromFloat<L32_UNORM>(pDst, srcPixel); break;
619     case L16A16_UNORM: ConvertPixelFromFloat<L16A16_UNORM>(pDst, srcPixel); break;
620     case I24X8_UNORM: ConvertPixelFromFloat<I24X8_UNORM>(pDst, srcPixel); break;
621     case L24X8_UNORM: ConvertPixelFromFloat<L24X8_UNORM>(pDst, srcPixel); break;
622     case I32_FLOAT: ConvertPixelFromFloat<I32_FLOAT>(pDst, srcPixel); break;
623     case L32_FLOAT: ConvertPixelFromFloat<L32_FLOAT>(pDst, srcPixel); break;
624     case A32_FLOAT: ConvertPixelFromFloat<A32_FLOAT>(pDst, srcPixel); break;
625     case B8G8R8X8_UNORM: ConvertPixelFromFloat<B8G8R8X8_UNORM>(pDst, srcPixel); break;
626     case B8G8R8X8_UNORM_SRGB: ConvertPixelFromFloat<B8G8R8X8_UNORM_SRGB>(pDst, srcPixel); break;
627     case R8G8B8X8_UNORM: ConvertPixelFromFloat<R8G8B8X8_UNORM>(pDst, srcPixel); break;
628     case R8G8B8X8_UNORM_SRGB: ConvertPixelFromFloat<R8G8B8X8_UNORM_SRGB>(pDst, srcPixel); break;
629     case R9G9B9E5_SHAREDEXP: ConvertPixelFromFloat<R9G9B9E5_SHAREDEXP>(pDst, srcPixel); break;
630     case B10G10R10X2_UNORM: ConvertPixelFromFloat<B10G10R10X2_UNORM>(pDst, srcPixel); break;
631     case L16A16_FLOAT: ConvertPixelFromFloat<L16A16_FLOAT>(pDst, srcPixel); break;
632     case R10G10B10X2_USCALED: ConvertPixelFromFloat<R10G10B10X2_USCALED>(pDst, srcPixel); break;
633     case R8G8B8A8_SSCALED: ConvertPixelFromFloat<R8G8B8A8_SSCALED>(pDst, srcPixel); break;
634     case R8G8B8A8_USCALED: ConvertPixelFromFloat<R8G8B8A8_USCALED>(pDst, srcPixel); break;
635     case R16G16_SSCALED: ConvertPixelFromFloat<R16G16_SSCALED>(pDst, srcPixel); break;
636     case R16G16_USCALED: ConvertPixelFromFloat<R16G16_USCALED>(pDst, srcPixel); break;
637     case R32_SSCALED: ConvertPixelFromFloat<R32_SSCALED>(pDst, srcPixel); break;
638     case R32_USCALED: ConvertPixelFromFloat<R32_USCALED>(pDst, srcPixel); break;
639     case B5G6R5_UNORM: ConvertPixelFromFloat<B5G6R5_UNORM>(pDst, srcPixel); break;
640     case B5G6R5_UNORM_SRGB: ConvertPixelFromFloat<B5G6R5_UNORM_SRGB>(pDst, srcPixel); break;
641     case B5G5R5A1_UNORM: ConvertPixelFromFloat<B5G5R5A1_UNORM>(pDst, srcPixel); break;
642     case B5G5R5A1_UNORM_SRGB: ConvertPixelFromFloat<B5G5R5A1_UNORM_SRGB>(pDst, srcPixel); break;
643     case B4G4R4A4_UNORM: ConvertPixelFromFloat<B4G4R4A4_UNORM>(pDst, srcPixel); break;
644     case B4G4R4A4_UNORM_SRGB: ConvertPixelFromFloat<B4G4R4A4_UNORM_SRGB>(pDst, srcPixel); break;
645     case R8G8_UNORM: ConvertPixelFromFloat<R8G8_UNORM>(pDst, srcPixel); break;
646     case R8G8_SNORM: ConvertPixelFromFloat<R8G8_SNORM>(pDst, srcPixel); break;
647     case R8G8_SINT: ConvertPixelFromFloat<R8G8_SINT>(pDst, srcPixel); break;
648     case R8G8_UINT: ConvertPixelFromFloat<R8G8_UINT>(pDst, srcPixel); break;
649     case R16_UNORM: ConvertPixelFromFloat<R16_UNORM>(pDst, srcPixel); break;
650     case R16_SNORM: ConvertPixelFromFloat<R16_SNORM>(pDst, srcPixel); break;
651     case R16_SINT: ConvertPixelFromFloat<R16_SINT>(pDst, srcPixel); break;
652     case R16_UINT: ConvertPixelFromFloat<R16_UINT>(pDst, srcPixel); break;
653     case R16_FLOAT: ConvertPixelFromFloat<R16_FLOAT>(pDst, srcPixel); break;
654     case I16_UNORM: ConvertPixelFromFloat<I16_UNORM>(pDst, srcPixel); break;
655     case L16_UNORM: ConvertPixelFromFloat<L16_UNORM>(pDst, srcPixel); break;
656     case A16_UNORM: ConvertPixelFromFloat<A16_UNORM>(pDst, srcPixel); break;
657     case L8A8_UNORM: ConvertPixelFromFloat<L8A8_UNORM>(pDst, srcPixel); break;
658     case I16_FLOAT: ConvertPixelFromFloat<I16_FLOAT>(pDst, srcPixel); break;
659     case L16_FLOAT: ConvertPixelFromFloat<L16_FLOAT>(pDst, srcPixel); break;
660     case A16_FLOAT: ConvertPixelFromFloat<A16_FLOAT>(pDst, srcPixel); break;
661     case L8A8_UNORM_SRGB: ConvertPixelFromFloat<L8A8_UNORM_SRGB>(pDst, srcPixel); break;
662     case B5G5R5X1_UNORM: ConvertPixelFromFloat<B5G5R5X1_UNORM>(pDst, srcPixel); break;
663     case B5G5R5X1_UNORM_SRGB: ConvertPixelFromFloat<B5G5R5X1_UNORM_SRGB>(pDst, srcPixel); break;
664     case R8G8_SSCALED: ConvertPixelFromFloat<R8G8_SSCALED>(pDst, srcPixel); break;
665     case R8G8_USCALED: ConvertPixelFromFloat<R8G8_USCALED>(pDst, srcPixel); break;
666     case R16_SSCALED: ConvertPixelFromFloat<R16_SSCALED>(pDst, srcPixel); break;
667     case R16_USCALED: ConvertPixelFromFloat<R16_USCALED>(pDst, srcPixel); break;
668     case A1B5G5R5_UNORM: ConvertPixelFromFloat<A1B5G5R5_UNORM>(pDst, srcPixel); break;
669     case A4B4G4R4_UNORM: ConvertPixelFromFloat<A4B4G4R4_UNORM>(pDst, srcPixel); break;
670     case L8A8_UINT: ConvertPixelFromFloat<L8A8_UINT>(pDst, srcPixel); break;
671     case L8A8_SINT: ConvertPixelFromFloat<L8A8_SINT>(pDst, srcPixel); break;
672     case R8_UNORM: ConvertPixelFromFloat<R8_UNORM>(pDst, srcPixel); break;
673     case R8_SNORM: ConvertPixelFromFloat<R8_SNORM>(pDst, srcPixel); break;
674     case R8_SINT: ConvertPixelFromFloat<R8_SINT>(pDst, srcPixel); break;
675     case R8_UINT: ConvertPixelFromFloat<R8_UINT>(pDst, srcPixel); break;
676     case A8_UNORM: ConvertPixelFromFloat<A8_UNORM>(pDst, srcPixel); break;
677     case I8_UNORM: ConvertPixelFromFloat<I8_UNORM>(pDst, srcPixel); break;
678     case L8_UNORM: ConvertPixelFromFloat<L8_UNORM>(pDst, srcPixel); break;
679     case R8_SSCALED: ConvertPixelFromFloat<R8_SSCALED>(pDst, srcPixel); break;
680     case R8_USCALED: ConvertPixelFromFloat<R8_USCALED>(pDst, srcPixel); break;
681     case L8_UNORM_SRGB: ConvertPixelFromFloat<L8_UNORM_SRGB>(pDst, srcPixel); break;
682     case L8_UINT: ConvertPixelFromFloat<L8_UINT>(pDst, srcPixel); break;
683     case L8_SINT: ConvertPixelFromFloat<L8_SINT>(pDst, srcPixel); break;
684     case I8_UINT: ConvertPixelFromFloat<I8_UINT>(pDst, srcPixel); break;
685     case I8_SINT: ConvertPixelFromFloat<I8_SINT>(pDst, srcPixel); break;
686     case YCRCB_SWAPUVY: ConvertPixelFromFloat<YCRCB_SWAPUVY>(pDst, srcPixel); break;
687     case BC1_UNORM: ConvertPixelFromFloat<BC1_UNORM>(pDst, srcPixel); break;
688     case BC2_UNORM: ConvertPixelFromFloat<BC2_UNORM>(pDst, srcPixel); break;
689     case BC3_UNORM: ConvertPixelFromFloat<BC3_UNORM>(pDst, srcPixel); break;
690     case BC4_UNORM: ConvertPixelFromFloat<BC4_UNORM>(pDst, srcPixel); break;
691     case BC5_UNORM: ConvertPixelFromFloat<BC5_UNORM>(pDst, srcPixel); break;
692     case BC1_UNORM_SRGB: ConvertPixelFromFloat<BC1_UNORM_SRGB>(pDst, srcPixel); break;
693     case BC2_UNORM_SRGB: ConvertPixelFromFloat<BC2_UNORM_SRGB>(pDst, srcPixel); break;
694     case BC3_UNORM_SRGB: ConvertPixelFromFloat<BC3_UNORM_SRGB>(pDst, srcPixel); break;
695     case YCRCB_SWAPUV: ConvertPixelFromFloat<YCRCB_SWAPUV>(pDst, srcPixel); break;
696     case R8G8B8_UNORM: ConvertPixelFromFloat<R8G8B8_UNORM>(pDst, srcPixel); break;
697     case R8G8B8_SNORM: ConvertPixelFromFloat<R8G8B8_SNORM>(pDst, srcPixel); break;
698     case R8G8B8_SSCALED: ConvertPixelFromFloat<R8G8B8_SSCALED>(pDst, srcPixel); break;
699     case R8G8B8_USCALED: ConvertPixelFromFloat<R8G8B8_USCALED>(pDst, srcPixel); break;
700     case BC4_SNORM: ConvertPixelFromFloat<BC4_SNORM>(pDst, srcPixel); break;
701     case BC5_SNORM: ConvertPixelFromFloat<BC5_SNORM>(pDst, srcPixel); break;
702     case R16G16B16_FLOAT: ConvertPixelFromFloat<R16G16B16_FLOAT>(pDst, srcPixel); break;
703     case R16G16B16_UNORM: ConvertPixelFromFloat<R16G16B16_UNORM>(pDst, srcPixel); break;
704     case R16G16B16_SNORM: ConvertPixelFromFloat<R16G16B16_SNORM>(pDst, srcPixel); break;
705     case R16G16B16_SSCALED: ConvertPixelFromFloat<R16G16B16_SSCALED>(pDst, srcPixel); break;
706     case R16G16B16_USCALED: ConvertPixelFromFloat<R16G16B16_USCALED>(pDst, srcPixel); break;
707     case BC6H_SF16: ConvertPixelFromFloat<BC6H_SF16>(pDst, srcPixel); break;
708     case BC7_UNORM: ConvertPixelFromFloat<BC7_UNORM>(pDst, srcPixel); break;
709     case BC7_UNORM_SRGB: ConvertPixelFromFloat<BC7_UNORM_SRGB>(pDst, srcPixel); break;
710     case BC6H_UF16: ConvertPixelFromFloat<BC6H_UF16>(pDst, srcPixel); break;
711     case R8G8B8_UNORM_SRGB: ConvertPixelFromFloat<R8G8B8_UNORM_SRGB>(pDst, srcPixel); break;
712     case R16G16B16_UINT: ConvertPixelFromFloat<R16G16B16_UINT>(pDst, srcPixel); break;
713     case R16G16B16_SINT: ConvertPixelFromFloat<R16G16B16_SINT>(pDst, srcPixel); break;
714     case R10G10B10A2_SNORM: ConvertPixelFromFloat<R10G10B10A2_SNORM>(pDst, srcPixel); break;
715     case R10G10B10A2_USCALED: ConvertPixelFromFloat<R10G10B10A2_USCALED>(pDst, srcPixel); break;
716     case R10G10B10A2_SSCALED: ConvertPixelFromFloat<R10G10B10A2_SSCALED>(pDst, srcPixel); break;
717     case R10G10B10A2_SINT: ConvertPixelFromFloat<R10G10B10A2_SINT>(pDst, srcPixel); break;
718     case B10G10R10A2_SNORM: ConvertPixelFromFloat<B10G10R10A2_SNORM>(pDst, srcPixel); break;
719     case B10G10R10A2_USCALED: ConvertPixelFromFloat<B10G10R10A2_USCALED>(pDst, srcPixel); break;
720     case B10G10R10A2_SSCALED: ConvertPixelFromFloat<B10G10R10A2_SSCALED>(pDst, srcPixel); break;
721     case B10G10R10A2_UINT: ConvertPixelFromFloat<B10G10R10A2_UINT>(pDst, srcPixel); break;
722     case B10G10R10A2_SINT: ConvertPixelFromFloat<B10G10R10A2_SINT>(pDst, srcPixel); break;
723     case R8G8B8_UINT: ConvertPixelFromFloat<R8G8B8_UINT>(pDst, srcPixel); break;
724     case R8G8B8_SINT: ConvertPixelFromFloat<R8G8B8_SINT>(pDst, srcPixel); break;
725     case RAW: ConvertPixelFromFloat<RAW>(pDst, srcPixel); break;
726     default:
727         SWR_INVALID("Invalid format: %d", format);
728         break;
729     }
730 }
731