more brainstorming on how spriting and computing is going to work

master
mitchellhansen 5 years ago
parent be20f3ae2a
commit c39994a7ae

@ -1,7 +1,7 @@
use crate::vertex_2d::{ColoredVertex2D, Vertex2D}; use crate::vertex_2d::{ColoredVertex2D, Vertex2D};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use std::collections::HashMap; use std::collections::HashMap;
use vulkano::buffer::{BufferAccess, BufferUsage, ImmutableBuffer}; use vulkano::buffer::{BufferAccess, BufferUsage, ImmutableBuffer, CpuAccessibleBuffer};
use std::sync::Arc; use std::sync::Arc;
use vulkano::format::{ClearValue, Format}; use vulkano::format::{ClearValue, Format};
use vulkano::framebuffer::{FramebufferAbstract, Framebuffer}; use vulkano::framebuffer::{FramebufferAbstract, Framebuffer};
@ -85,8 +85,6 @@ pub trait Drawable {
fn get_texture_id(&self) -> Option<String>; fn get_texture_id(&self) -> Option<String>;
} }
// Need three types of shaders. Solid, Textured, Compute // Need three types of shaders. Solid, Textured, Compute
#[derive(PartialEq, Eq, Hash, Clone)] #[derive(PartialEq, Eq, Hash, Clone)]
pub enum ShaderType { pub enum ShaderType {
@ -145,10 +143,10 @@ impl CanvasFrame {
pub struct Canvas { pub struct Canvas {
colored_drawables : Vec<ColoredVertex2D>, colored_drawables : Vec<ColoredVertex2D>,
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>, colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
textured_drawables: HashMap<String, Vec<Vertex2D>>, textured_drawables: HashMap<String, Vec<Vertex2D>>,
textured_vertex_buffer: HashMap<String, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>, textured_vertex_buffer: HashMap<String, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
shader_kernels: HashMap<ShaderType, ShaderKernels>, shader_kernels: HashMap<ShaderType, ShaderKernels>,
@ -163,6 +161,7 @@ pub struct Canvas {
impl Canvas { impl Canvas {
// needs to take in the texture list // needs to take in the texture list
pub fn new(queue: Arc<Queue>, pub fn new(queue: Arc<Queue>,
device: Arc<Device>, device: Arc<Device>,
@ -273,6 +272,14 @@ impl Canvas {
self.colored_vertex_buffer.clear(); self.colored_vertex_buffer.clear();
self.textured_vertex_buffer.clear(); self.textured_vertex_buffer.clear();
//TODO should probably use cpu accessible buffer instead of recreating immutes each frame
// CpuAccessibleBuffer::from_iter(
// device.clone(),
// BufferUsage::vertex_buffer(),
// self.colored_drawables.iter().cloned(),
// ).unwrap().0;
self.colored_vertex_buffer.push( self.colored_vertex_buffer.push(
ImmutableBuffer::from_iter( ImmutableBuffer::from_iter(
self.colored_drawables.iter().cloned(), self.colored_drawables.iter().cloned(),

@ -33,6 +33,98 @@ mod vertex_3d;
mod sprite; mod sprite;
mod canvas; mod canvas;
/*
Alright, what the hell do I do next...
Canvas works, but I want to use CPU accessible buffer instead of immutable buffer
I think it would be faster if we reuse fewer oversized buffers than vis versa
Texturing is broken
Compute is running in the background, but don't have a way to draw it.
Would like to draw it to a sprite???
8/13 :
Okay. So I've decided to keep compute image and compute kernel in their own 'canvas'
Canvas still needs to be cleaned up. I would like a contract type of thing going on
with the loaded textures. Where you need to request a texture_handle from vkprocessor
to attach to a Sprite. The problem is kinda what I do with the swap image. I only need
a reference to it and the general buffer coming back from the compute kernel. I could
continue to hold the image in the Canvas, and just give out an ID when a Sprite wants it.
The issue here is that kinda muddles the API a bit. I would need to do something like
Canvas.load_textures()
Compute.create_compute(data) -> compute_buffer_id
Canvas.load_image(compute_buffer_id, Compute)
Sprite::with_image(compute_buffer_id)
Canvas::swap_into(compute_buffer, swap_image);
I want to be able to chain computes using the same data
So that would be a different pipeline using the same or similar descriptor set
sprite = Sprite::with_texture(Canvas.get_texture_from_file())
(compute, sprite2) = Compute::with_swap_image(Canvas.get_new_image())
compute load shader -> shader object
compute load buffers -> buffer object
shader object + buffer object + maybe the swap buffer
-> command queue
let mut canvas = CanvasFrame::new();
canvas.draw(&sprite);
canvas.draw(&sprite2);
(frame_future) = processor.run(&surface, frame_future, canvas);
*/
fn main() { fn main() {
let instance = { let instance = {
@ -80,6 +172,8 @@ fn main() {
accumulator_time -= step_size; accumulator_time -= step_size;
} }
println!("{}", delta_time);
let mut exit = false; let mut exit = false;
events_loop.poll_events(|event| { events_loop.poll_events(|event| {
match event { match event {
@ -112,10 +206,18 @@ fn main() {
return; return;
} }
/*
*/
let mut canvas = CanvasFrame::new(); let mut canvas = CanvasFrame::new();
canvas.draw(&sprite); canvas.draw(&sprite);
canvas.draw(&sprite2); canvas.draw(&sprite2);
(frame_future) = processor.run(&surface, frame_future, canvas); (frame_future) = processor.run(&surface, frame_future, canvas);
} }
} }

@ -12,6 +12,7 @@ pub struct Sprite {
texture_id: Option<String>, texture_id: Option<String>,
} }
impl Sprite { impl Sprite {

@ -35,6 +35,7 @@ pub struct VkProcessor<'a> {
impl<'a> VkProcessor<'a> { impl<'a> VkProcessor<'a> {
pub fn new(instance: &'a Arc<Instance>, surface: &'a Arc<Surface<Window>>) -> VkProcessor<'a> { pub fn new(instance: &'a Arc<Instance>, surface: &'a Arc<Surface<Window>>) -> VkProcessor<'a> {
let physical = PhysicalDevice::enumerate(instance).next().unwrap(); let physical = PhysicalDevice::enumerate(instance).next().unwrap();
@ -72,12 +73,10 @@ impl<'a> VkProcessor<'a> {
} }
} }
pub fn compile_kernel(&mut self, filename: String) { pub fn compile_kernel(&mut self, filename: String) {
self.compute_kernel = Some(ComputeKernel::new(filename, self.device.clone())); self.compute_kernel = Some(ComputeKernel::new(filename, self.device.clone()));
} }
pub fn create_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) { pub fn create_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) {
let (mut swapchain, images) = { let (mut swapchain, images) = {
let capabilities = surface.capabilities(self.physical).unwrap(); let capabilities = surface.capabilities(self.physical).unwrap();
@ -154,8 +153,11 @@ impl<'a> VkProcessor<'a> {
surface: &'a Arc<Surface<Window>>, surface: &'a Arc<Surface<Window>>,
mut frame_future: Box<dyn GpuFuture>, mut frame_future: Box<dyn GpuFuture>,
canvas_frame: CanvasFrame, canvas_frame: CanvasFrame,
) -> Box<dyn GpuFuture> { ) -> Box<dyn GpuFuture> {
self.canvas.draw(canvas_frame);
self.canvas.allocate_vertex_buffers(self.device.clone());
let mut framebuffers = let mut framebuffers =
self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone()); self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone());
@ -196,9 +198,6 @@ impl<'a> VkProcessor<'a> {
.copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(), .copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(),
self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap(); self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap();
self.canvas.draw(canvas_frame);
self.canvas.allocate_vertex_buffers(self.device.clone());
let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num); let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num);
let command_buffer = command_buffer.build().unwrap(); let command_buffer = command_buffer.build().unwrap();

Loading…
Cancel
Save