aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
blob: 3035ebf6708f62578cfb13894e4ff1fe1934eb41 (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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;

namespace Ryujinx.Graphics.Shader.Translation
{
    struct ShaderConfig
    {
        public ShaderStage Stage { get; }

        public OutputTopology OutputTopology { get; }

        public int MaxOutputVertices { get; }

        public int LocalMemorySize { get; }

        public ImapPixelType[] ImapTypes { get; }

        public OmapTarget[] OmapTargets    { get; }
        public bool         OmapSampleMask { get; }
        public bool         OmapDepth      { get; }

        public TranslationFlags Flags { get; }

        private TranslatorCallbacks _callbacks;

        public ShaderConfig(TranslationFlags flags, TranslatorCallbacks callbacks)
        {
            Stage             = ShaderStage.Compute;
            OutputTopology    = OutputTopology.PointList;
            MaxOutputVertices = 0;
            LocalMemorySize   = 0;
            ImapTypes         = null;
            OmapTargets       = null;
            OmapSampleMask    = false;
            OmapDepth         = false;
            Flags             = flags;
            _callbacks        = callbacks;
        }

        public ShaderConfig(ShaderHeader header, TranslationFlags flags, TranslatorCallbacks callbacks)
        {
            Stage             = header.Stage;
            OutputTopology    = header.OutputTopology;
            MaxOutputVertices = header.MaxOutputVertexCount;
            LocalMemorySize   = header.ShaderLocalMemoryLowSize + header.ShaderLocalMemoryHighSize;
            ImapTypes         = header.ImapTypes;
            OmapTargets       = header.OmapTargets;
            OmapSampleMask    = header.OmapSampleMask;
            OmapDepth         = header.OmapDepth;
            Flags             = flags;
            _callbacks        = callbacks;
        }

        public int GetDepthRegister()
        {
            int count = 0;

            for (int index = 0; index < OmapTargets.Length; index++)
            {
                for (int component = 0; component < 4; component++)
                {
                    if (OmapTargets[index].ComponentEnabled(component))
                    {
                        count++;
                    }
                }
            }

            // The depth register is always two registers after the last color output.
            return count + 1;
        }

        public bool QueryInfoBool(QueryInfoName info, int index = 0)
        {
            return Convert.ToBoolean(QueryInfo(info, index));
        }

        public int QueryInfo(QueryInfoName info, int index = 0)
        {
            if (_callbacks.QueryInfo != null)
            {
                return _callbacks.QueryInfo(info, index);
            }
            else
            {
                switch (info)
                {
                    case QueryInfoName.ComputeLocalSizeX:
                    case QueryInfoName.ComputeLocalSizeY:
                    case QueryInfoName.ComputeLocalSizeZ:
                        return 1;
                    case QueryInfoName.ComputeLocalMemorySize:
                        return 0x1000;
                    case QueryInfoName.ComputeSharedMemorySize:
                        return 0xc000;
                    case QueryInfoName.IsTextureBuffer:
                        return Convert.ToInt32(false);
                    case QueryInfoName.IsTextureRectangle:
                        return Convert.ToInt32(false);
                    case QueryInfoName.PrimitiveTopology:
                        return (int)InputTopology.Points;
                    case QueryInfoName.StorageBufferOffsetAlignment:
                        return 16;
                    case QueryInfoName.SupportsNonConstantTextureOffset:
                        return Convert.ToInt32(true);
                    case QueryInfoName.TextureFormat:
                        return (int)TextureFormat.R8G8B8A8Unorm;
                }
            }

            return 0;
        }

        public void PrintLog(string message)
        {
            _callbacks.PrintLog?.Invoke(message);
        }
    }
}