Skip to main content

buffer/
main.rs

1use std::sync::{Arc, Mutex};
2use ash::vk;
3use ash::vk::{BufferImageCopy, BufferUsageFlags, DeviceSize, Extent3D, ImageLayout, ImageSubresourceLayers};
4use gpu_allocator::MemoryLocation;
5use cen::app::Cen;
6use cen::app::app::AppConfig;
7use cen::app::component::{Component, ComponentRegistry};
8use cen::app::engine::InitContext;
9use cen::graphics::renderer::{RenderComponent, RenderContext};
10use cen::vulkan::{Buffer};
11
12struct ComputeRender {
13    buffer: Buffer,
14}
15
16impl ComputeRender {
17    fn new(ctx: &mut InitContext) -> Self {
18        // Image
19        let buffer = Buffer::new(
20            &ctx.device,
21            &mut ctx.allocator,
22            MemoryLocation::CpuToGpu,
23            2000 * 2000 * 4,
24            BufferUsageFlags::TRANSFER_SRC
25        );
26
27        {
28            let mut mem = buffer.mapped().unwrap();
29            for i in mem.as_mut_slice() {
30                *i = 255u8;
31            }
32        }
33
34        Self {
35            buffer
36        }
37    }
38}
39
40impl RenderComponent for ComputeRender {
41
42    fn render(&mut self, ctx: &mut RenderContext) {
43
44        if self.buffer.size() != (ctx.swapchain_image.width() * ctx.swapchain_image.height() * 4) as u64 {
45            // Recreate image
46            self.buffer = Buffer::new(
47                &ctx.device,
48                &mut ctx.allocator,
49                MemoryLocation::CpuToGpu,
50                (ctx.swapchain_image.width() * ctx.swapchain_image.height() * 4) as DeviceSize,
51                BufferUsageFlags::TRANSFER_SRC
52            );
53
54            {
55                let mut mem = self.buffer.mapped().unwrap();
56                for i in mem.as_mut_slice() {
57                    *i = 255u8;
58                }
59            }
60        }
61
62        // Transition the swapchain image
63        ctx.command_buffer.image_barrier(
64            ctx.swapchain_image,
65            vk::ImageLayout::PRESENT_SRC_KHR,
66            vk::ImageLayout::TRANSFER_DST_OPTIMAL,
67            vk::PipelineStageFlags::TOP_OF_PIPE,
68            vk::PipelineStageFlags::TRANSFER,
69            vk::AccessFlags::NONE,
70            vk::AccessFlags::TRANSFER_WRITE
71        );
72
73        // Copy to the swapchain
74        ctx.command_buffer.clear_color_image(
75            ctx.swapchain_image,
76            ImageLayout::TRANSFER_DST_OPTIMAL,
77            [1.0, 0.0, 0.0, 1.0]
78        );
79
80        ctx.command_buffer.copy_buffer_to_image(
81            &self.buffer,
82            ctx.swapchain_image,
83            ImageLayout::TRANSFER_DST_OPTIMAL,
84            &[
85                BufferImageCopy::default()
86                    .buffer_image_height(0)
87                    .buffer_row_length(0)
88                    .buffer_offset(0)
89                    .image_extent(
90                        Extent3D::default()
91                            .width(ctx.swapchain_image.width())
92                            .height(ctx.swapchain_image.height())
93                            .depth(1)
94                    )
95                    .image_subresource(
96                        ImageSubresourceLayers::default()
97                            .aspect_mask(vk::ImageAspectFlags::COLOR)
98                            .base_array_layer(0)
99                            .layer_count(1)
100                            .mip_level(0)
101                    )
102            ]
103        );
104
105        // Transfer back to default states
106        ctx.command_buffer.image_barrier(
107            ctx.swapchain_image,
108            vk::ImageLayout::TRANSFER_DST_OPTIMAL,
109            vk::ImageLayout::PRESENT_SRC_KHR,
110            vk::PipelineStageFlags::TRANSFER,
111            vk::PipelineStageFlags::BOTTOM_OF_PIPE,
112            vk::AccessFlags::TRANSFER_WRITE,
113            vk::AccessFlags::NONE
114        );
115
116    }
117}
118
119fn main() {
120
121    Cen::run(
122        AppConfig::default(),
123        Box::new(|ctx| {
124            let compute = Arc::new(Mutex::new(ComputeRender::new(ctx)));
125            ComponentRegistry::new()
126                .register(Component::Render(compute))
127        })
128    );
129}
130