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 }