aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
blob: e20df384e383a1a49b440192bb4504c531771aa8 (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
119
120
121
122
123
124
125
126
127
128
using Ryujinx.Graphics.Shader.IntermediateRepresentation;
using Ryujinx.Graphics.Shader.StructuredIr;
using Ryujinx.Graphics.Shader.Translation;
using System.Collections.Generic;
using System.Text;

namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
    class CodeGenContext
    {
        public const string Tab = "    ";

        private readonly StructuredProgramInfo _info;

        public StructuredFunction CurrentFunction { get; set; }

        public ShaderConfig Config { get; }

        public bool CbIndexable => _info.UsesCbIndexing;

        public List<BufferDescriptor>  CBufferDescriptors { get; }
        public List<BufferDescriptor>  SBufferDescriptors { get; }
        public List<TextureDescriptor> TextureDescriptors { get; }
        public List<TextureDescriptor> ImageDescriptors   { get; }

        public OperandManager OperandManager { get; }

        private StringBuilder _sb;

        private int _level;

        private string _indentation;

        public CodeGenContext(StructuredProgramInfo info, ShaderConfig config)
        {
            _info = info;
            Config = config;

            CBufferDescriptors = new List<BufferDescriptor>();
            SBufferDescriptors = new List<BufferDescriptor>();
            TextureDescriptors = new List<TextureDescriptor>();
            ImageDescriptors   = new List<TextureDescriptor>();

            OperandManager = new OperandManager();

            _sb = new StringBuilder();
        }

        public void AppendLine()
        {
            _sb.AppendLine();
        }

        public void AppendLine(string str)
        {
            _sb.AppendLine(_indentation + str);
        }

        public string GetCode()
        {
            return _sb.ToString();
        }

        public void EnterScope()
        {
            AppendLine("{");

            _level++;

            UpdateIndentation();
        }

        public void LeaveScope(string suffix = "")
        {
            if (_level == 0)
            {
                return;
            }

            _level--;

            UpdateIndentation();

            AppendLine("}" + suffix);
        }

        private int FindDescriptorIndex(List<TextureDescriptor> list, AstTextureOperation texOp)
        {
            return list.FindIndex(descriptor =>
                descriptor.Type == texOp.Type &&
                descriptor.CbufSlot == texOp.CbufSlot &&
                descriptor.HandleIndex == texOp.Handle &&
                descriptor.Format == texOp.Format);
        }

        public int FindTextureDescriptorIndex(AstTextureOperation texOp)
        {
            return FindDescriptorIndex(TextureDescriptors, texOp);
        }

        public int FindImageDescriptorIndex(AstTextureOperation texOp)
        {
            return FindDescriptorIndex(ImageDescriptors, texOp);
        }

        public StructuredFunction GetFunction(int id)
        {
            return _info.Functions[id];
        }

        private void UpdateIndentation()
        {
            _indentation = GetIndentation(_level);
        }

        private static string GetIndentation(int level)
        {
            string indentation = string.Empty;

            for (int index = 0; index < level; index++)
            {
                indentation += Tab;
            }

            return indentation;
        }
    }
}