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 VulkanImage : Image
18 {
19     this(VkImage vk, VulkanDevice dev, ImageType type, ImageDims dims, Format format)
20     {
21         _vk = vk;
22         _dev = dev;
23         _type = type;
24         _dims = dims;
25         _format = format;
26         _cmds = dev.cmds;
27     }
28 
29     final @property VkImage vk()
30     {
31         return _vk;
32     }
33 
34     final @property VulkanDevice dev()
35     {
36         return _dev;
37     }
38 
39     final @property VkDevice vkDev()
40     {
41         return _dev.vk;
42     }
43 
44     final @property VkDeviceCmds cmds() {
45         return _cmds;
46     }
47 
48     final override @property ImageType type() {
49         return _type;
50     }
51     final @property Format format() {
52         return _format;
53     }
54     final override @property ImageDims dims() {
55         return _dims;
56     }
57     final @property uint levels() {
58         return _levels;
59     }
60 
61     override VulkanImageView createView(ImageType viewType, ImageSubresourceRange isr, Swizzle swizzle)
62     {
63         const it = type;
64         VkImageViewCreateInfo ivci;
65         ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
66         ivci.image = vk;
67         ivci.viewType = viewType.toVkView();
68         ivci.format = format.toVk();
69         ivci.subresourceRange = isr.toVk();
70         ivci.components = swizzle.toVk();
71 
72         VkImageView vkIv;
73         vulkanEnforce(
74             cmds.createImageView(vkDev, &ivci, null, &vkIv),
75             "Could not create Vulkan View"
76         );
77 
78         return new VulkanImageView(vkIv, this, isr, swizzle);
79     }
80 
81     private VkImage _vk;
82     private VulkanDevice _dev;
83     private VkDeviceCmds _cmds;
84     private ImageType _type;
85     private ImageDims _dims;
86     private Format _format;
87     private uint _levels;
88 }
89 
90 class VulkanImageRc : VulkanImage, ImageRc
91 {
92     mixin(atomicRcCode);
93 
94     this(VkImage vk, VulkanDevice dev, ImageType type, ImageDims dims, Format format)
95     {
96         super(vk, dev, type, dims, format);
97         dev.retain();
98     }
99 
100     override void dispose() {
101         cmds.destroyImage(vkDev, vk, null);
102         if (_vdm) _vdm.release();
103         dev.release();
104     }
105 
106     override @property MemoryRequirements memoryRequirements() {
107         VkMemoryRequirements vkMr;
108         cmds.getImageMemoryRequirements(vkDev, vk, &vkMr);
109         return vkMr.toGfx();
110     }
111 
112     override void bindMemory(DeviceMemory mem, in size_t offset)
113     {
114         assert(!_vdm, "Bind the same buffer twice");
115         _vdm = enforce(cast(VulkanDeviceMemory)mem, "Did not pass a Vulkan memory");
116         vulkanEnforce(
117             cmds.bindImageMemory(vkDev, vk, _vdm.vk, offset),
118             "Could not bind image memory"
119         );
120         _vdm.retain();
121     }
122 
123     VulkanDeviceMemory _vdm;
124 }
125 
126 class VulkanImageView : VulkanDevObj!(VkImageView, "destroyImageView"), ImageView
127 {
128     mixin(atomicRcCode);
129 
130     this(VkImageView vk, VulkanImage img, ImageSubresourceRange isr, Swizzle swizzle)
131     {
132         super(vk, img.dev);
133         _img = img;
134         _isr = isr;
135         _swizzle = swizzle;
136     }
137 
138     override void dispose()
139     {
140         super.dispose();
141         _img = null;
142     }
143 
144     override @property VulkanImage image() {
145         return _img;
146     }
147 
148     override @property ImageSubresourceRange subresourceRange() {
149         return _isr;
150     }
151 
152     override @property Swizzle swizzle() {
153         return _swizzle;
154     }
155 
156     private VulkanImage _img;
157     private ImageSubresourceRange _isr;
158     private Swizzle _swizzle;
159 }
160 
161 class VulkanSampler : VulkanDevObj!(VkSampler, "destroySampler"), Sampler
162 {
163     mixin(atomicRcCode);
164     this(VkSampler sampler, VulkanDevice dev) {
165         super(sampler, dev);
166     }
167 }