working on docs

master
mitchellhansen 5 years ago
parent 314fa3e4af
commit 26b73c48a8

@ -23,46 +23,25 @@ use crate::canvas_frame::CanvasFrame;
use std::hash::Hash; use std::hash::Hash;
use crate::canvas_shader::CanvasShader; use crate::canvas_shader::CanvasShader;
use crate::canvas_buffer::{CanvasImage, CanvasTexture}; use crate::canvas_buffer::{CanvasImage, CanvasTexture};
// Canvas is the accumulator of Sprites for drawing
// Needs to know:
// textured?
// colored?
// vertices
/* /*
If it is textured. It needs to be rendered with the texture shader which requires a separate If it is textured. It needs to be rendered with the texture shader which requires a separate
graphics pipeline. Might as well have a new render pass as well. graphics pipeline. Might as well have a new render pass as well.
So framebuffer is tied to the swapchains images as well as the renderpass So framebuffer is tied to the swapchains images as well as the renderpass
it appears that renderpass is tied to the individual shader it appears that renderpass is tied to the individual shader
*/ */
// I want to be able to draw 2d sprites.
// These sprites might be textured or a single color
// All of the single colors will be grouped into one batch using colored vertices.
// The rest will be grouped by their texture and run individually
/// Vertex trait for Drawable Vertices.
pub trait Vertex { pub trait Vertex {
fn position(&self) -> (f32, f32) { fn position(&self) -> (f32, f32) {
(0.0, 0.0) (0.0, 0.0)
} }
fn color(&self) -> Option<(f32, f32, f32, f32)> { fn color(&self) -> Option<(f32, f32, f32, f32)> {
Some((0., 0., 0., 0.)) Some((0., 0., 0., 0.))
} }
} }
impl Vertex for ColoredVertex2D { impl Vertex for ColoredVertex2D {
fn position(&self) -> (f32, f32) { fn position(&self) -> (f32, f32) {
(0.0, 0.0) (0.0, 0.0)
@ -73,6 +52,8 @@ impl Vertex for ColoredVertex2D {
} }
} }
/// A drawable object can be passed into a CanvasFrame to be rendered
/// Allows Texture or Image drawing via their handles
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);
@ -80,7 +61,7 @@ pub trait Drawable {
fn get_image_handle(&self) -> Option<Arc<CanvasImageHandle>>; fn get_image_handle(&self) -> Option<Arc<CanvasImageHandle>>;
} }
// Need three types of shaders. Solid, Textured, Image /// Legacy ShaderType enum for single type shaders.
#[derive(PartialEq, Eq, Hash, Clone)] #[derive(PartialEq, Eq, Hash, Clone)]
pub enum ShaderType { pub enum ShaderType {
SOLID = 0, SOLID = 0,
@ -88,22 +69,18 @@ pub enum ShaderType {
IMAGE = 2, IMAGE = 2,
} }
/// Typed wrapper for a u32 texture handle (index id)
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CanvasTextureHandle { pub struct CanvasTextureHandle {
pub handle: u32 pub handle: u32
} }
/// Typed wrapper for a u32 image handle (index id)
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CanvasImageHandle { pub struct CanvasImageHandle {
pub handle: u32 pub handle: u32
} }
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct CanvasShaderHandle {
pub handle: u32
}
#[derive(Clone)] #[derive(Clone)]
pub struct CanvasState { pub struct CanvasState {
dynamic_state: DynamicState, dynamic_state: DynamicState,
@ -158,8 +135,6 @@ 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 texture_kernel = String::from("simple_texture");
CanvasState { CanvasState {
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
@ -168,20 +143,7 @@ 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: HashMap::from_iter(vec![ shader_buffers: HashMap::from_iter(vec![]),
(solid_color_kernel.clone(), Arc::new(CanvasShader::new_colored(solid_color_kernel.clone(),
capabilities.clone(),
queue.clone(),
physical.clone(),
device.clone()))
),
(texture_kernel.clone(), Arc::new(CanvasShader::new_textured(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![],
@ -279,6 +241,22 @@ impl CanvasState {
Some(handle) Some(handle)
} }
/// Load and Compile a shader with the filename at resources/shaders
/// Takes physical and capabilities as we don't store that in Canvas
pub fn load_shader(&mut self,
filename: String,
physical: PhysicalDevice,
capabilities: Capabilities) {
self.shader_buffers.insert(filename.clone(),
Arc::new(CanvasShader::new_colored(filename.clone(),
capabilities.clone(),
self.queue.clone(),
physical.clone(),
self.device.clone())));
}
/// Using the texture name, iterates through the stored textures and matches by the name
pub fn get_texture_handle(&self, texture_name: String) pub fn get_texture_handle(&self, texture_name: String)
-> Option<Arc<CanvasTextureHandle>> { -> Option<Arc<CanvasTextureHandle>> {
for i in self.texture_buffers.clone() { for i in self.texture_buffers.clone() {
@ -289,6 +267,7 @@ impl CanvasState {
None None
} }
/// Using the texture handle, grab the stored texture and return the buffer
pub fn get_texture(&self, texture_handle: Arc<CanvasTextureHandle>) pub fn get_texture(&self, texture_handle: Arc<CanvasTextureHandle>)
-> Arc<ImmutableImage<Format>> { -> Arc<ImmutableImage<Format>> {
let handle = texture_handle.handle as usize; let handle = texture_handle.handle as usize;
@ -300,35 +279,18 @@ impl CanvasState {
} }
} }
// After done using this, need to call allocated vertex buffers /// Scrape all the values from the CanvasFrame and then allocate the 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;
self.colored_drawables = canvas_frame.colored_drawables; self.colored_drawables = canvas_frame.colored_drawables;
self.image_drawables = canvas_frame.image_drawables; self.image_drawables = canvas_frame.image_drawables;
self.allocate_vertex_buffers(self.device.clone()); self.allocate_vertex_buffers();
} }
fn allocate_vertex_buffers(&mut self, device: Arc<Device>) { /// draw(canvas_fame) stored all the intermediate information, this function
self.image_vertex_buffer.clear(); /// allocates the vertex buffers using that information
fn allocate_vertex_buffers(&mut self) {
/*
So a bit of brainstorming with the shaders:
I compile shaders into their respective buffers and add them to a descriptor set
along with the textures or whatever other resource buffer
So I'm gonna fix that texturing issue by adding vertex texture coordinate attributes
Still don't really know how I'm gonna do this...
* Going to definitely need to use the CpuAccessbileBuffer
* Maybe calculate deltas between frames???
*
*/
self.colored_vertex_buffer.clear(); self.colored_vertex_buffer.clear();
{ {
@ -356,8 +318,24 @@ impl CanvasState {
); );
} }
} }
self.image_vertex_buffer.clear();
{
let g = hprof::enter("Image Vertex Buffer");
for (k, v) in self.image_drawables.drain() {
self.image_vertex_buffer.insert(
k.clone(),
ImmutableBuffer::from_iter(
v.first().unwrap().iter().cloned(),
BufferUsage::vertex_buffer(),
self.queue.clone(),
).unwrap().0,
);
}
}
} }
/// Builds the descriptor set for solid colors using the input kernel (needs to support solid colors)
fn get_solid_color_descriptor_set(&self, kernel: Arc<CanvasShader>) -> Box<dyn DescriptorSet + Send + Sync> { fn get_solid_color_descriptor_set(&self, kernel: Arc<CanvasShader>) -> Box<dyn DescriptorSet + Send + Sync> {
let o: Box<dyn DescriptorSet + Send + Sync> = Box::new( let o: Box<dyn DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start( PersistentDescriptorSet::start(
@ -366,6 +344,7 @@ impl CanvasState {
o o
} }
/// Pushes the draw commands s
pub fn draw_commands(&self, pub fn draw_commands(&self,
mut command_buffer: AutoCommandBufferBuilder, mut command_buffer: AutoCommandBufferBuilder,
framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>, framebuffers: Vec<Arc<dyn FramebufferAbstract + Send + Sync>>,
@ -392,10 +371,9 @@ impl CanvasState {
).unwrap(); ).unwrap();
} }
// Images // Textures
let mut shader = self.shader_buffers.get("simple_texture").unwrap().clone(); let mut shader = self.shader_buffers.get("simple_texture").unwrap().clone();
if !self.textured_vertex_buffer.is_empty() { if !self.textured_vertex_buffer.is_empty() {
let handle = self.get_texture_handle(String::from("funky-bird.jpg")).unwrap().clone(); let handle = self.get_texture_handle(String::from("funky-bird.jpg")).unwrap().clone();
@ -411,21 +389,26 @@ impl CanvasState {
vec![descriptor_set], (), vec![descriptor_set], (),
).unwrap(); ).unwrap();
} }
/*for (shader_type, kernel) in self.shader_kernels.clone().iter() {
match shader_type {
ShaderType::SOLID => {
}
ShaderType::TEXTURED => { let mut shader = self.shader_buffers.get("simple-image").unwrap().clone();
command_buffer = command_buffer.draw(
kernel.clone().get_pipeline().clone(), if !self.image_vertex_buffer.is_empty() {
&dynamic_state.clone(), self.textured_vertex_buffer.clone(),
vec![self.get_textured_descriptor_set(String::from("funky-bird.jpg"))], () let handle = self.get_texture_handle(String::from("funky-bird.jpg")).unwrap().clone();
).unwrap();
} // TODO : BAD BAD BAD. SELECTS FIRST TEXTURE ONLY!!!!!!!!!!!!
ShaderType::IMAGE => {} let descriptor_set = self.texture_buffers.first().clone().unwrap().clone()
} .get_descriptor_set(shader.clone(), self.sampler.clone());
}*/
let vertex_buffer = self.textured_vertex_buffer.get(&handle).unwrap().clone();
command_buffer = command_buffer.draw(
shader.get_pipeline().clone(),
&self.dynamic_state.clone(), vec![vertex_buffer],
vec![descriptor_set], (),
).unwrap();
}
command_buffer command_buffer
.end_render_pass() .end_render_pass()

@ -10,12 +10,13 @@ use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, Specialization
use vulkano::swapchain::{Capabilities}; use vulkano::swapchain::{Capabilities};
use crate::vertex_2d::{ColoredVertex2D, Vertex2D}; use crate::vertex_2d::{ColoredVertex2D, Vertex2D};
/* /// Typed wrapper for a u32 shader handle (index id)
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
CanvasShader holds the pipeline and render pass for the inputted shader source pub struct CanvasShaderHandle {
pub handle: u32
*/ }
/// CanvasShader holds the pipeline and render pass for the input shader source
#[derive(Clone)] #[derive(Clone)]
pub struct CanvasShader { pub struct CanvasShader {
@ -27,6 +28,8 @@ pub struct CanvasShader {
impl CanvasShader { impl CanvasShader {
/// Takes the filename of a .vertex .fragment shader combo in resources/shaders/
/// Returns pathbuffer of that vertex and fragment shader
fn get_path(filename: String) -> (PathBuf, PathBuf) { fn get_path(filename: String) -> (PathBuf, PathBuf) {
let project_root = let project_root =
@ -47,10 +50,13 @@ impl CanvasShader {
(vertex_shader_path, fragment_shader_path) (vertex_shader_path, fragment_shader_path)
} }
/// Clone and returns the compiled graphics pipeline
pub fn get_pipeline(&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()
} }
/// Create a new `Colored` shader. Which just means that it uses ColoredVertex2D's
/// This will explode when the shader does not want to compile
pub fn new_colored(filename: String, pub fn new_colored(filename: String,
capabilities: Capabilities, capabilities: Capabilities,
queue: Arc<Queue>, queue: Arc<Queue>,
@ -168,6 +174,8 @@ impl CanvasShader {
} }
} }
/// Create a new `Textured` shader. Which just means that it uses plain Vertex2D's
/// This will explode when the shader does not want to compile
pub fn new_textured(filename: String, pub fn new_textured(filename: String,
capabilities: Capabilities, capabilities: Capabilities,
queue: Arc<Queue>, queue: Arc<Queue>,
@ -289,7 +297,7 @@ impl CanvasShader {
#[repr(C)] #[repr(C)]
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]
// TODO: This needs to be duplicated and moved into their respective containers shaderkenrels copute /// Specialization constants which can be passed to the shader. Pretty much placeholder ATM
struct ShaderSpecializationConstants { struct ShaderSpecializationConstants {
first_constant: i32, first_constant: i32,
second_constant: u32, second_constant: u32,

@ -75,7 +75,6 @@ impl CompuState {
handle handle
} }
// TODO : THIS IS BROKEN
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> { pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
for i in self.kernels.clone() { for i in self.kernels.clone() {
if i.get_name() == kernel_name { if i.get_name() == kernel_name {
@ -127,8 +126,10 @@ impl CompuState {
panic!("Buffer sizes not the same"); panic!("Buffer sizes not the same");
} }
let size = buffer.get_size();
command_buffer = command_buffer command_buffer = command_buffer
.dispatch([100,100,1], p, d, ()).unwrap() .dispatch([size.0,size.1,1], p, d, ()).unwrap()
.copy_buffer_to_image(buffer.get_input_buffer(), image).unwrap(); .copy_buffer_to_image(buffer.get_input_buffer(), image).unwrap();
} }

@ -28,24 +28,24 @@ use crate::compu_buffer::CompuBuffers;
use crate::util::load_raw; use crate::util::load_raw;
use crate::canvas_frame::CanvasFrame; use crate::canvas_frame::CanvasFrame;
mod util; pub mod util;
mod timer; pub mod timer;
mod input; pub mod input;
mod vkprocessor; pub mod vkprocessor;
mod vertex_2d; pub mod vertex_2d;
mod vertex_3d; pub mod vertex_3d;
mod sprite; pub mod sprite;
mod canvas; pub mod canvas;
mod canvas_frame; pub mod canvas_frame;
mod canvas_shader; pub mod canvas_shader;
mod canvas_buffer; pub mod canvas_buffer;
mod compu_state; pub mod compu_state;
mod compu_frame; pub mod compu_frame;
mod compu_sprite; pub mod compu_sprite;
mod compu_kernel; pub mod compu_kernel;
mod compu_buffer; pub mod compu_buffer;
/* /*
@ -56,7 +56,9 @@ Canvas works, but I want to use CPU accessible buffer instead of immutable buffe
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
*/ */
fn main() {
/// Main Entry
pub fn main() {
hprof::start_frame(); hprof::start_frame();
@ -166,12 +168,12 @@ fn main() {
let mut compu_frame = CompuFrame::new(); let mut compu_frame = CompuFrame::new();
compu_frame.add(compute_buffer.clone(), compute_kernel.clone()); compu_frame.add(compute_buffer.clone(), compute_kernel.clone());
// compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1); compu_frame.add_with_image_swap(compute_buffer.clone(), compute_kernel.clone(), &compu_sprite1);
let mut canvas = CanvasFrame::new(); let mut canvas = CanvasFrame::new();
// canvas.draw(&sprite); canvas.draw(&sprite);
// canvas.draw(&sprite2); canvas.draw(&sprite2);
// canvas.draw(&sprite3); canvas.draw(&sprite3);
//canvas.draw(&compu_sprite1); //canvas.draw(&compu_sprite1);
{ {
let g = hprof::enter("Run"); let g = hprof::enter("Run");

@ -11,12 +11,15 @@ use winit::Window;
use crate::compu_state::CompuState; use crate::compu_state::CompuState;
use vulkano::image::ImageUsage; use vulkano::image::ImageUsage;
use crate::compu_frame::CompuFrame; use crate::compu_frame::CompuFrame;
use crate::canvas::{CanvasState, CanvasTextureHandle, CanvasShaderHandle, CanvasImageHandle}; use crate::canvas::{CanvasState, CanvasTextureHandle, CanvasImageHandle};
use crate::canvas_frame::CanvasFrame; use crate::canvas_frame::CanvasFrame;
use crate::compu_kernel::{CompuKernel, CompuKernelHandle}; use crate::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle}; use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
use std::time::Duration; use std::time::Duration;
use crate::canvas_shader::CanvasShaderHandle;
/// VKProcessor holds the vulkan instance information, the swapchain, and the compute and canvas states
///
pub struct VkProcessor<'a> { pub struct VkProcessor<'a> {
// Vulkan state fields // Vulkan state fields
pub instance: Arc<Instance>, pub instance: Arc<Instance>,
@ -39,7 +42,11 @@ pub struct VkProcessor<'a> {
impl<'a> VkProcessor<'a> { impl<'a> VkProcessor<'a> {
/// Creates a new VkProcessor from an instance and surface
/// This includes the physical device, queues, compute and canvas state
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| {
@ -75,6 +82,7 @@ impl<'a> VkProcessor<'a> {
} }
} }
/// Using the surface, we calculate the surface capabilities and create the swapchain and swapchain images
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();
@ -109,7 +117,8 @@ impl<'a> VkProcessor<'a> {
self.swapchain = Some(swapchain); self.swapchain = Some(swapchain);
self.swapchain_images = Some(images); self.swapchain_images = Some(images);
} }
// On resizes we have to recreate the swapchain
/// On screen resizes, the swapchain and images must be recreated
pub fn recreate_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) { pub fn recreate_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) {
let dimensions = if let Some(dimensions) = surface.window().get_inner_size() { let dimensions = if let Some(dimensions) = surface.window().get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into();
@ -130,17 +139,27 @@ impl<'a> VkProcessor<'a> {
self.swapchain_images = Some(new_images); self.swapchain_images = Some(new_images);
} }
/// A hardcoded list of textures which can be preloaded from this function
pub fn preload_textures(&mut self) { pub fn preload_textures(&mut self) {
self.canvas.load_texture(String::from("funky-bird.jpg")); self.canvas.load_texture(String::from("funky-bird.jpg"));
self.canvas.load_texture(String::from("button.png")); self.canvas.load_texture(String::from("button.png"));
self.canvas.load_texture(String::from("background.jpg")); self.canvas.load_texture(String::from("background.jpg"));
self.canvas.load_texture(String::from("test2.png")); self.canvas.load_texture(String::from("test2.png"));
} }
/// A hardcoded list of kernels which can be preloaded from this function
pub fn preload_kernels(&mut self) { pub fn preload_kernels(&mut self) {
self.compute_state.new_kernel(String::from("simple-homogenize.compute"), self.device.clone()); self.compute_state.new_kernel(String::from("simple-homogenize.compute"), self.device.clone());
self.compute_state.new_kernel(String::from("simple-edge.compute"), self.device.clone()); self.compute_state.new_kernel(String::from("simple-edge.compute"), self.device.clone());
} }
pub fn preload_shaders(&mut self) {}
/// A hardcoded list of shaders which can be proloaded from this function
pub fn preload_shaders(&mut self) {
self.canvas.load_shader(String::from("color-passthrough"), self.physical.clone(), self.capabilities.clone());
self.canvas.load_shader(String::from("simple_texture"), self.physical.clone(), self.capabilities.clone());
}
pub fn get_texture_handle(&self, texture_name: String) -> Option<Arc<CanvasTextureHandle>> { pub fn get_texture_handle(&self, texture_name: String) -> Option<Arc<CanvasTextureHandle>> {
self.canvas.get_texture_handle(texture_name) self.canvas.get_texture_handle(texture_name)
} }

Loading…
Cancel
Save