aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/FormatConverter.cs
blob: 33472ae4a5cc941b8bd2b9fed96d3da9a47dfd4c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System;
using System.Runtime.InteropServices;

namespace Ryujinx.Graphics.Vulkan
{
    class FormatConverter
    {
        public static void ConvertD24S8ToD32FS8(Span<byte> output, ReadOnlySpan<byte> input)
        {
            const float UnormToFloat = 1f / 0xffffff;

            Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output);
            ReadOnlySpan<uint> inputUint = MemoryMarshal.Cast<byte, uint>(input);

            int i = 0;

            for (; i < inputUint.Length; i++)
            {
                uint depthStencil = inputUint[i];
                uint depth = depthStencil >> 8;
                uint stencil = depthStencil & 0xff;

                int j = i * 2;

                outputUint[j] = (uint)BitConverter.SingleToInt32Bits(depth * UnormToFloat);
                outputUint[j + 1] = stencil;
            }
        }

        public static void ConvertD32FS8ToD24S8(Span<byte> output, ReadOnlySpan<byte> input)
        {
            Span<uint> outputUint = MemoryMarshal.Cast<byte, uint>(output);
            ReadOnlySpan<uint> inputUint = MemoryMarshal.Cast<byte, uint>(input);

            int i = 0;

            for (; i < inputUint.Length; i += 2)
            {
                float depth = BitConverter.Int32BitsToSingle((int)inputUint[i]);
                uint stencil = inputUint[i + 1];
                uint depthStencil = (Math.Clamp((uint)(depth * 0xffffff), 0, 0xffffff) << 8) | (stencil & 0xff);

                int j = i >> 1;

                outputUint[j] = depthStencil;
            }
        }
    }
}