1 module gfx.vulkan.pipeline;
2 
3 package:
4 
5 import gfx.bindings.vulkan;
6 
7 import gfx.core.rc;
8 import gfx.graal.pipeline;
9 import gfx.vulkan;
10 import gfx.vulkan.device;
11 
12 class VulkanShaderModule : VulkanDevObj!(VkShaderModule, "DestroyShaderModule"), ShaderModule
13 {
14     mixin(atomicRcCode);
15     this(VkShaderModule vkObj, VulkanDevice dev, string entryPoint)
16     {
17         super(vkObj, dev);
18         _entryPoint = entryPoint;
19     }
20 
21     override @property Device device() {
22         return dev;
23     }
24 
25     override @property string entryPoint() {
26         return _entryPoint;
27     }
28 
29     private string _entryPoint;
30 }
31 
32 class VulkanPipelineLayout : VulkanDevObj!(VkPipelineLayout, "DestroyPipelineLayout"), PipelineLayout
33 {
34     mixin(atomicRcCode);
35     this(VkPipelineLayout vkObj, VulkanDevice dev)
36     {
37         super(vkObj, dev);
38     }
39 
40     override @property Device device() {
41         return dev;
42     }
43 }
44 
45 class VulkanPipeline : VulkanDevObj!(VkPipeline, "DestroyPipeline"), Pipeline
46 {
47     mixin(atomicRcCode);
48     this(VkPipeline vkObj, VulkanDevice dev, PipelineLayout pl)
49     {
50         super(vkObj, dev);
51         this.pl = pl;
52     }
53 
54     override void dispose() {
55         pl.unload();
56         super.dispose();
57     }
58 
59     override @property Device device() {
60         return dev;
61     }
62 
63     private Rc!PipelineLayout pl;
64 }
65 
66 class VulkanDescriptorSetLayout : VulkanDevObj!(VkDescriptorSetLayout, "DestroyDescriptorSetLayout"), DescriptorSetLayout
67 {
68     mixin(atomicRcCode);
69     this(VkDescriptorSetLayout vkObj, VulkanDevice dev)
70     {
71         super(vkObj, dev);
72     }
73 
74     override @property Device device() {
75         return dev;
76     }
77 }
78 
79 class VulkanDescriptorPool : VulkanDevObj!(VkDescriptorPool, "DestroyDescriptorPool"), DescriptorPool
80 {
81     mixin(atomicRcCode);
82     this(VkDescriptorPool vkObj, VulkanDevice dev)
83     {
84         super(vkObj, dev);
85     }
86 
87     override @property Device device() {
88         return dev;
89     }
90 
91     override DescriptorSet[] allocate(DescriptorSetLayout[] layouts)
92     {
93         import std.algorithm : map;
94         import std.array : array;
95 
96         auto vkLayouts = layouts.map!(
97             l => enforce(
98                 cast(VulkanDescriptorSetLayout)l,
99                 "VulkanDescriptorPool.allocate: Did not supply a Vulkan DescriptorSetLayout"
100             ).vkObj
101         ).array;
102 
103         VkDescriptorSetAllocateInfo ai;
104         ai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
105         ai.descriptorPool = vkObj;
106         ai.descriptorSetCount = cast(uint)vkLayouts.length;
107         ai.pSetLayouts = vkLayouts.ptr;
108 
109         auto vkSets = new VkDescriptorSet[vkLayouts.length];
110         vulkanEnforce(
111             vk.AllocateDescriptorSets(vkDev, &ai, &vkSets[0]),
112             "Could not allocate Vulkan descriptor sets"
113         );
114 
115         auto sets = vkSets.map!(
116             vkS => cast(DescriptorSet)new VulkanDescriptorSet(vkS, this)
117         ).array;
118 
119         _allocatedSets ~= sets;
120 
121         return sets;
122     }
123 
124     override void reset() {
125         vulkanEnforce(
126             vk.ResetDescriptorPool(vkDev, vkObj, 0),
127             "Could not reset Descriptor pool"
128         );
129         _allocatedSets = [];
130     }
131 
132     DescriptorSet[] _allocatedSets;
133 }
134 
135 class VulkanDescriptorSet : VulkanObj!(VkDescriptorSet), DescriptorSet
136 {
137     this (VkDescriptorSet vkObj, VulkanDescriptorPool pool)
138     {
139         super(vkObj);
140         _pool = pool;
141     }
142 
143     @property DescriptorPool pool() {
144         return _pool;
145     }
146 
147     VulkanDescriptorPool _pool;
148 }