1 module sbylib.wrapper.vulkan.descriptorset;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan.buffer;
6 import sbylib.wrapper.vulkan.descriptorpool;
7 import sbylib.wrapper.vulkan.descriptorsetlayout;
8 import sbylib.wrapper.vulkan.device;
9 import sbylib.wrapper.vulkan.enums;
10 import sbylib.wrapper.vulkan.imageview;
11 import sbylib.wrapper.vulkan.sampler;
12 import sbylib.wrapper.vulkan.util;
13 
14 class DescriptorSet {
15     static struct AllocateInfo {
16         @vkProp() {
17             DescriptorPool descriptorPool;
18         }
19 
20         @vkProp("pSetLayouts", "descriptorSetCount") {
21             const DescriptorSetLayout[] setLayouts;
22         }
23 
24         mixin VkTo!(VkDescriptorSetAllocateInfo);
25     }
26 
27     static struct Write {
28         static struct ImageInfo {
29             @vkProp() {
30                 Sampler sampler;
31                 ImageView imageView;
32                 ImageLayout imageLayout;
33             }
34             mixin VkTo!(VkDescriptorImageInfo);
35         }
36 
37         static struct BufferInfo {
38             @vkProp() {
39                 Buffer buffer;
40                 VkDeviceSize offset;
41                 VkDeviceSize range;
42             }
43             mixin VkTo!(VkDescriptorBufferInfo);
44         }
45 
46         @vkProp() {
47             DescriptorSet dstSet;
48             uint dstBinding;
49             uint dstArrayElement;
50             DescriptorType descriptorType;
51         }
52 
53         @vkProp("pImageInfo", "descriptorCount") {
54             ImageInfo[] imageInfo;
55         }
56 
57         @vkProp("pBufferInfo", "descriptorCount") {
58             BufferInfo[] bufferInfo;
59         }
60 
61         @vkProp("pTexelBufferView", "descriptorCount") {
62             VkBufferView[] texelBufferView;
63         }
64 
65         mixin VkTo!(VkWriteDescriptorSet);
66     }
67 
68     static struct Copy {
69         @vkProp() {
70             DescriptorSet srcSet;
71             uint srcBinding;
72             uint srcArrayElement;
73             DescriptorSet dstSet;
74             uint dstBinding;
75             uint dstArrayElement;
76             uint descriptorCount;
77         }
78 
79         mixin VkTo!(VkCopyDescriptorSet);
80     }
81 
82     private Device device;
83     private DescriptorPool descriptorPool;
84     private VkDescriptorSet descriptorSet;
85 
86     mixin ImplNameSetter!(device, descriptorSet, DebugReportObjectType.DescriptorSet);
87 
88     private this(Device device, DescriptorPool descriptorPool, VkDescriptorSet descriptorSet) {
89         import std.exception : enforce;
90 
91         this.device = device;
92         this.descriptorPool = descriptorPool;
93         this.descriptorSet = descriptorSet;
94     }
95 
96     ~this() {
97         enforceVK(vkFreeDescriptorSets(device.device, descriptorPool.descriptorPool, 1, &descriptorSet));
98     }
99 
100     mixin VkTo!(VkDescriptorSet);
101 
102     static DescriptorSet[] allocate(Device device, AllocateInfo _info) {
103         VkDescriptorSet[] descriptorSets = new VkDescriptorSet[_info.setLayouts.length];
104 
105         auto info = _info.vkTo();
106 
107         enforceVK(vkAllocateDescriptorSets(device.device, &info, descriptorSets.ptr));
108 
109         return descriptorSets.map!(cb => new DescriptorSet(device, _info.descriptorPool, cb)).array;
110     }
111 
112     void update(uint W, uint C)(Write[W] _writes, Copy[C] _copies) {
113         VkWriteDescriptorSet[W] writes;
114         static foreach (i; 0..W) {
115             writes[i] = _writes[i].vkTo();
116         }
117 
118         VkCopyDescriptorSet[C] copies;
119         static foreach (i; 0..C) {
120             copies[i] = _copies[i].vkTo();
121         }
122         vkUpdateDescriptorSets(device.device, W, writes.ptr, C, copies.ptr);
123     }
124 }