1 module sbylib.graphics.wrapper.image;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan;
6 import sbylib.graphics.wrapper.commandbuffer;
7 import sbylib.graphics.wrapper.device;
8 import sbylib.graphics.wrapper.queue;
9 import sbylib.graphics.util.own;
10 
11 class VImage {
12 
13     private @own {
14         Image _image;
15         DeviceMemory _memory;
16     }
17 
18     mixin ImplReleaseOwn;
19 
20     this(Image _image, MemoryProperties.MemoryType.Flags flag) {
21         this._image = _image;
22         this._memory = _image.allocateMemory(VDevice().gpu, flag);
23     
24         _memory.bindImage(_image, 0);
25     }
26 
27     Image image() {
28         return _image;
29     }
30 
31     DeviceMemory memory() {
32         return _memory;
33     }
34 
35     void transit(ImageLayout oldLayout, ImageLayout newLayout, ImageAspect aspect) {
36         auto commandBuffer = VCommandBuffer.allocate(VCommandBuffer.Type.Graphics);
37         scope (exit)
38             commandBuffer.destroy();
39 
40         with (commandBuffer(CommandBuffer.BeginInfo.Flags.OneTimeSubmit)) {
41             VkImageMemoryBarrier barrier = {
42                 oldLayout: oldLayout,
43                 newLayout: newLayout,
44                 image: image.image,
45                 subresourceRange: {
46                     aspectMask: aspect,
47                     baseMipLevel: 0,
48                     levelCount: 1,
49                     baseArrayLayer: 0,
50                     layerCount: 1
51                 }
52             };
53             
54             // wait at bottom of pipe until before command's stage comes to top of pipe (does not wait at all)
55             cmdPipelineBarrier(PipelineStage.TopOfPipe, PipelineStage.BottomOfPipe, 0, [], [], [barrier]);
56         }
57 
58         auto fence = VQueue(VQueue.Type.Graphics).submitWithFence(commandBuffer, "transit");
59         fence.wait();
60         fence.destroy();
61     }
62 }