1 module sbylib.graphics.material.standard.renderpass;
2 
3 import std;
4 import sbylib.graphics.core.presenter;
5 import sbylib.graphics.util.own;
6 import sbylib.graphics.wrapper;
7 
8 class StandardRenderPass : VRenderPass {
9 
10     enum ColorFormat = VK_FORMAT_B8G8R8A8_UNORM;
11     enum DepthFormat = VK_FORMAT_D32_SFLOAT;
12 
13     @own {
14         private {
15             ImageView[] colorImageViews;
16             VImage depthImage;
17             ImageView depthImageView;
18         }
19     }
20     mixin ImplReleaseOwn;
21 
22     mixin ImplOpCall;
23 
24     immutable RenderPass.CreateInfo c = {
25         attachments: [{
26             format: ColorFormat,
27             samples: SampleCount.Count1,
28             loadOp: AttachmentLoadOp.Clear,
29             storeOp: AttachmentStoreOp.Store,
30             initialLayout: ImageLayout.Undefined,
31             finalLayout: ImageLayout.PresentSrc,
32         }, {
33             format: DepthFormat,
34             samples: SampleCount.Count1,
35             loadOp: AttachmentLoadOp.Clear,
36             storeOp: AttachmentStoreOp.Store,
37             initialLayout: ImageLayout.Undefined,
38             finalLayout: ImageLayout.DepthStencilAttachmentOptimal,
39         }],
40         subpasses: [{
41             pipelineBindPoint: PipelineBindPoint.Graphics,
42             colorAttachments: [{
43                 attachment: 0,
44                 layout: ImageLayout.ColorAttachmentOptimal
45             }],
46             depthStencilAttachments: [{
47                 attachment: 1,
48                 layout: ImageLayout.DepthStencilAttachmentOptimal
49             }]
50         }]
51     };
52     mixin Info!c;
53 
54     private this(Window window) {
55         super(window);
56 
57         foreach (im; Presenter(window).getSwapchainImages()) {
58             this.colorImageViews ~= createImageView(im, ColorFormat, ImageAspect.Color);
59         }
60 
61         this.depthImage = createImage(window.width, window.height);
62         this.depthImageView = createImageView(depthImage.image, DepthFormat, ImageAspect.Depth);
63 
64         Framebuffer[] framebuffers;
65         foreach (colorImageView; colorImageViews) {
66             framebuffers ~= createFramebuffer(window.width, window.height, colorImageView, depthImageView);
67         }
68         registerFrameBuffers(framebuffers);
69     }
70 
71     private VImage createImage(int width, int height) {
72         Image.CreateInfo imageInfo = {
73             imageType: ImageType.Type2D,
74             extent: {
75                 width: width,
76                 height: height,
77                 depth: 1
78             },
79             mipLevels: 1,
80             arrayLayers: 1,
81             format: DepthFormat,
82             tiling: ImageTiling.Optimal,
83             initialLayout: ImageLayout.DepthStencilAttachmentOptimal,
84             usage: ImageUsage.DepthStencilAttachment,
85             sharingMode: SharingMode.Exclusive,
86             samples: SampleCount.Count1
87         };
88         return new VImage(new Image(VDevice(), imageInfo), MemoryProperties.MemoryType.Flags.DeviceLocal);
89     }
90 
91     private ImageView createImageView(Image image, VkFormat format, ImageAspect aspectMask) {
92         ImageView.CreateInfo info = {
93            image: image,
94            viewType: ImageViewType.Type2D,
95            format: format,
96            subresourceRange: {
97                aspectMask: aspectMask,
98                baseMipLevel: 0,
99                levelCount: 1,
100                baseArrayLayer: 0,
101                layerCount: 1,
102            }
103         };
104         return new ImageView(VDevice(), info);
105     }
106 
107     private Framebuffer createFramebuffer(int width, int height, ImageView colorImage, ImageView depthImage) {
108         Framebuffer.CreateInfo info = {
109             renderPass: this,
110             attachments: [colorImage, depthImage],
111             width: width,
112             height: height,
113             layers: 1,
114         };
115         return new Framebuffer(VDevice(), info);
116     }
117 }