aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Memory/BufferStage.cs
blob: d56abda28401c8be12a305b8934469db236782dd (plain)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using Ryujinx.Graphics.Shader;
using System.Runtime.CompilerServices;

namespace Ryujinx.Graphics.Gpu.Memory
{
    /// <summary>
    /// Pipeline stages that can modify buffer data, as well as flags indicating storage usage.
    /// Must match ShaderStage for the shader stages, though anything after that can be in any order.
    /// </summary>
    internal enum BufferStage : byte
    {
        Compute,
        Vertex,
        TessellationControl,
        TessellationEvaluation,
        Geometry,
        Fragment,

        Indirect,
        VertexBuffer,
        IndexBuffer,
        Copy,
        TransformFeedback,
        Internal,
        None,

        StageMask = 0x3f,
        StorageMask = 0xc0,

        StorageRead = 0x40,
        StorageWrite = 0x80,

#pragma warning disable CA1069 // Enums values should not be duplicated
        StorageAtomic = 0xc0
#pragma warning restore CA1069 // Enums values should not be duplicated
    }

    /// <summary>
    /// Utility methods to convert shader stages and binding flags into buffer stages.
    /// </summary>
    internal static class BufferStageUtils
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage FromShaderStage(ShaderStage stage)
        {
            return (BufferStage)stage;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage FromShaderStage(int stageIndex)
        {
            return (BufferStage)(stageIndex + 1);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage FromUsage(BufferUsageFlags flags)
        {
            if (flags.HasFlag(BufferUsageFlags.Write))
            {
                return BufferStage.StorageWrite;
            }
            else
            {
                return BufferStage.StorageRead;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage FromUsage(TextureUsageFlags flags)
        {
            if (flags.HasFlag(TextureUsageFlags.ImageStore))
            {
                return BufferStage.StorageWrite;
            }
            else
            {
                return BufferStage.StorageRead;
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage TextureBuffer(ShaderStage shaderStage, TextureUsageFlags flags)
        {
            return FromShaderStage(shaderStage) | FromUsage(flags);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage GraphicsStorage(int stageIndex, BufferUsageFlags flags)
        {
            return FromShaderStage(stageIndex) | FromUsage(flags);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static BufferStage ComputeStorage(BufferUsageFlags flags)
        {
            return BufferStage.Compute | FromUsage(flags);
        }
    }
}