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 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     @property BufferUsage usage() {
32         return _usage;
33     }
34 
35     @property size_t size() {
36         return _size;
37     }
38 
39     override @property MemoryRequirements memoryRequirements() {
40         VkMemoryRequirements vkMr;
41         vk.GetBufferMemoryRequirements(vkDev, vkObj, &vkMr);
42         return vkMr.toGfx();
43     }
44 
45     override void bindMemory(DeviceMemory mem, in size_t offset)
46     {
47         assert(!_vdm, "Bind the same buffer twice");
48         _vdm = enforce(cast(VulkanDeviceMemory)mem, "Did not pass a Vulkan memory");
49         vulkanEnforce(
50             vk.BindBufferMemory(vkDev, vkObj, _vdm.vkObj, offset),
51             "Could not bind image memory"
52         );
53         _vdm.retain();
54     }
55 
56     override @property DeviceMemory boundMemory() {
57         return _vdm;
58     }
59 
60     override VulkanBufferView createView(Format format, size_t offset, size_t size)
61     {
62         VkBufferViewCreateInfo bvci;
63         bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
64         bvci.format = format.toVk();
65         bvci.offset = offset;
66         bvci.range = size;
67 
68         VkBufferView vkBv;
69         vulkanEnforce(
70             vk.CreateBufferView(vkDev, &bvci, null, &vkBv),
71             "Could not create Vulkan buffer view"
72         );
73 
74         return new VulkanBufferView(vkBv, this, format, offset, size);
75     }
76 
77     private VulkanDeviceMemory _vdm;
78     private BufferUsage _usage;
79     private size_t _size;
80 }
81 
82 
83 class VulkanBufferView : VulkanDevObj!(VkBufferView, "DestroyBufferView"), BufferView
84 {
85     mixin(atomicRcCode);
86 
87     this(VkBufferView vkObj, VulkanBuffer buf, Format format, size_t offset, size_t size)
88     {
89         super(vkObj, buf.dev);
90         _buf = buf;
91         _buf.retain();
92         _format = format;
93         _offset = offset;
94         _size = size;
95     }
96 
97     override void dispose()
98     {
99         super.dispose();
100         _buf.release();
101         _buf = null;
102     }
103 
104     override @property VulkanBuffer buffer() {
105         return _buf;
106     }
107 
108     override @property Format format() {
109         return _format;
110     }
111 
112     override @property size_t offset() {
113         return _offset;
114     }
115 
116     override @property size_t size() {
117         return _size;
118     }
119 
120 
121     private VulkanBuffer _buf;
122     private Format _format;
123     private size_t _offset;
124     private size_t _size;
125 }