more refactoring, compiles.

master
mitchellhansen 5 years ago
parent 1737319fc5
commit 0357296771

@ -21,6 +21,7 @@ use winit::Window;
use vulkano::pipeline::viewport::Viewport; use vulkano::pipeline::viewport::Viewport;
use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer; use vulkano::descriptor::descriptor::DescriptorDescTy::TexelBuffer;
use crate::canvas_frame::CanvasFrame; use crate::canvas_frame::CanvasFrame;
use std::hash::Hash;
// Canvas is the accumulator of Sprites for drawing // Canvas is the accumulator of Sprites for drawing
@ -74,8 +75,8 @@ impl Vertex for ColoredVertex2D {
pub trait Drawable { pub trait Drawable {
fn get_vertices(&self) -> Vec<(f32, f32)>; fn get_vertices(&self) -> Vec<(f32, f32)>;
fn get_color(&self) -> (f32, f32, f32, f32); fn get_color(&self) -> (f32, f32, f32, f32);
fn get_texture_handle(&self) -> Option<Arc<u32>>; fn get_texture_handle(&self) -> Option<Arc<CanvasTextureHandle>>;
fn get_image_handle(&self) -> Option<Arc<u32>>; fn get_image_handle(&self) -> Option<Arc<CanvasImageHandle>>;
} }
// Need three types of shaders. Solid, Textured, Image // Need three types of shaders. Solid, Textured, Image
@ -87,24 +88,24 @@ pub enum ShaderType {
} }
#[derive(Clone)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct TextureHandle { pub struct CanvasTextureHandle {
handle: u32 pub handle: u32
} }
#[derive(Clone)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct ImageHandle { pub struct CanvasImageHandle {
handle: u32 pub handle: u32
} }
#[derive(Clone)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct ShaderHandle { pub struct CanvasShaderHandle {
handle: u32 pub handle: u32
} }
#[derive(Clone)] #[derive(Clone)]
pub struct CanvasTexture { pub struct CanvasTexture {
handle: Arc<TextureHandle>, handle: Arc<CanvasTextureHandle>,
buffer: Arc<ImmutableImage<Format>>, buffer: Arc<ImmutableImage<Format>>,
name: String, name: String,
size: (u32, u32), size: (u32, u32),
@ -126,7 +127,7 @@ impl CanvasTexture {
#[derive(Clone)] #[derive(Clone)]
pub struct CanvasImage { pub struct CanvasImage {
handle: Arc<ImageHandle>, handle: Arc<CanvasImageHandle>,
buffer: Arc<AttachmentImage>, buffer: Arc<AttachmentImage>,
size: (u32, u32), size: (u32, u32),
} }
@ -159,11 +160,11 @@ pub struct CanvasState {
colored_drawables: Vec<ColoredVertex2D>, colored_drawables: Vec<ColoredVertex2D>,
colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, colored_vertex_buffer: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
textured_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>, textured_drawables: HashMap<Arc<CanvasTextureHandle>, Vec<Vec<Vertex2D>>>,
textured_vertex_buffer: HashMap<Arc<u32>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, textured_vertex_buffer: HashMap<Arc<CanvasTextureHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
image_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>, image_drawables: HashMap<Arc<CanvasImageHandle>, Vec<Vec<Vertex2D>>>,
image_vertex_buffer: HashMap<Arc<u32>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, image_vertex_buffer: HashMap<Arc<CanvasImageHandle>, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>,
// Looks like we gotta hold onto the queue for managing textures // Looks like we gotta hold onto the queue for managing textures
queue: Arc<Queue>, queue: Arc<Queue>,
@ -186,7 +187,7 @@ impl CanvasState {
images.iter().map(|image| { images.iter().map(|image| {
Arc::new( Arc::new(
Framebuffer::start(self.shader_kernels.get(String::from("color-passthrough")).unwrap().render_pass.clone()) Framebuffer::start(self.shader_buffers.get("color-passthrough").unwrap().render_pass.clone())
.add(image.clone()).unwrap() .add(image.clone()).unwrap()
.build().unwrap() .build().unwrap()
) as Arc<dyn FramebufferAbstract + Send + Sync> ) as Arc<dyn FramebufferAbstract + Send + Sync>
@ -198,15 +199,10 @@ impl CanvasState {
device: Arc<Device>, device: Arc<Device>,
physical: PhysicalDevice, physical: PhysicalDevice,
capabilities: Capabilities) -> CanvasState { capabilities: Capabilities) -> CanvasState {
let solid_color_kernel = String::from("color-passthrough"); let solid_color_kernel = String::from("color-passthrough");
let texture_kernel = String::from("simple_texture"); let texture_kernel = String::from("simple_texture");
let shader_kernels: HashMap<ShaderType, ShaderKernels> = HashMap::from_iter(vec![
(ShaderType::SOLID, ShaderKernels::new(solid_color_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())),
(ShaderType::TEXTURED, ShaderKernels::new(texture_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone()))
]);
CanvasState { CanvasState {
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
sampler: Sampler::new(device.clone(), Filter::Linear, Filter::Linear, sampler: Sampler::new(device.clone(), Filter::Linear, Filter::Linear,
@ -214,11 +210,24 @@ impl CanvasState {
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(), SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(),
image_buffers: vec![], image_buffers: vec![],
texture_buffers: vec![], texture_buffers: vec![],
shader_buffers: Default::default(), shader_buffers: HashMap::from_iter(vec![
(solid_color_kernel.clone(), ShaderKernels::new(solid_color_kernel.clone(),
capabilities.clone(),
queue.clone(),
physical.clone(),
device.clone())
),
(texture_kernel.clone(), ShaderKernels::new(texture_kernel.clone(),
capabilities.clone(),
queue.clone(),
physical.clone(),
device.clone())
),
]),
colored_drawables: vec![], colored_drawables: vec![],
colored_vertex_buffer: vec![], colored_vertex_buffer: vec![],
textured_drawables: Default::default(), textured_drawables: HashMap::default(),
textured_vertex_buffer: Default::default(), textured_vertex_buffer: Default::default(),
image_drawables: Default::default(), image_drawables: Default::default(),
image_vertex_buffer: Default::default(), image_vertex_buffer: Default::default(),
@ -228,9 +237,9 @@ impl CanvasState {
} }
} }
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<ImageHandle> { pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
let image = CanvasImage { let image = CanvasImage {
handle: Arc::new(ImageHandle { handle: self.image_buffers.len() as u32 + 1 }), handle: Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 + 1 }),
buffer: AttachmentImage::with_usage( buffer: AttachmentImage::with_usage(
self.device.clone(), self.device.clone(),
[dimensions.0, dimensions.1], [dimensions.0, dimensions.1],
@ -243,8 +252,8 @@ impl CanvasState {
handle handle
} }
pub fn get_image(&self, image_handle: Arc<ImageHandle>) -> Arc<AttachmentImage> { pub fn get_image(&self, image_handle: Arc<CanvasImageHandle>) -> Arc<AttachmentImage> {
self.image_buffers.get((*image_handle).clone() as usize).unwrap() self.image_buffers.get((*image_handle).clone().handle as usize).unwrap()
.clone().buffer.clone() .clone().buffer.clone()
} }
@ -290,10 +299,10 @@ impl CanvasState {
texture texture
} }
pub fn load_texture(&mut self, filename: String) -> Option<Arc<TextureHandle>> { pub fn load_texture(&mut self, filename: String) -> Option<Arc<CanvasTextureHandle>> {
let texture_buffer = self.get_texture_from_file(filename.clone()); let texture_buffer = self.get_texture_from_file(filename.clone());
let handle = Arc::new(TextureHandle { let handle = Arc::new(CanvasTextureHandle {
handle: self.texture_buffers.len() as u32 + 1 handle: self.texture_buffers.len() as u32 + 1
}); });
@ -309,6 +318,18 @@ impl CanvasState {
Some(handle) Some(handle)
} }
fn get_texture(&self, texture_handle: Arc<CanvasTextureHandle>)
-> Arc<ImmutableImage<Format>> {
let handle = texture_handle.handle as usize;
if let Some(i) = self.texture_buffers.get(handle) {
return i.clone().buffer.clone();
} else {
panic!("{} : Texture not loaded", handle);
}
}
// After done using this, need to call allocated vertex buffers // After done using this, need to call allocated vertex buffers
pub fn draw(&mut self, canvas_frame: CanvasFrame) { pub fn draw(&mut self, canvas_frame: CanvasFrame) {
self.textured_drawables = canvas_frame.textured_drawables; self.textured_drawables = canvas_frame.textured_drawables;
@ -353,15 +374,6 @@ impl CanvasState {
} }
} }
fn get_texture(&self, texture_id: String) -> Arc<ImmutableImage<Format>> {
if let Some(i) = self.texture_store.get(&texture_id) {
return i.clone();
} else {
panic!("{} : Texture not loaded", texture_id);
}
}
fn get_solid_color_descriptor_set(&self, kernel: Arc<ShaderKernels>) -> Box<dyn DescriptorSet + Send + Sync> { fn get_solid_color_descriptor_set(&self, kernel: Arc<ShaderKernels>) -> Box<dyn DescriptorSet + Send + Sync> {
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new( let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
@ -383,27 +395,31 @@ impl CanvasState {
framebuffers[image_num].clone(), false, clear_values.clone(), framebuffers[image_num].clone(), false, clear_values.clone(),
).unwrap(); ).unwrap();
// Solid colors
let mut shader = self.shader_buffers.get("color-passthrough").unwrap().clone();
command_buffer = command_buffer.draw(
shader.get_pipeline().clone(),
&self.dynamic_state.clone(),
self.colored_vertex_buffer.clone(),
(), (),
).unwrap();
for (shader_type, kernel) in self.shader_kernels.clone().iter() { /*for (shader_type, kernel) in self.shader_kernels.clone().iter() {
match shader_type { match shader_type {
ShaderType::SOLID => { ShaderType::SOLID => {
}
ShaderType::TEXTURED => {
command_buffer = command_buffer.draw( command_buffer = command_buffer.draw(
kernel.clone().get_pipeline().clone(), kernel.clone().get_pipeline().clone(),
&self.dynamic_state.clone(), &dynamic_state.clone(), self.textured_vertex_buffer.clone(),
self.colored_vertex_buffer.clone(), vec![self.get_textured_descriptor_set(String::from("funky-bird.jpg"))], ()
(), (),
).unwrap(); ).unwrap();
} }
ShaderType::TEXTURED => {
// command_buffer = command_buffer.draw(
// kernel.clone().get_pipeline().clone(),
// &dynamic_state.clone(), self.textured_vertex_buffer.clone(),
// vec![self.get_textured_descriptor_set(String::from("funky-bird.jpg"))], ()
// ).unwrap();
}
ShaderType::IMAGE => {} ShaderType::IMAGE => {}
} }
} }*/
command_buffer command_buffer
.end_render_pass() .end_render_pass()

@ -1,12 +1,12 @@
use crate::vertex_2d::{ColoredVertex2D, Vertex2D}; use crate::vertex_2d::{ColoredVertex2D, Vertex2D};
use std::sync::Arc; use std::sync::Arc;
use std::collections::HashMap; use std::collections::HashMap;
use crate::canvas::Drawable; use crate::canvas::{Drawable, CanvasTextureHandle, CanvasImage, CanvasImageHandle};
pub struct CanvasFrame { pub struct CanvasFrame {
pub colored_drawables: Vec<ColoredVertex2D>, pub colored_drawables: Vec<ColoredVertex2D>,
pub textured_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>, pub textured_drawables: HashMap<Arc<CanvasTextureHandle>, Vec<Vec<Vertex2D>>>,
pub image_drawables: HashMap<Arc<u32>, Vec<Vec<Vertex2D>>>, pub image_drawables: HashMap<Arc<CanvasImageHandle>, Vec<Vec<Vertex2D>>>,
} }
impl CanvasFrame { impl CanvasFrame {

@ -0,0 +1,204 @@
use vulkano::device::{Device, Queue};
use vulkano::instance::{PhysicalDevice, QueueFamily};
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract, GraphicsPipelineBuilder};
use std::sync::Arc;
use std::ffi::CStr;
use std::path::PathBuf;
use shade_runner as sr;
use vulkano::framebuffer::{Subpass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, SpecializationConstants, SpecializationMapEntry};
use vulkano::swapchain::{Capabilities};
use crate::vertex_2d::ColoredVertex2D;
/*
CanvasShader holds the pipeline and render pass for the inputted shader source
*/
#[derive(Clone)]
pub struct CanvasShader {
pub render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
graphics_pipeline: Option<Arc<dyn GraphicsPipelineAbstract + Sync + Send>>,
device: Arc<Device>,
}
impl CanvasShader {
fn get_path(filename: String) -> (PathBuf, PathBuf) {
let project_root =
std::env::current_dir()
.expect("failed to get root directory");
let mut shader_path = project_root.clone();
shader_path.push(PathBuf::from("resources/shaders/"));
let mut vertex_shader_path = project_root.clone();
vertex_shader_path.push(PathBuf::from("resources/shaders/"));
vertex_shader_path.push(PathBuf::from(filename.clone() + ".vertex"));
let mut fragment_shader_path = project_root.clone();
fragment_shader_path.push(PathBuf::from("resources/shaders/"));
fragment_shader_path.push(PathBuf::from(filename.clone() + ".fragment"));
(vertex_shader_path, fragment_shader_path)
}
pub fn get_pipeline(&mut self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send> {
self.graphics_pipeline.clone().unwrap()
}
pub fn new(filename: String,
capabilities: Capabilities,
queue: Arc<Queue>,
physical: PhysicalDevice,
device: Arc<Device>) -> CanvasShader {
let format = capabilities.supported_formats[0].0;
let filenames = CanvasShader::get_path(filename.clone());
// TODO: better compile message, run til successful compile
let shader = sr::load(filenames.0, filenames.1)
.expect("Shader didn't compile");
let vulkano_entry =
sr::parse(&shader)
.expect("failed to parse");
let fragment_shader_module: Arc<ShaderModule> = unsafe {
let filenames1 = CanvasShader::get_path(filename.clone());
let shader1 = sr::load(filenames1.0, filenames1.1)
.expect("Shader didn't compile");
vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader1.fragment.clone())
}.unwrap();
let vertex_shader_module: Arc<ShaderModule> = unsafe {
let filenames1 = CanvasShader::get_path(filename.clone());
let shader1 = sr::load(filenames1.0, filenames1.1)
.expect("Shader didn't compile");
vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader1.vertex.clone())
}.unwrap();
let filenames = CanvasShader::get_path(filename.clone());
let frag_entry_point = unsafe {
Some(fragment_shader_module.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
vulkano_entry.frag_input,
vulkano_entry.frag_output,
vulkano_entry.frag_layout,
GraphicsShaderType::Fragment))
};
let vertex_entry_point = unsafe {
Some(vertex_shader_module.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
vulkano_entry.vert_input,
vulkano_entry.vert_output,
vulkano_entry.vert_layout,
GraphicsShaderType::Vertex))
};
let render_pass = Arc::new(vulkano::single_pass_renderpass!(
device.clone(),
// Attachments are outgoing like f_color
attachments: {
// `color` is a custom name we give to the first and only attachment.
color: {
// `load: Clear` means that we ask the GPU to clear the content of this
// attachment at the start of the drawing.
load: Clear,
// `store: Store` means that we ask the GPU to store the output of the draw
// in the actual image. We could also ask it to discard the result.
store: Store,
// `format: <ty>` indicates the type of the format of the image. This has to
// be one of the types of the `vulkano::format` module (or alternatively one
// of your structs that implements the `FormatDesc` trait). Here we use the
// same format as the swapchain.
format: format,
// TODO:
samples: 1,
}
},
pass: {
// We use the attachment named `color` as the one and only color attachment.
color: [color],
//color: [],
// No depth-stencil attachment is indicated with empty brackets.
depth_stencil: {}
}
).unwrap());
CanvasShader {
graphics_pipeline: Some(Arc::new(GraphicsPipeline::start()
.vertex_input_single_buffer::<ColoredVertex2D>()
.vertex_shader(vertex_entry_point.clone().unwrap(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
})
.triangle_list()
// Use a resizable viewport set to draw over the entire window
.viewports_dynamic_scissors_irrelevant(1)
.fragment_shader(frag_entry_point.clone().unwrap(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
})
// We have to indicate which subpass of which render pass this pipeline is going to be used
// in. The pipeline will only be usable from this particular subpass.
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
.build(device.clone())
.unwrap())),
device: device,
render_pass: render_pass,
}
}
}
#[repr(C)]
#[derive(Default, Debug, Clone)]
// TODO: This needs to be duplicated and moved into their respective containers shaderkenrels copute
struct ShaderSpecializationConstants {
first_constant: i32,
second_constant: u32,
third_constant: f32,
}
unsafe impl SpecializationConstants for ShaderSpecializationConstants {
fn descriptors() -> &'static [SpecializationMapEntry] {
static DESCRIPTORS: [SpecializationMapEntry; 3] = [
SpecializationMapEntry {
constant_id: 0,
offset: 0,
size: 4,
},
SpecializationMapEntry {
constant_id: 1,
offset: 4,
size: 4,
},
SpecializationMapEntry {
constant_id: 2,
offset: 8,
size: 4,
},
];
&DESCRIPTORS
}
}

@ -3,8 +3,15 @@ use vulkano::device::Device;
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage}; use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
use vulkano::pipeline::ComputePipeline; use vulkano::pipeline::ComputePipeline;
use vulkano::descriptor::pipeline_layout::PipelineLayout; use vulkano::descriptor::pipeline_layout::PipelineLayout;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, PersistentDescriptorSetBuf};
use image::ImageBuffer; use image::ImageBuffer;
use image::Rgba;
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuBufferHandle {
pub handle: u32,
}
#[derive(Clone)] #[derive(Clone)]
pub struct CompuBuffers { pub struct CompuBuffers {
@ -63,9 +70,10 @@ impl CompuBuffers {
pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>) pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>)
-> Arc<PersistentDescriptorSet<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>, ((((), -> Arc<PersistentDescriptorSet<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>, ((((),
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>), PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>), PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u32]>>>)>> { PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u32]>>>)>> {
Arc::new(PersistentDescriptorSet::start(compute_pipeline.clone(), 0) Arc::new(PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
.add_buffer(self.io_buffers.get(0).unwrap().clone()).unwrap() .add_buffer(self.io_buffers.get(0).unwrap().clone()).unwrap()
.add_buffer(self.io_buffers.get(1).unwrap().clone()).unwrap() .add_buffer(self.io_buffers.get(1).unwrap().clone()).unwrap()
@ -87,13 +95,12 @@ impl CompuBuffers {
image::Rgba([r, g, b, a]) image::Rgba([r, g, b, a])
}) })
} }
}
#[derive(Clone)] pub fn get_input_buffer(&self) -> Arc<CpuAccessibleBuffer<[u8]>> {
pub struct CompuBufferHandle { self.io_buffers.get(0).unwrap().clone()
handle: u32, }
pub fn get_output_buffer(&self) -> Arc<CpuAccessibleBuffer<[u8]>> {
self.io_buffers.get(1).unwrap().clone()
}
} }
#[derive(Clone)]
pub struct CompuKernelHandle {
handle: u32,
}

@ -1,22 +1,23 @@
use crate::canvas::ImageHandle; use crate::canvas::{CanvasImageHandle, Drawable};
use std::sync::Arc; use std::sync::Arc;
use crate::compu_sprite::CompuSprite; use crate::compu_sprite::CompuSprite;
use crate::compu_buffer::{CompuBufferHandle, CompuKernelHandle}; use crate::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
pub struct CompuFrame { pub struct CompuFrame {
// Vec<(Buffer, Kernel)> // Vec<(Buffer, Kernel)>
pure_compute: Vec<( pub pure_compute: Vec<(
Arc<CompuBufferHandle>, Arc<CompuBufferHandle>,
Arc<CompuKernelHandle>)>, Arc<CompuKernelHandle>)>,
// Vec<(Buffer, Image, Kernel)> // Vec<(Buffer, Image, Kernel)>
swapped_to_image: Vec<( pub swapped_to_image: Vec<(
Arc<CompuBufferHandle>, Arc<CompuBufferHandle>,
Arc<ImageHandle>, Arc<CanvasImageHandle>,
Arc<CompuKernelHandle>)>, Arc<CompuKernelHandle>)>,
// Vec<(Input Buffer, Output Buffer, Kernel)> // Vec<(Input Buffer, Output Buffer, Kernel)>
swapped_to_buffer: Vec<( pub swapped_to_buffer: Vec<(
Arc<CompuBufferHandle>, Arc<CompuBufferHandle>,
Arc<CompuBufferHandle>, Arc<CompuBufferHandle>,
Arc<CompuKernelHandle>)>, Arc<CompuKernelHandle>)>,
@ -51,6 +52,6 @@ impl CompuFrame {
buffer: Arc<CompuBufferHandle>, buffer: Arc<CompuBufferHandle>,
kernel: Arc<CompuKernelHandle>, kernel: Arc<CompuKernelHandle>,
sprite: &CompuSprite) { sprite: &CompuSprite) {
self.swapped_to_image.push((buffer, sprite.get_image_handle().clone(), kernel)) self.swapped_to_image.push((buffer, sprite.get_image_handle().unwrap().clone(), kernel))
} }
} }

@ -8,8 +8,12 @@ use vulkano::descriptor::pipeline_layout::PipelineLayout;
use shade_runner::{CompileError, FragLayout, FragInput, FragOutput, VertInput, VertOutput, VertLayout, CompiledShaders, Entry}; use shade_runner::{CompileError, FragLayout, FragInput, FragOutput, VertInput, VertOutput, VertLayout, CompiledShaders, Entry};
use shaderc::CompileOptions; use shaderc::CompileOptions;
use vulkano::pipeline::shader::{ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry}; use vulkano::pipeline::shader::{ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry};
use crate::compu_buffer::CompuKernelHandle; use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CompuKernelHandle {
pub handle: u32,
}
#[derive(Clone)] #[derive(Clone)]
pub struct CompuKernel { pub struct CompuKernel {

@ -1,4 +1,4 @@
use crate::canvas::{ImageHandle, Drawable, TextureHandle}; use crate::canvas::{CanvasImageHandle, Drawable, CanvasTextureHandle};
use std::sync::Arc; use std::sync::Arc;
pub struct CompuSprite { pub struct CompuSprite {
@ -6,31 +6,13 @@ pub struct CompuSprite {
position: (f32, f32), position: (f32, f32),
size: (f32, f32), size: (f32, f32),
color: (f32, f32, f32, f32), color: (f32, f32, f32, f32),
image_handle: Arc<ImageHandle>, image_handle: Arc<CanvasImageHandle>,
}
impl Drawable for CompuSprite {
fn get_vertices(&self) -> Vec<(f32, f32)> {
self.vertices.to_vec()
}
fn get_color(&self) -> (f32, f32, f32, f32) {
self.color
}
fn get_texture_handle(&self) -> Option<Arc<TextureHandle>> {
None
}
fn get_image_handle(&self) -> Option<Arc<ImageHandle>> {
Some(self.image_handle.clone())
}
} }
impl CompuSprite { impl CompuSprite {
pub fn new(position: (f32, f32), pub fn new(position: (f32, f32),
size: (f32, f32), size: (f32, f32),
image_handle: Arc<ImageHandle>) -> CompuSprite { image_handle: Arc<CanvasImageHandle>) -> CompuSprite {
let fsize = (size.0 as f32, size.1 as f32); let fsize = (size.0 as f32, size.1 as f32);
CompuSprite { CompuSprite {
@ -49,16 +31,22 @@ impl CompuSprite {
image_handle: image_handle.clone(), image_handle: image_handle.clone(),
} }
} }
}
impl Drawable for CompuSprite {
fn get_vertices(&self) -> Vec<(f32, f32)> { fn get_vertices(&self) -> Vec<(f32, f32)> {
self.vertices.to_vec() self.vertices.to_vec()
} }
fn get_color(&self) -> (f32, f32, f32, f32) { fn get_color(&self) -> (f32, f32, f32, f32) {
self.color.clone() self.color
} }
fn get_image_handle(&self) -> Arc<ImageHandle> { fn get_texture_handle(&self) -> Option<Arc<CanvasTextureHandle>> {
self.image_handle.clone() None
}
fn get_image_handle(&self) -> Option<Arc<CanvasImageHandle>> {
Some(self.image_handle.clone())
} }
} }

@ -1,7 +1,7 @@
use std::ffi::CStr; use std::ffi::CStr;
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage}; use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
use std::sync::Arc; use std::sync::Arc;
use crate::canvas::{Drawable, CanvasState, ImageHandle, CanvasImage, TextureHandle}; use crate::canvas::{Drawable, CanvasState, CanvasImageHandle, CanvasImage, CanvasTextureHandle};
use vulkano::framebuffer::RenderPassAbstract; use vulkano::framebuffer::RenderPassAbstract;
use vulkano::pipeline::{GraphicsPipelineAbstract, ComputePipeline}; use vulkano::pipeline::{GraphicsPipelineAbstract, ComputePipeline};
use vulkano::device::Device; use vulkano::device::Device;
@ -18,8 +18,8 @@ use std::path::PathBuf;
use shade_runner::{CompiledShaders, Entry, CompileError}; use shade_runner::{CompiledShaders, Entry, CompileError};
use vulkano::pipeline::shader::ShaderModule; use vulkano::pipeline::shader::ShaderModule;
use shaderc::CompileOptions; use shaderc::CompileOptions;
use crate::compu_kernel::CompuKernel; use crate::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle, CompuKernelHandle}; use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
use crate::compu_frame::CompuFrame; use crate::compu_frame::CompuFrame;
@ -63,7 +63,7 @@ impl CompuState {
pub fn new_kernel(&mut self, pub fn new_kernel(&mut self,
filename: String, filename: String,
device: &Arc<Device>) -> Arc<CompuKernelHandle> { device: Arc<Device>) -> Arc<CompuKernelHandle> {
let handle = Arc::new(CompuKernelHandle { let handle = Arc::new(CompuKernelHandle {
handle: self.kernels.len() as u32 + 1 handle: self.kernels.len() as u32 + 1
@ -82,8 +82,8 @@ impl CompuState {
// i = (Buffer, Kernel) // i = (Buffer, Kernel)
for i in compute_frame.pure_compute { for i in compute_frame.pure_compute {
let buffer_id = (*i.0).clone() as usize; let buffer_id = (*i.0).clone().handle as usize;
let kernel_id = (*i.1).clone() as usize; let kernel_id = (*i.1).clone().handle as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap(); let buffer = self.compute_buffers.get(buffer_id).unwrap();
let kernel = self.kernels.get(buffer_id).unwrap(); let kernel = self.kernels.get(buffer_id).unwrap();
@ -97,9 +97,9 @@ impl CompuState {
// i = (Buffer, Image, Kernel) // i = (Buffer, Image, Kernel)
for i in compute_frame.swapped_to_image { for i in compute_frame.swapped_to_image {
let buffer_id = (*i.0).clone() as usize; let buffer_id = (*i.0).clone().handle as usize;
let image_id = i.1.clone(); let image_id = i.1.clone();
let kernel_id = (*i.2).clone() as usize; let kernel_id = (*i.2).clone().handle as usize;
let buffer = self.compute_buffers.get(buffer_id).unwrap(); let buffer = self.compute_buffers.get(buffer_id).unwrap();
let image = canvas.get_image(image_id); let image = canvas.get_image(image_id);
@ -110,16 +110,16 @@ impl CompuState {
command_buffer = command_buffer command_buffer = command_buffer
.dispatch([100,100,1], p, d, ()).unwrap() .dispatch([100,100,1], p, d, ()).unwrap()
.copy_buffer_to_image(buffer.io_buffers.get(0).unwrap().clone(), image).unwrap(); .copy_buffer_to_image(buffer.get_input_buffer(), image).unwrap();
} }
// i = (Input Buffer, Output Buffer, Kernel) // i = (Input Buffer, Output Buffer, Kernel)
// Input buffer -> Kernel -> Output buffer // Input buffer -> Kernel -> Output buffer
for i in compute_frame.swapped_to_buffer { for i in compute_frame.swapped_to_buffer {
let input_buffer_id = (*i.0).clone() as usize; let input_buffer_id = (*i.0).clone().handle as usize;
let output_buffer_id = (*i.1).clone() as usize; let output_buffer_id = (*i.1).clone().handle as usize;
let kernel_id = (*i.2).clone() as usize; let kernel_id = (*i.2).clone().handle as usize;
let input_buffer = self.compute_buffers.get(input_buffer_id).unwrap(); let input_buffer = self.compute_buffers.get(input_buffer_id).unwrap();
let output_buffer = self.compute_buffers.get(output_buffer_id).unwrap(); let output_buffer = self.compute_buffers.get(output_buffer_id).unwrap();
@ -131,8 +131,8 @@ impl CompuState {
command_buffer = command_buffer command_buffer = command_buffer
.dispatch([100,100,1], pipeline, descriptor_set, ()).unwrap() .dispatch([100,100,1], pipeline, descriptor_set, ()).unwrap()
.copy_buffer( .copy_buffer(
input_buffer.io_buffers.get(1).unwrap().clone(), input_buffer.get_output_buffer(),
output_buffer.io_buffers.get(0).unwrap().clone()).unwrap(); output_buffer.get_input_buffer()).unwrap();
} }
command_buffer command_buffer

@ -19,13 +19,13 @@ use winit::{EventsLoop, WindowBuilder, WindowEvent, Event, DeviceEvent, VirtualK
use winit::dpi::LogicalSize; use winit::dpi::LogicalSize;
use vulkano_win::VkSurfaceBuild; use vulkano_win::VkSurfaceBuild;
use sprite::Sprite; use sprite::Sprite;
use crate::canvas::{CanvasFrame, CanvasImage};
use crate::compu_state::CompuState; use crate::compu_state::CompuState;
use crate::compu_frame::CompuFrame; use crate::compu_frame::CompuFrame;
use crate::compu_sprite::CompuSprite; use crate::compu_sprite::CompuSprite;
use crate::compu_kernel::CompuKernel; use crate::compu_kernel::CompuKernel;
use crate::compu_buffer::CompuBuffers; use crate::compu_buffer::CompuBuffers;
use crate::util::load_raw; use crate::util::load_raw;
use crate::canvas_frame::CanvasFrame;
mod util; mod util;
mod slider; mod slider;
@ -36,8 +36,11 @@ mod button;
mod vertex_2d; mod vertex_2d;
mod vertex_3d; mod vertex_3d;
mod sprite; mod sprite;
mod canvas; mod canvas;
mod canvas_frame; mod canvas_frame;
mod canvas_shader;
mod compu_state; mod compu_state;
mod compu_frame; mod compu_frame;
mod compu_sprite; mod compu_sprite;
@ -50,137 +53,6 @@ Alright, what the hell do I do next...
Canvas works, but I want to use CPU accessible buffer instead of immutable buffer 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 I think it would be faster if we reuse fewer oversized buffers than vis versa
Texturing is broken
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
8/27 :
But I dont always want to draw a computable...
Which I guess is fine. I could have another datatype implement computable
CompuSprite
-> Drawable, Computable
TxturSprite
-> Drawable
ColorSprite
-> Drawable
Computable
-> get pipeline id (need to assoc. compiled kernel)
->
Drawable
-> get texture id
-> get image id
-> get color
-> get vertices
Computable
get data
set data?
set settings?
get swap image id
Drawable:
get vertices
get color
get texture id
get descriptor set
need some sort of computable interface for the Sprite. It already has drawable
so why not computable
Pipeline is the compiled kernel/shader
in the shaders case, it has the vertex definition, constants, and the compiled code
in kernel, its just constants and compiled code
Descriptor set holds the buffers which we will pass to the pipeline
rw and settings buffers for the compu
texture buffer for the textured
image buffer for the image (swap)
Need to have certain stages in the building of the command buffer.
(Z level????)
1.) computes
2.) compute swaps
3.) render images
4.) render textures
5.) render solids
So to start with we need to know the compute data which we want to run and the kernel we want to run it on. We combine the buffers along with the pipeline generated from the compiled kernel and get
the descriptor set. We also need the XY for the compute run
CompuSprite
holds the image handle
impl's drawable
CompuBuffers
holds the buffer handles
creates the descriptor set?
CompuState
holds the compute buffers
holds the compute kernels
ComputeFrame
preserves order of entered elements
holds compute buffer ids and their tied kernel ids
holds compute buffer ids, their swap image ids and their kernel ids
holds compute buffer ids, their swap buffer ids, and their kernel ids
// Creates the compu sprite with an associated image stored in canvas
let compu_sprite = CompuSprite::new(&mut canvas)
// Compiles and stores the kernel in CompuState
// Returns the handle to the stored kernel (immutable at this state probably)
let KernelID = ComputeState.new_kernel(kernel_path)
// Pushes the data to the GPU and returns a handle
let ComputeBuffer_1 = ComputeState.new_compute_buffer(input_data, input_settings)
// One by one, assign the buffers to their kernels for run
ComputeFrame.add(ComputeBuffer_1, KernelID)
// If the buffer needs to be swapped in first
ComputeFrame.add_with_buffer_swap(ComputeBuffer_1, ComputeBuffer_2, KernelID)
// If the buffer should be swappd out to an image after it computes
ComputeFrame.add_with_image_swap(ComputeBuffer_1, compu_sprite, KernelID)
CompuState.compute()
// Full example if API:
CompuFrame.add(ComputeBuffer1ID, Kernel1ID)
CompuFrame.add(ComputeBuffer2ID, Kernel2ID)
CompuFrame.add_with_image_swap(ComputeBuffer1ID, CompuSprite, KernelID)
CanvasFrame.draw(Sprite1)
CanvasFrame.draw(Sprite2)
CanvasFrame.draw(CompuSprite)
vkprocessor.run(CanvasFrame, CompuFrame)
*/ */
fn main() { fn main() {
@ -197,9 +69,6 @@ fn main() {
let mut window = surface.window(); let mut window = surface.window();
let mut processor = vkprocessor::VkProcessor::new(&instance, &surface); let mut processor = vkprocessor::VkProcessor::new(&instance, &surface);
// processor.compile_kernel(String::from("simple-edge.compute"));
// processor.load_compute_image(String::from("background.jpg"));
// processor.load_textures(String::from("funky-bird.jpg"));
processor.create_swapchain(&surface); processor.create_swapchain(&surface);
let mut timer = Timer::new(); let mut timer = Timer::new();
@ -232,11 +101,6 @@ fn main() {
while let Some(p) = window.get_position() { while let Some(p) = window.get_position() {
elapsed_time = timer.elap_time(); elapsed_time = timer.elap_time();

@ -1,4 +1,4 @@
use crate::canvas::Drawable; use crate::canvas::{Drawable, CanvasTextureHandle, CanvasImageHandle};
use std::sync::Arc; use std::sync::Arc;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -10,7 +10,7 @@ pub struct Sprite {
color: (f32, f32, f32, f32), color: (f32, f32, f32, f32),
textured: bool, textured: bool,
texture_id: Option<Arc<u32>>, texture_handle: Option<Arc<CanvasTextureHandle>>,
} }
@ -20,7 +20,9 @@ impl Sprite {
Sprite::new_with_color(position, size, (0.,0.,0.,0.)) Sprite::new_with_color(position, size, (0.,0.,0.,0.))
} }
pub fn new_with_color(position: (f32, f32), size: (f32, f32), color: (f32, f32, f32, f32)) -> Sprite { pub fn new_with_color(position: (f32, f32),
size: (f32, f32),
color: (f32, f32, f32, f32)) -> Sprite {
let fsize = (size.0 as f32, size.1 as f32); let fsize = (size.0 as f32, size.1 as f32);
@ -38,11 +40,11 @@ impl Sprite {
size: size, size: size,
color: color, color: color,
textured: false, textured: false,
texture_id: None texture_handle: None
} }
} }
pub fn new_with_texture(position: (f32, f32), size: (f32, f32), texture_id: Arc<u32>) -> Sprite { pub fn new_with_texture(position: (f32, f32), size: (f32, f32), texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
let fsize = (size.0 as f32, size.1 as f32); let fsize = (size.0 as f32, size.1 as f32);
@ -59,7 +61,7 @@ impl Sprite {
size: size, size: size,
color: (0.0, 0.0, 0.0, 0.0), color: (0.0, 0.0, 0.0, 0.0),
textured: false, textured: false,
texture_id: Some(texture_id) texture_handle: Some(texture_handle.clone())
} }
} }
@ -76,16 +78,16 @@ impl Drawable for Sprite {
self.color.clone() self.color.clone()
} }
fn get_texture_handle(&self) -> Option<Arc<u32>> { fn get_texture_handle(&self) -> Option<Arc<CanvasTextureHandle>> {
match self.textured { match self.textured {
true => { true => {
self.texture_id.clone() self.texture_handle.clone()
}, },
false => None, false => None,
} }
} }
fn get_image_handle(&self) -> Option<Arc<u32>> { fn get_image_handle(&self) -> Option<Arc<CanvasImageHandle>> {
None None
} }
} }

@ -47,7 +47,7 @@ impl ShaderKernels {
(vertex_shader_path, fragment_shader_path) (vertex_shader_path, fragment_shader_path)
} }
pub fn get_pipeline(&mut self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send> { pub fn get_pipeline(&self) -> Arc<dyn GraphicsPipelineAbstract + Sync + Send> {
self.graphics_pipeline.clone().unwrap() self.graphics_pipeline.clone().unwrap()
} }

@ -7,11 +7,13 @@ use std::sync::Arc;
use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities}; use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities};
use vulkano::image::swapchain::SwapchainImage; use vulkano::image::swapchain::SwapchainImage;
use winit::{Window}; use winit::{Window};
use crate::canvas::{CanvasState, CanvasFrame, ImageHandle};
use crate::compu_state::CompuState; use crate::compu_state::CompuState;
use vulkano::image::ImageUsage; use vulkano::image::ImageUsage;
use crate::compu_buffer::CompuBufferHandle;
use crate::compu_frame::CompuFrame; use crate::compu_frame::CompuFrame;
use crate::canvas::{CanvasState, CanvasTextureHandle, CanvasShaderHandle, CanvasImageHandle};
use crate::canvas_frame::CanvasFrame;
use crate::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
pub struct VkProcessor<'a> { pub struct VkProcessor<'a> {
@ -64,8 +66,6 @@ impl<'a> VkProcessor<'a> {
queue: queue.clone(), queue: queue.clone(),
queues: queues, queues: queues,
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
compute_kernel: None,
compute_image: None,
swapchain: None, swapchain: None,
swapchain_images: None, swapchain_images: None,
swapchain_recreate_needed: false, swapchain_recreate_needed: false,
@ -132,27 +132,27 @@ impl<'a> VkProcessor<'a> {
} }
pub fn preload_textures(&mut self) { pub fn preload_textures(&mut self) {
self.canvas.load_texture_from_filename(String::from("funky-bird.jpg")); self.canvas.load_texture(String::from("funky-bird.jpg"));
} }
pub fn preload_kernels(&mut self) { pub fn preload_kernels(&mut self) {
self.compute_state.new_kernel(String::from("simple-edge.compute"), self.device.clone());
} }
pub fn preload_shaders(&mut self) { pub fn preload_shaders(&mut self) {
} }
pub fn get_texture_handle(&self, texture_name: String) -> Option<Arc<u32>> { pub fn get_texture_handle(&self, texture_name: String) -> Option<Arc<CanvasTextureHandle>> {
None None
} }
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<u32>> { pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
None None
} }
pub fn get_shader_handle(&self, shader_name: String) -> Option<Arc<u32>> { pub fn get_shader_handle(&self, shader_name: String) -> Option<Arc<CanvasShaderHandle>> {
None None
} }
// Create a new image which has the transfer usage // Create a new image which has the transfer usage
pub fn new_swap_image(&mut self, dimensions: (u32, u32)) -> Arc<ImageHandle> { pub fn new_swap_image(&mut self, dimensions: (u32, u32)) -> Arc<CanvasImageHandle> {
let mut usage = ImageUsage::none(); let mut usage = ImageUsage::none();
usage.transfer_destination = true; usage.transfer_destination = true;
usage.storage = true; usage.storage = true;

Loading…
Cancel
Save