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 }