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 
36     this(VkPipelineLayout vkObj, VulkanDevice dev,
37             DescriptorSetLayout[] descriptorLayouts,
38             in PushConstantRange[] pushConstantRanges)
39     {
40         super(vkObj, dev);
41         _descriptorLayouts = descriptorLayouts;
42         _pushConstantRanges = pushConstantRanges;
43         retainArr(_descriptorLayouts);
44     }
45 
46     override void dispose()
47     {
48         releaseArr(_descriptorLayouts);
49         super.dispose();
50     }
51 
52     override @property Device device() {
53         return dev;
54     }
55 
56     override @property DescriptorSetLayout[] descriptorLayouts()
57     {
58         return _descriptorLayouts;
59     }
60 
61     override @property const(PushConstantRange)[] pushConstantRanges()
62     {
63         return _pushConstantRanges;
64     }
65 
66     private DescriptorSetLayout[] _descriptorLayouts;
67     private const(PushConstantRange)[] _pushConstantRanges;
68 }
69 
70 class VulkanPipeline : VulkanDevObj!(VkPipeline, "DestroyPipeline"), Pipeline
71 {
72     mixin(atomicRcCode);
73     this(VkPipeline vkObj, VulkanDevice dev, PipelineLayout pl)
74     {
75         super(vkObj, dev);
76         this.pl = pl;
77     }
78 
79     override void dispose() {
80         pl.unload();
81         super.dispose();
82     }
83 
84     override @property Device device() {
85         return dev;
86     }
87 
88     private Rc!PipelineLayout pl;
89 }
90 
91 class VulkanDescriptorSetLayout : VulkanDevObj!(VkDescriptorSetLayout, "DestroyDescriptorSetLayout"), DescriptorSetLayout
92 {
93     mixin(atomicRcCode);
94     this(VkDescriptorSetLayout vkObj, VulkanDevice dev)
95     {
96         super(vkObj, dev);
97     }
98 
99     override @property Device device() {
100         return dev;
101     }
102 }
103 
104 class VulkanDescriptorPool : VulkanDevObj!(VkDescriptorPool, "DestroyDescriptorPool"), DescriptorPool
105 {
106     mixin(atomicRcCode);
107     this(VkDescriptorPool vkObj, VulkanDevice dev)
108     {
109         super(vkObj, dev);
110     }
111 
112     override @property Device device() {
113         return dev;
114     }
115 
116     override DescriptorSet[] allocate(DescriptorSetLayout[] layouts)
117     {
118         import std.algorithm : map;
119         import std.array : array;
120 
121         auto vkLayouts = layouts.map!(
122             l => enforce(
123                 cast(VulkanDescriptorSetLayout)l,
124                 "VulkanDescriptorPool.allocate: Did not supply a Vulkan DescriptorSetLayout"
125             ).vkObj
126         ).array;
127 
128         VkDescriptorSetAllocateInfo ai;
129         ai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
130         ai.descriptorPool = vkObj;
131         ai.descriptorSetCount = cast(uint)vkLayouts.length;
132         ai.pSetLayouts = vkLayouts.ptr;
133 
134         auto vkSets = new VkDescriptorSet[vkLayouts.length];
135         vulkanEnforce(
136             vk.AllocateDescriptorSets(vkDev, &ai, &vkSets[0]),
137             "Could not allocate Vulkan descriptor sets"
138         );
139 
140         auto sets = vkSets.map!(
141             vkS => cast(DescriptorSet)new VulkanDescriptorSet(vkS, this)
142         ).array;
143 
144         _allocatedSets ~= sets;
145 
146         return sets;
147     }
148 
149     override void reset() {
150         vulkanEnforce(
151             vk.ResetDescriptorPool(vkDev, vkObj, 0),
152             "Could not reset Descriptor pool"
153         );
154         _allocatedSets = [];
155     }
156 
157     DescriptorSet[] _allocatedSets;
158 }
159 
160 class VulkanDescriptorSet : VulkanObj!(VkDescriptorSet), DescriptorSet
161 {
162     this (VkDescriptorSet vkObj, VulkanDescriptorPool pool)
163     {
164         super(vkObj);
165         _pool = pool;
166     }
167 
168     @property DescriptorPool pool() {
169         return _pool;
170     }
171 
172     VulkanDescriptorPool _pool;
173 }