1 /// Vulkan image module
2 module gfx.vulkan.image;
3
4 package:
5
6 import gfx.bindings.vulkan;
7
8 import gfx.core.rc;
9 import gfx.graal.image;
10 import gfx.graal.memory;
11 import gfx.vulkan;
12 import gfx.vulkan.conv;
13 import gfx.vulkan.device;
14 import gfx.vulkan.error;
15 import gfx.vulkan.memory;
16
17 class VulkanImageBase : ImageBase
18 {
19 this(VkImage vkObj, VulkanDevice dev, ImageInfo info)
20 {
21 _vkObj = vkObj;
22 _dev = dev;
23 _info = info;
24 _vk = dev.vk;
25 }
26
27 final @property VkImage vkObj()
28 {
29 return _vkObj;
30 }
31
32 final @property VulkanDevice dev()
33 {
34 return _dev;
35 }
36
37 final @property VkDevice vkDev()
38 {
39 return _dev.vkObj;
40 }
41
42 final @property VkDeviceCmds vk() {
43 return _vk;
44 }
45
46 final override @property ImageInfo info() {
47 return _info;
48 }
49
50 override VulkanImageView createView(ImageType viewType, ImageSubresourceRange isr, Swizzle swizzle)
51 {
52 const it = _info.type;
53 VkImageViewCreateInfo ivci;
54 ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
55 ivci.image = vkObj;
56 ivci.viewType = viewType.toVkView();
57 ivci.format = _info.format.toVk();
58 ivci.subresourceRange = isr.toVk();
59 ivci.components = swizzle.toVk();
60
61 VkImageView vkIv;
62 vulkanEnforce(
63 vk.CreateImageView(vkDev, &ivci, null, &vkIv),
64 "Could not create Vulkan View"
65 );
66
67 return new VulkanImageView(vkIv, this, isr, swizzle);
68 }
69
70 private VkImage _vkObj;
71 private VulkanDevice _dev;
72 private VkDeviceCmds _vk;
73 private ImageInfo _info;
74 }
75
76 final class VulkanImage : VulkanImageBase, Image
77 {
78 mixin(atomicRcCode);
79
80 this(VkImage vkObj, VulkanDevice dev, ImageInfo info)
81 {
82 super(vkObj, dev, info);
83 dev.retain();
84 }
85
86 override void dispose() {
87 vk.DestroyImage(vkDev, vkObj, null);
88 if (_vdm) _vdm.release();
89 dev.release();
90 }
91
92 override Device device() {
93 return dev;
94 }
95
96 override @property MemoryRequirements memoryRequirements() {
97 VkMemoryRequirements vkMr;
98 vk.GetImageMemoryRequirements(vkDev, vkObj, &vkMr);
99 return vkMr.toGfx();
100 }
101
102 override void bindMemory(DeviceMemory mem, in size_t offset)
103 {
104 assert(!_vdm, "Bind the same buffer twice");
105 _vdm = enforce(cast(VulkanDeviceMemory)mem, "Did not pass a Vulkan memory");
106 vulkanEnforce(
107 vk.BindImageMemory(vkDev, vkObj, _vdm.vkObj, offset),
108 "Could not bind image memory"
109 );
110 _vdm.retain();
111 }
112
113 override @property DeviceMemory boundMemory() {
114 return _vdm;
115 }
116
117 VulkanDeviceMemory _vdm;
118 }
119
120 class VulkanImageView : VulkanDevObj!(VkImageView, "DestroyImageView"), ImageView
121 {
122 mixin(atomicRcCode);
123
124 this(VkImageView vkObj, VulkanImageBase img, ImageSubresourceRange isr, Swizzle swizzle)
125 {
126 super(vkObj, img.dev);
127 _img = img;
128 _isr = isr;
129 _swizzle = swizzle;
130 }
131
132 override void dispose()
133 {
134 super.dispose();
135 _img = null;
136 }
137
138 override @property VulkanImageBase image() {
139 return _img;
140 }
141
142 override @property ImageSubresourceRange subresourceRange() {
143 return _isr;
144 }
145
146 override @property Swizzle swizzle() {
147 return _swizzle;
148 }
149
150 private VulkanImageBase _img;
151 private ImageSubresourceRange _isr;
152 private Swizzle _swizzle;
153 }
154
155 final class VulkanSampler : VulkanDevObj!(VkSampler, "DestroySampler"), Sampler
156 {
157 mixin(atomicRcCode);
158 this(VkSampler sampler, VulkanDevice dev) {
159 super(sampler, dev);
160 }
161 override @property Device device() {
162 return dev;
163 }
164 }