Moved the framebuffer gen to the canvas. Cleaned up a lot of unused imports

This commit is contained in:
2019-08-11 16:37:14 -07:00
parent 8cd5e3e562
commit dfd4cbb6a2
9 changed files with 156 additions and 418 deletions

View File

@@ -1,80 +1,17 @@
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, StdDescriptorPoolAlloc, PersistentDescriptorSetBuilder, FixedSizeDescriptorSetsPool, StdDescriptorPool};
use vulkano::descriptor::descriptor_set::collection::DescriptorSetsCollection;
use vulkano::device::{Device, DeviceExtensions, QueuesIter, Queue};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice, QueueFamily};
use vulkano::pipeline::{ComputePipeline, GraphicsPipeline, GraphicsPipelineAbstract};
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use std::time::SystemTime;
use std::sync::Arc;
use std::ffi::CStr;
use std::path::PathBuf;
use shade_runner as sr;
use image::{DynamicImage, ImageBuffer};
use image::GenericImageView;
use vulkano::descriptor::pipeline_layout::PipelineLayout;
use image::GenericImage;
use shade_runner::{ComputeLayout, CompileError, FragLayout, FragInput, FragOutput, VertInput, VertOutput, VertLayout, CompiledShaders, Entry};
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, PersistentDescriptorSetImg, PersistentDescriptorSetSampler};
use shaderc::CompileOptions;
use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule, GraphicsEntryPoint, SpecializationConstants, SpecializationMapEntry};
use vulkano::swapchain::{Swapchain, PresentMode, SurfaceTransform, Surface, SwapchainCreationError, AcquireError, Capabilities};
use vulkano::swapchain::acquire_next_image;
use vulkano::image::swapchain::SwapchainImage;
use winit::{EventsLoop, WindowBuilder, Window, Event, WindowEvent};
use vulkano_win::VkSurfaceBuild;
use vulkano::pipeline::vertex::{SingleBufferDefinition, Vertex};
use vulkano::descriptor::{PipelineLayoutAbstract, DescriptorSet};
use std::alloc::Layout;
use vulkano::pipeline::viewport::Viewport;
use image::ImageFormat;
use vulkano::image::immutable::ImmutableImage;
use vulkano::image::attachment::AttachmentImage;
use vulkano::image::{Dimensions, ImageUsage, ImageAccess, ImageDimensions};
use vulkano::format::Format;
use vulkano::format::ClearValue;
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
use image::flat::NormalForm::ColumnMajorPacked;
use winit::{Window};
use crate::util::compute_kernel::ComputeKernel;
use crate::util::shader_kernels::ShaderKernels;
use crate::util::compute_image::ComputeImage;
use vulkano::descriptor::descriptor::DescriptorDesc;
use crate::vertex_2d::ColoredVertex2D;
use crate::canvas::Canvas;
use std::mem;
/// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>],
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
dynamic_state: &mut DynamicState,
) -> Vec<Arc<dyn FramebufferAbstract + Send + Sync>> {
let dimensions = images[0].dimensions();
let viewport = Viewport {
origin: [0.0, 0.0],
dimensions: [dimensions.width() as f32, dimensions.height() as f32],
depth_range: 0.0..1.0,
};
dynamic_state.viewports = Some(vec!(viewport));
images.iter().map(|image| {
Arc::new(
Framebuffer::start(render_pass.clone())
.add(image.clone()).unwrap()
.build().unwrap()
) as Arc<dyn FramebufferAbstract + Send + Sync>
}).collect::<Vec<_>>()
}
pub struct VkProcessor<'a> {
// Vulkan state fields
pub instance: Arc<Instance>,
pub physical: PhysicalDevice<'a>,
@@ -84,15 +21,7 @@ pub struct VkProcessor<'a> {
pub dynamic_state: DynamicState,
// TODO: This will need to handle multiple of each type
pub shader_kernels: Option<ShaderKernels>,
pub compute_kernel: Option<ComputeKernel>,
// TODO: Move this into canvas
pub vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
pub vertex_buffer2: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
pub textures: Vec<Arc<ImmutableImage<Format>>>,
pub compute_image: Option<ComputeImage>,
pub swapchain: Option<Arc<Swapchain<Window>>>,
@@ -106,9 +35,7 @@ pub struct VkProcessor<'a> {
impl<'a> VkProcessor<'a> {
pub fn new(instance: &'a Arc<Instance>, surface: &'a Arc<Surface<Window>>) -> VkProcessor<'a> {
let physical = PhysicalDevice::enumerate(instance).next().unwrap();
let queue_family = physical.queue_families().find(|&q| {
@@ -135,36 +62,23 @@ impl<'a> VkProcessor<'a> {
queue: queue.clone(),
queues: queues,
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
shader_kernels: None,
compute_kernel: None,
vertex_buffer: None,
vertex_buffer2: None,
textures: vec![],
compute_image: None,
swapchain: None,
swapchain_images: None,
swapchain_recreate_needed: false,
capabilities: capabilities.clone(),
canvas: Canvas::new(queue, device, physical, capabilities)
canvas: Canvas::new(queue, device, physical, capabilities),
}
}
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 compile_shaders(&mut self, filename: String, surface: &'a Arc<Surface<Window>>) {
self.shader_kernels = Some(
ShaderKernels::new(filename.clone(),
self.capabilities.clone(), self.queue.clone(),
self.physical,
self.device.clone())
);
}
pub fn create_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) {
let (mut swapchain, images) = {
let capabilities = surface.capabilities(self.physical).unwrap();
let usage = capabilities.supported_usage_flags;
@@ -197,12 +111,10 @@ impl<'a> VkProcessor<'a> {
self.swapchain = Some(swapchain);
self.swapchain_images = Some(images);
}
// On resizes we have to recreate the swapchain
pub fn recreate_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) {
let dimensions = if let Some(dimensions) = surface.window().get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into();
[dimensions.0, dimensions.1]
@@ -220,143 +132,30 @@ impl<'a> VkProcessor<'a> {
self.swapchain = Some(new_swapchain);
self.swapchain_images = Some(new_images);
}
fn get_texture_from_file(image_filename: String, queue: Arc<Queue>) -> Arc<ImmutableImage<Format>> {
let project_root =
std::env::current_dir()
.expect("failed to get root directory");
let mut compute_path = project_root.clone();
compute_path.push(PathBuf::from("resources/images/"));
compute_path.push(PathBuf::from(image_filename));
let img = image::open(compute_path).expect("Couldn't find image");
let xy = img.dimensions();
let data_length = xy.0 * xy.1 * 4;
let pixel_count = img.raw_pixels().len();
let mut image_buffer = Vec::new();
if pixel_count != data_length as usize {
println!("Creating apha channel...");
for i in img.raw_pixels().iter() {
if (image_buffer.len() + 1) % 4 == 0 {
image_buffer.push(255);
}
image_buffer.push(*i);
}
image_buffer.push(255);
} else {
image_buffer = img.raw_pixels();
}
let (texture, tex_future) = ImmutableImage::from_iter(
image_buffer.iter().cloned(),
Dimensions::Dim2d { width: xy.0, height: xy.1 },
Format::R8G8B8A8Srgb,
queue.clone()
).unwrap();
texture
}
pub fn load_compute_image(&mut self, image_filename: String) {
self.compute_image = Some(ComputeImage::new(self.device.clone(), image_filename.clone()));
}
pub fn load_buffers(&mut self, image_filename: String)
pub fn load_textures(&mut self, image_filename: String)
{
self.load_compute_image(image_filename.clone());
let color = [1.,0.,0.,0.];
let vertex_buffer = {
CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [
ColoredVertex2D { position: [ 1.0, 1.0 ], color },
ColoredVertex2D { position: [ 1.0, 0.5 ], color },
ColoredVertex2D { position: [ 0.5, 0.5 ], color },
ColoredVertex2D { position: [ 0.5, 1.0 ], color },
].iter().cloned()).unwrap()
};
let vertex_buffer2 = {
CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [
ColoredVertex2D { position: [-1.0, -1.0 ], color },
ColoredVertex2D { position: [-1.0, -0.5 ], color },
ColoredVertex2D { position: [-0.5, -0.5 ], color },
ColoredVertex2D { position: [-0.5, -1.0 ], color },
].iter().cloned()).unwrap()
};
self.vertex_buffer = Some(vertex_buffer);
self.vertex_buffer2 = Some(vertex_buffer2);
let texture = VkProcessor::get_texture_from_file(image_filename.clone(), self.queue.clone());
self.textures.push(texture);
let texture1 = VkProcessor::get_texture_from_file(String::from("button.png"), self.queue.clone());
self.textures.push(texture1);
self.canvas.load_texture_from_filename(image_filename.clone());
}
// The image set is the containing object for all texture and image hooks.
fn get_image_set(&mut self) -> Box<DescriptorSet + Send + Sync> {
let sampler = Sampler::new(self.device.clone(), Filter::Linear, Filter::Linear,
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
let o : Box<DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
self.shader_kernels.clone().unwrap().get_pipeline(), 0
)
.add_sampled_image(self.textures.get(0).unwrap().clone(), sampler.clone()).unwrap()
.add_image(self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap()
.build().unwrap());
o
}
// The image set is the containing object for all texture and image hooks.
fn get_gui_image_set(&mut self) -> Box<DescriptorSet + Send + Sync> {
let sampler = Sampler::new(self.device.clone(), Filter::Linear, Filter::Linear,
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
let o : Box<DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
self.shader_kernels.clone().unwrap().get_pipeline(), 0
)
.add_sampled_image(self.textures.get(1).unwrap().clone(), sampler.clone()).unwrap()
.add_image(self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap()
.build().unwrap());
o
}
pub fn save_edges_image(&mut self){
pub fn save_edges_image(&mut self) {
self.compute_image.clone().unwrap().clone().save_image();
}
pub fn run(&mut self,
surface: &'a Arc<Surface<Window>>,
mut frame_future: Box<dyn GpuFuture>,
) -> Box<dyn GpuFuture> {
let mut framebuffers = window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone(),
self.shader_kernels.clone().unwrap().render_pass.clone(),
&mut self.dynamic_state);
let mut framebuffers =
self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone());
// The docs said to call this on each loop.
frame_future.cleanup_finished();
@@ -365,9 +164,8 @@ impl<'a> VkProcessor<'a> {
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
if self.swapchain_recreate_needed {
self.recreate_swapchain(surface);
framebuffers = window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone(),
self.shader_kernels.clone().unwrap().render_pass.clone(),
&mut self.dynamic_state);
framebuffers =
self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone());
self.swapchain_recreate_needed = false;
}
@@ -382,14 +180,6 @@ impl<'a> VkProcessor<'a> {
Err(err) => panic!("{:?}", err)
};
// Specify the color to clear the framebuffer with i.e. blue
let clear_values = vec!(ClearValue::Float([0.0, 0.0, 1.0, 1.0]));
let mut v = Vec::new();
v.push(self.vertex_buffer.clone().unwrap().clone());
let mut v2 = Vec::new();
v2.push(self.vertex_buffer2.clone().unwrap().clone());
let xy = self.compute_image.clone().unwrap().get_size();
@@ -403,19 +193,11 @@ impl<'a> VkProcessor<'a> {
.get_descriptor_set(self.compute_kernel.clone().unwrap().clone().get_pipeline()).clone(), ()).unwrap()
.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();
/*
Fuck. So this is a problem...
I can't replace canvas.
*/
let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num);
//self.canvas = mem::replace(&mut self.canvas,
let command_buffer = command_buffer.build().unwrap();
// Wait on the previous frame, then execute the command buffer and present the image