1 module sbylib.wrapper.vulkan.image;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan.device;
6 import sbylib.wrapper.vulkan.devicememory;
7 import sbylib.wrapper.vulkan.enums;
8 import sbylib.wrapper.vulkan.physicaldevice;
9 import sbylib.wrapper.vulkan.memoryproperties;
10 import sbylib.wrapper.vulkan.util;
11 
12 class Image {
13     static struct CreateInfo {
14         @vkProp() {
15             VkImageCreateFlags flags;
16             ImageType imageType;
17             VkFormat format;
18             VkExtent3D extent;
19             uint mipLevels;
20             uint arrayLayers;
21             SampleCount samples;
22             ImageTiling tiling;
23             ImageUsage usage;
24             SharingMode sharingMode;
25             ImageLayout initialLayout;
26         }
27 
28         @vkProp("pQueueFamilyIndices", "queueFamilyIndexCount") {
29             const uint[] queueFamilyIndices;
30         }
31 
32         mixin VkTo!(VkImageCreateInfo);
33     }
34 
35     private Device device;
36     public VkImage image;
37     private bool mustRelease;
38 
39     mixin ImplNameSetter!(device, image, DebugReportObjectType.Image);
40 
41     this(Device device, CreateInfo _info) {
42         this.device = device;
43 
44         auto info = _info.vkTo();
45 
46         enforce(device !is null);
47         enforce(device.device !is null);
48         enforceVK(vkCreateImage(device.device, &info, null, &image));
49         enforce(image != VK_NULL_HANDLE);
50         this.mustRelease = true;
51     }
52 
53     this(VkImage image) {
54         this.image = image;
55         enforce(image != VK_NULL_HANDLE);
56         this.mustRelease = false;
57     }
58 
59     ~this() {
60         if (mustRelease)
61             vkDestroyImage(device.device, image, null);
62     }
63 
64     mixin VkTo!(VkImage);
65 
66     VkSubresourceLayout getSubresourceLayout(VkImageSubresource subResource) {
67         VkSubresourceLayout subResourceLayout;
68         vkGetImageSubresourceLayout(device.device, image, &subResource, &subResourceLayout);
69         return subResourceLayout;
70     }
71 
72     DeviceMemory allocateMemory(PhysicalDevice gpu, MemoryProperties.MemoryType.Flags memoryTypeFlag) {
73         const requirements = device.getImageMemoryRequirements(this);
74         DeviceMemory.AllocateInfo deviceMemoryAllocInfo = {
75             allocationSize: requirements.size,
76             memoryTypeIndex: cast(uint)gpu.getMemoryProperties().memoryTypes.enumerate
77                 .countUntil!(p => requirements.acceptable(p.index) && p.value.supports(memoryTypeFlag))
78         };
79         enforce(deviceMemoryAllocInfo.memoryTypeIndex != -1);
80         return new DeviceMemory(device, deviceMemoryAllocInfo);
81     }
82 }