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 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 @property MemoryRequirements memoryRequirements() { 93 VkMemoryRequirements vkMr; 94 vk.GetImageMemoryRequirements(vkDev, vkObj, &vkMr); 95 return vkMr.toGfx(); 96 } 97 98 override void bindMemory(DeviceMemory mem, in size_t offset) 99 { 100 assert(!_vdm, "Bind the same buffer twice"); 101 _vdm = enforce(cast(VulkanDeviceMemory)mem, "Did not pass a Vulkan memory"); 102 vulkanEnforce( 103 vk.BindImageMemory(vkDev, vkObj, _vdm.vkObj, offset), 104 "Could not bind image memory" 105 ); 106 _vdm.retain(); 107 } 108 109 VulkanDeviceMemory _vdm; 110 } 111 112 class VulkanImageView : VulkanDevObj!(VkImageView, "DestroyImageView"), ImageView 113 { 114 mixin(atomicRcCode); 115 116 this(VkImageView vkObj, VulkanImageBase img, ImageSubresourceRange isr, Swizzle swizzle) 117 { 118 super(vkObj, img.dev); 119 _img = img; 120 _isr = isr; 121 _swizzle = swizzle; 122 } 123 124 override void dispose() 125 { 126 super.dispose(); 127 _img = null; 128 } 129 130 override @property VulkanImageBase image() { 131 return _img; 132 } 133 134 override @property ImageSubresourceRange subresourceRange() { 135 return _isr; 136 } 137 138 override @property Swizzle swizzle() { 139 return _swizzle; 140 } 141 142 private VulkanImageBase _img; 143 private ImageSubresourceRange _isr; 144 private Swizzle _swizzle; 145 } 146 147 class VulkanSampler : VulkanDevObj!(VkSampler, "DestroySampler"), Sampler 148 { 149 mixin(atomicRcCode); 150 this(VkSampler sampler, VulkanDevice dev) { 151 super(sampler, dev); 152 } 153 }