1 /// Vulkan buffer module
2 module gfx.vulkan.buffer;
3 
4 package:
5 
6 import gfx.bindings.vulkan;
7 
8 import gfx.core.rc;
9 import gfx.graal.buffer;
10 import gfx.vulkan.device;
11 import gfx.vulkan.error;
12 import gfx.vulkan.memory;
13 
14 final class VulkanBuffer : VulkanDevObj!(VkBuffer, "DestroyBuffer"), Buffer
15 {
16     mixin(atomicRcCode);
17 
18     this (VkBuffer vkObj, VulkanDevice dev, BufferUsage usage, size_t size)
19     {
20         super(vkObj, dev);
21         _usage = usage;
22         _size = size;
23     }
24 
25     override void dispose() {
26         vk.DestroyBuffer(vkDev, vkObj, null);
27         if (_vdm) _vdm.release();
28         dev.release();
29     }
30 
31     override Device device() {
32         return dev;
33     }
34 
35     @property BufferUsage usage() {
36         return _usage;
37     }
38 
39     @property size_t size() {
40         return _size;
41     }
42 
43     override @property MemoryRequirements memoryRequirements() {
44         VkMemoryRequirements vkMr;
45         vk.GetBufferMemoryRequirements(vkDev, vkObj, &vkMr);
46         return vkMr.toGfx();
47     }
48 
49     override void bindMemory(DeviceMemory mem, in size_t offset)
50     {
51         assert(!_vdm, "Bind the same buffer twice");
52         _vdm = enforce(cast(VulkanDeviceMemory)mem, "Did not pass a Vulkan memory");
53         vulkanEnforce(
54             vk.BindBufferMemory(vkDev, vkObj, _vdm.vkObj, offset),
55             "Could not bind image memory"
56         );
57         _vdm.retain();
58     }
59 
60     override @property DeviceMemory boundMemory() {
61         return _vdm;
62     }
63 
64     override VulkanTexelBufferView createTexelView(Format format, size_t offset, size_t size)
65     {
66         VkBufferViewCreateInfo bvci;
67         bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
68         bvci.format = format.toVk();
69         bvci.offset = offset;
70         bvci.range = size;
71 
72         VkBufferView vkBv;
73         vulkanEnforce(
74             vk.CreateBufferView(vkDev, &bvci, null, &vkBv),
75             "Could not create Vulkan buffer view"
76         );
77 
78         return new VulkanTexelBufferView(vkBv, this, format, offset, size);
79     }
80 
81     private VulkanDeviceMemory _vdm;
82     private BufferUsage _usage;
83     private size_t _size;
84 }
85 
86 
87 class VulkanTexelBufferView : VulkanDevObj!(VkBufferView, "DestroyBufferView"), TexelBufferView
88 {
89     mixin(atomicRcCode);
90 
91     this(VkBufferView vkObj, VulkanBuffer buf, Format format, size_t offset, size_t size)
92     {
93         super(vkObj, buf.dev);
94         _buf = buf;
95         _buf.retain();
96         _format = format;
97         _offset = offset;
98         _size = size;
99     }
100 
101     override void dispose()
102     {
103         super.dispose();
104         _buf.release();
105         _buf = null;
106     }
107 
108     override @property VulkanBuffer buffer() {
109         return _buf;
110     }
111 
112     override @property Format format() {
113         return _format;
114     }
115 
116     override @property size_t offset() {
117         return _offset;
118     }
119 
120     override @property size_t size() {
121         return _size;
122     }
123 
124 
125     private VulkanBuffer _buf;
126     private Format _format;
127     private size_t _offset;
128     private size_t _size;
129 }