aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/ResourceLayoutBuilder.cs
blob: eac0d6c20062a8f3322df024568ba8b6978e3c18 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using Ryujinx.Graphics.GAL;
using System;
using System.Collections.Generic;

namespace Ryujinx.Graphics.Vulkan
{
    class ResourceLayoutBuilder
    {
        private const int TotalSets = PipelineBase.DescriptorSetLayouts;

        private readonly List<ResourceDescriptor>[] _resourceDescriptors;
        private readonly List<ResourceUsage>[] _resourceUsages;

        public ResourceLayoutBuilder()
        {
            _resourceDescriptors = new List<ResourceDescriptor>[TotalSets];
            _resourceUsages = new List<ResourceUsage>[TotalSets];

            for (int index = 0; index < TotalSets; index++)
            {
                _resourceDescriptors[index] = new();
                _resourceUsages[index] = new();
            }
        }

        public ResourceLayoutBuilder Add(ResourceStages stages, ResourceType type, int binding)
        {
            int setIndex = type switch
            {
                ResourceType.UniformBuffer => PipelineBase.UniformSetIndex,
                ResourceType.StorageBuffer => PipelineBase.StorageSetIndex,
                ResourceType.TextureAndSampler or ResourceType.BufferTexture => PipelineBase.TextureSetIndex,
                ResourceType.Image or ResourceType.BufferImage => PipelineBase.ImageSetIndex,
                _ => throw new ArgumentException($"Invalid resource type \"{type}\".")
            };

            ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;

            _resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages));
            _resourceUsages[setIndex].Add(new ResourceUsage(binding, type, stages, access));

            return this;
        }

        private static bool IsReadOnlyType(ResourceType type)
        {
            return type == ResourceType.UniformBuffer ||
                   type == ResourceType.Sampler ||
                   type == ResourceType.TextureAndSampler ||
                   type == ResourceType.BufferTexture;
        }

        public ResourceLayout Build()
        {
            var descriptors = new ResourceDescriptorCollection[TotalSets];
            var usages = new ResourceUsageCollection[TotalSets];

            for (int index = 0; index < TotalSets; index++)
            {
                descriptors[index] = new ResourceDescriptorCollection(_resourceDescriptors[index].ToArray().AsReadOnly());
                usages[index] = new ResourceUsageCollection(_resourceUsages[index].ToArray().AsReadOnly());
            }

            return new ResourceLayout(descriptors.AsReadOnly(), usages.AsReadOnly());
        }
    }
}