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(_WIN32)
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?
42static 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?
82template<UINT numMantissaBits>
83static 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?
160static 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).
230template<SWR_FORMAT DstFormat>
231static 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_ASSERT(0);
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_ASSERT(0);
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
392template<SWR_FORMAT SrcFormat>
393INLINE 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_ASSERT(0);
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_ASSERT(0);
551            break;
552        }
553    }
554}
555
556// non-templated version of conversion functions
557INLINE 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_ASSERT(0);
728        break;
729    }
730}
731