very close to the skeleton of the canvas written. Still haven't tested it but it's looking good. Need to figure out how I'm goign to iterate shader_kernels without borrowing from self

master
mitchellhansen 5 years ago
parent 2207c41956
commit a7e79668eb

@ -17,6 +17,9 @@ use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use std::path::PathBuf; use std::path::PathBuf;
use image::GenericImageView; use image::GenericImageView;
use crate::util::compute_image::ComputeImage; use crate::util::compute_image::ComputeImage;
use std::iter::FromIterator;
use vulkano::swapchain::Capabilities;
use shaderc::TargetEnv;
// Canvas is the accumulator of Sprites for drawing // Canvas is the accumulator of Sprites for drawing
// Needs to know: // Needs to know:
@ -107,27 +110,8 @@ pub trait Drawable {
/*
OASIJDOQIWEJFOWIEJFOWIEJFOWEIJFOIWEJFOIW
Right now I'm in the middle of adding texture ownership to the canvas.
I'm aiming at being able to load them on the fly from what texture name (String) the
sprite is requesting. This might be too slow though as I can't really avoid a lookup table
somewhere in the code.
*/
// Need three types of shaders. Solid, Textured, Compute // Need three types of shaders. Solid, Textured, Compute
#[derive(PartialEq)] #[derive(PartialEq, Eq, Hash)]
#[derive(Eq)]
#[derive(Hash)]
pub enum ShaderType { pub enum ShaderType {
SOLID = 0, SOLID = 0,
TEXTURED = 1, TEXTURED = 1,
@ -137,31 +121,61 @@ pub enum ShaderType {
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)>>,
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)>>,
vertex_buffers: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>, vertex_buffers: Vec<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
shader_kernels: HashMap<ShaderType, ShaderKernels>, shader_kernels: HashMap<ShaderType, ShaderKernels>,
textures: Vec<Arc<ImmutableImage<Format>>>, texture_store: HashMap<String, Arc<ImmutableImage<Format>>>,
// Looks like we gotta hold onto the queue for managing textures
queue: Arc<Queue>,
sampler: Arc<Sampler>
} }
impl Canvas { impl Canvas {
// needs to take in the texture list // needs to take in the texture list
pub fn new() -> Canvas { pub fn new(queue: Arc<Queue>,
device: Arc<Device>,
physical: PhysicalDevice,
capabilities: Capabilities) -> Canvas {
let solid_color_kernel = String::from("color-passthrough");
let texture_kernel = String::from("simple_texture");
let shader_kernels = 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()))
]);
Canvas { Canvas {
colored_drawables: vec![], colored_drawables: vec![],
colored_vertex_buffer: vec![],
textured_drawables: Default::default(), textured_drawables: Default::default(),
textured_vertex_buffer: Default::default(),
vertex_buffers: vec![], vertex_buffers: vec![],
shader_kernels: HashMap::new(), shader_kernels: shader_kernels,
textures: vec![] texture_store: Default::default(),
queue: queue.clone(),
sampler: Sampler::new(device.clone(), Filter::Linear, Filter::Linear,
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(),
} }
} }
fn get_texture_from_file(image_filename: String, queue: Arc<Queue>) -> Arc<ImmutableImage<Format>> { // TODO Handle file not found gracefully
fn get_texture_from_file(&self, image_filename: String) -> Arc<ImmutableImage<Format>> {
let project_root = let project_root =
std::env::current_dir() std::env::current_dir()
@ -197,20 +211,26 @@ impl Canvas {
image_buffer.iter().cloned(), image_buffer.iter().cloned(),
Dimensions::Dim2d { width: xy.0, height: xy.1 }, Dimensions::Dim2d { width: xy.0, height: xy.1 },
Format::R8G8B8A8Srgb, Format::R8G8B8A8Srgb,
queue.clone() self.queue.clone()
).unwrap(); ).unwrap();
texture texture
} }
pub fn load_texture_from_filename(&mut self, filename: String, queue: Arc<Queue>) { pub fn load_texture_from_filename(&mut self, filename: String) -> Arc<ImmutableImage<Format>> {
let texture = Canvas::get_texture_from_file(filename.clone(), queue.clone());
self.textures.push(texture); if (self.texture_store.contains_key(&filename.clone())) {
println!("{} Already exists, not going to replace it.", filename.clone());
self.texture_store.get(&filename.clone()).unwrap().clone()
} else {
let texture = self.get_texture_from_file(filename.clone());
self.texture_store.insert(filename, texture.clone());
texture
}
let texture1 = Canvas::get_texture_from_file(String::from("button.png"), queue.clone());
self.textures.push(texture1);
} }
// After done using this, need to call allocated vertex buffers
pub fn draw(&mut self, drawable: &dyn Drawable) { pub fn draw(&mut self, drawable: &dyn Drawable) {
match drawable.get_texture_id() { match drawable.get_texture_id() {
@ -234,8 +254,20 @@ impl Canvas {
} }
fn get_texture(&mut self, texture_id: String) -> Arc<ImmutableImage<Format>> {
if let Some(i) = self.texture_store.get(&texture_id) {
return i.clone();
} else {
self.load_texture_from_filename(texture_id)
}
}
pub fn allocate_colored_vertex_buffers(&mut self, device: Arc<Device>) {
pub fn allocate_vertex_buffers(&mut self, device: Arc<Device>) { self.vertex_buffers.clear();
self.colored_vertex_buffer.clear();
self.vertex_buffers.push( self.vertex_buffers.push(
CpuAccessibleBuffer::from_iter( CpuAccessibleBuffer::from_iter(
@ -244,6 +276,14 @@ impl Canvas {
self.colored_drawables.iter().cloned() self.colored_drawables.iter().cloned()
).unwrap() ).unwrap()
); );
self.colored_vertex_buffer.push(
CpuAccessibleBuffer::from_iter(
device.clone(),
BufferUsage::vertex_buffer(),
self.colored_drawables.iter().cloned()
).unwrap()
);
} }
// I guess these go out as an array. So I can add multiple descriptor sets // I guess these go out as an array. So I can add multiple descriptor sets
@ -256,22 +296,37 @@ impl Canvas {
// Choose which texture I want to add to this descriptor set. // Choose which texture I want to add to this descriptor set.
// Add multiple textures // Add multiple textures
// Choose which shader and pipeline it should run on // Choose which shader and pipeline it should run on
fn get_texture_descriptor_set(&mut self, device: Arc<Device>) -> Box<dyn DescriptorSet + Send + Sync> {
let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear, fn get_descriptor_set(&mut self,
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, shader_type: &ShaderType,
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(); texture_id: String) -> Box<dyn DescriptorSet + Send + Sync> {
match shader_type {
ShaderType::SOLID => {
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
self.shader_kernels.get(&shader_type).unwrap().clone().get_pipeline().clone(), 0
).build().unwrap());
o
},
ShaderType::TEXTURED => {
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new( let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start( PersistentDescriptorSet::start(
self.shader_kernels.get(&ShaderType::TEXTURED).unwrap().clone().get_pipeline(), 0 self.shader_kernels.get(&shader_type).unwrap().clone().get_pipeline().clone(), 0
) )
.add_sampled_image(self.textures.get(0).unwrap().clone(), sampler.clone()).unwrap() .add_sampled_image(self.get_texture(texture_id), self.sampler.clone()).unwrap()
.build().unwrap()); .build().unwrap());
o o
},
ShaderType::COMPUTE => {
unimplemented!("Compute dont work here");
},
}
} }
// The image set is the containing object for all texture and image hooks. // This is the image which is written to by the write compute buffer
// I suppose I could just have a general image set maker instead of compue... they are
// somewhat similar
fn get_compute_swap_descriptor_set(&mut self, fn get_compute_swap_descriptor_set(&mut self,
device: Arc<Device>, device: Arc<Device>,
compute_image: &ComputeImage) -> Box<dyn DescriptorSet + Send + Sync> { compute_image: &ComputeImage) -> Box<dyn DescriptorSet + Send + Sync> {
@ -290,6 +345,7 @@ impl Canvas {
} }
/* /*
@ -331,13 +387,26 @@ impl Canvas {
framebuffers[image_num].clone(), false, clear_values.clone() framebuffers[image_num].clone(), false, clear_values.clone()
).unwrap(); ).unwrap();
// for i in self.shader_kernels {
// command_buffer = command_buffer.draw( // So I need to do this without borrowing self from the shader_kernels....
// i.clone().unwrap().get_pipeline(), // Maybe self referential struct issue cropping up
// &dynamic_state.clone(), self.vertex_buffers, //
// vec![self.get_image_set()], () //
// ).unwrap(); //
// } //
//
//
//
//
for (shader_type, kernel) in self.shader_kernels.iter() {
command_buffer = command_buffer.draw(
kernel.clone().get_pipeline().clone(),
&dynamic_state.clone(), self.vertex_buffers.clone(),
vec![self.get_descriptor_set(shader_type, String::from("texture"))], ()
).unwrap();
}
// //
// .draw(self.shader_kernels.clone().unwrap().get_pipeline(), // .draw(self.shader_kernels.clone().unwrap().get_pipeline(),
// &dynamic_state.clone(), self.vertex_buffers, // &dynamic_state.clone(), self.vertex_buffers,
@ -349,3 +418,33 @@ impl Canvas {
.unwrap() .unwrap()
} }
} }

@ -20,7 +20,7 @@ use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, Persistent
use shaderc::CompileOptions; use shaderc::CompileOptions;
use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract, RenderPassDesc}; use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract, RenderPassDesc};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry}; use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry};
use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError}; use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities};
use vulkano::swapchain::acquire_next_image; use vulkano::swapchain::acquire_next_image;
use vulkano::image::swapchain::SwapchainImage; use vulkano::image::swapchain::SwapchainImage;
use winit::{EventsLoop, WindowBuilder, Window, Event, WindowEvent}; use winit::{EventsLoop, WindowBuilder, Window, Event, WindowEvent};
@ -80,12 +80,11 @@ impl ShaderKernels {
} }
pub fn new(filename: String, pub fn new(filename: String,
surface: &Arc<Surface<Window>>, capabilities: Capabilities,
queue: Arc<Queue>, queue: Arc<Queue>,
physical: PhysicalDevice, physical: PhysicalDevice,
device: Arc<Device>) -> ShaderKernels { device: Arc<Device>) -> ShaderKernels {
let capabilities = surface.capabilities(physical).unwrap();
let format = capabilities.supported_formats[0].0; let format = capabilities.supported_formats[0].0;
let filenames = ShaderKernels::get_path(filename.clone()); let filenames = ShaderKernels::get_path(filename.clone());

@ -21,7 +21,7 @@ use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, Persistent
use shaderc::CompileOptions; use shaderc::CompileOptions;
use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract}; use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry}; use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry};
use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError}; use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities};
use vulkano::swapchain::acquire_next_image; use vulkano::swapchain::acquire_next_image;
use vulkano::image::swapchain::SwapchainImage; use vulkano::image::swapchain::SwapchainImage;
use winit::{EventsLoop, WindowBuilder, Window, Event, WindowEvent}; use winit::{EventsLoop, WindowBuilder, Window, Event, WindowEvent};
@ -99,12 +99,16 @@ pub struct VkProcessor<'a> {
swapchain_recreate_needed: bool, swapchain_recreate_needed: bool,
capabilities: Capabilities
} }
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();
let queue_family = physical.queue_families().find(|&q| { let queue_family = physical.queue_families().find(|&q| {
@ -138,6 +142,7 @@ impl<'a> VkProcessor<'a> {
swapchain: None, swapchain: None,
swapchain_images: None, swapchain_images: None,
swapchain_recreate_needed: false, swapchain_recreate_needed: false,
capabilities: surface.capabilities(physical).unwrap()
} }
} }
@ -149,7 +154,7 @@ impl<'a> VkProcessor<'a> {
pub fn compile_shaders(&mut self, filename: String, surface: &'a Arc<Surface<Window>>) { pub fn compile_shaders(&mut self, filename: String, surface: &'a Arc<Surface<Window>>) {
self.shader_kernels = Some( self.shader_kernels = Some(
ShaderKernels::new(filename.clone(), ShaderKernels::new(filename.clone(),
surface, self.queue.clone(), self.capabilities.clone(), self.queue.clone(),
self.physical, self.physical,
self.device.clone()) self.device.clone())
); );

Loading…
Cancel
Save