cen 0.0.10

Vulkan window backend
Documentation
use std::sync::{Arc, Mutex};
use ash::vk;
use ash::vk::{BufferImageCopy, BufferUsageFlags, DeviceSize, Extent3D, ImageLayout, ImageSubresourceLayers};
use gpu_allocator::MemoryLocation;
use cen::app::Cen;
use cen::app::app::AppConfig;
use cen::app::component::{Component, ComponentRegistry};
use cen::app::engine::InitContext;
use cen::graphics::renderer::{RenderComponent, RenderContext};
use cen::vulkan::{Buffer};

struct ComputeRender {
    buffer: Buffer,
}

impl ComputeRender {
    fn new(ctx: &mut InitContext) -> Self {
        // Image
        let buffer = Buffer::new(
            &ctx.device,
            &mut ctx.allocator,
            MemoryLocation::CpuToGpu,
            2000 * 2000 * 4,
            BufferUsageFlags::TRANSFER_SRC
        );

        {
            let mut mem = buffer.mapped().unwrap();
            for i in mem.as_mut_slice() {
                *i = 255u8;
            }
        }

        Self {
            buffer
        }
    }
}

impl RenderComponent for ComputeRender {

    fn render(&mut self, ctx: &mut RenderContext) {

        if self.buffer.size() != (ctx.swapchain_image.width() * ctx.swapchain_image.height() * 4) as u64 {
            // Recreate image
            self.buffer = Buffer::new(
                &ctx.device,
                &mut ctx.allocator,
                MemoryLocation::CpuToGpu,
                (ctx.swapchain_image.width() * ctx.swapchain_image.height() * 4) as DeviceSize,
                BufferUsageFlags::TRANSFER_SRC
            );

            {
                let mut mem = self.buffer.mapped().unwrap();
                for i in mem.as_mut_slice() {
                    *i = 255u8;
                }
            }
        }

        // Transition the swapchain image
        ctx.command_buffer.image_barrier(
            ctx.swapchain_image,
            vk::ImageLayout::PRESENT_SRC_KHR,
            vk::ImageLayout::TRANSFER_DST_OPTIMAL,
            vk::PipelineStageFlags::TOP_OF_PIPE,
            vk::PipelineStageFlags::TRANSFER,
            vk::AccessFlags::NONE,
            vk::AccessFlags::TRANSFER_WRITE
        );

        // Copy to the swapchain
        ctx.command_buffer.clear_color_image(
            ctx.swapchain_image,
            ImageLayout::TRANSFER_DST_OPTIMAL,
            [1.0, 0.0, 0.0, 1.0]
        );

        ctx.command_buffer.copy_buffer_to_image(
            &self.buffer,
            ctx.swapchain_image,
            ImageLayout::TRANSFER_DST_OPTIMAL,
            &[
                BufferImageCopy::default()
                    .buffer_image_height(0)
                    .buffer_row_length(0)
                    .buffer_offset(0)
                    .image_extent(
                        Extent3D::default()
                            .width(ctx.swapchain_image.width())
                            .height(ctx.swapchain_image.height())
                            .depth(1)
                    )
                    .image_subresource(
                        ImageSubresourceLayers::default()
                            .aspect_mask(vk::ImageAspectFlags::COLOR)
                            .base_array_layer(0)
                            .layer_count(1)
                            .mip_level(0)
                    )
            ]
        );

        // Transfer back to default states
        ctx.command_buffer.image_barrier(
            ctx.swapchain_image,
            vk::ImageLayout::TRANSFER_DST_OPTIMAL,
            vk::ImageLayout::PRESENT_SRC_KHR,
            vk::PipelineStageFlags::TRANSFER,
            vk::PipelineStageFlags::BOTTOM_OF_PIPE,
            vk::AccessFlags::TRANSFER_WRITE,
            vk::AccessFlags::NONE
        );

    }
}

fn main() {

    Cen::run(
        AppConfig::default(),
        Box::new(|ctx| {
            let compute = Arc::new(Mutex::new(ComputeRender::new(ctx)));
            ComponentRegistry::new()
                .register(Component::Render(compute))
        })
    );
}