cleaning up the shader hoohaw

master
mitchellhansen 5 years ago
parent bb1f782168
commit 56455774bc

@ -75,66 +75,26 @@ fn window_size_dependent_setup(
}).collect::<Vec<_>>()
}
#[repr(C)]
#[derive(Default, Debug, Clone)]
struct SimpleSpecializationConstants {
first_constant: i32,
second_constant: u32,
third_constant: f32,
}
unsafe impl SpecializationConstants for SimpleSpecializationConstants {
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
}
}
pub struct VkProcessor<'a> {
pub shader_kernels: Option<ShaderKernels>,
pub compute_kernel: Option<ComputeKernel>,
pub vertex_shader_path: PathBuf,
pub fragment_shader_path: PathBuf,
// Vulkan state fields
pub instance: Arc<Instance>,
pub physical: PhysicalDevice<'a>,
pub graphics_pipeline: Option<Arc<GraphicsPipelineAbstract + Sync + Send>>,
pub compute_pipeline: Option<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>>,
pub device: Arc<Device>,
pub queues: QueuesIter,
pub queue: Arc<Queue>,
pub compute_set: Option<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<[u32]>>>)>>>,
pub img_set: Option<Arc<PersistentDescriptorSet<Arc<dyn GraphicsPipelineAbstract + Send + Sync>, ((((), PersistentDescriptorSetImg<Arc<ImmutableImage<Format>>>), PersistentDescriptorSetSampler), PersistentDescriptorSetImg<Arc<AttachmentImage>>)>>>,
pub graphics_image_buffer: Option<Arc<ImmutableImage<Format>>>,
pub image_buffer: Vec<u8>,
pub compute_image_buffers: Vec<Arc<CpuAccessibleBuffer<[u8]>>>,
pub settings_buffer: Option<Arc<CpuAccessibleBuffer<[u32]>>>,
pub xy: (u32, u32),
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 dynamic_state: DynamicState,
pub graphics_image_swap_buffer: Option<Arc<AttachmentImage>>,
// 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 image_buffer_store : Vec<Box<ImageAccess + Send + Sync>>,
pub compute_image: Option<ComputeImage>,
pub swapchain: Option<Arc<Swapchain<Window>>>,
@ -164,35 +124,18 @@ impl<'a> VkProcessor<'a> {
let queue = queues.next().unwrap();
VkProcessor {
shader_kernels: Option::None,
compute_kernel: Option::None,
vertex_shader_path: Default::default(),
fragment_shader_path: Default::default(),
instance: instance.clone(),
physical: physical.clone(),
graphics_pipeline: Option::None,
compute_pipeline: Option::None,
device: device.clone(),
queue: queue,
queues: queues,
compute_set: Option::None,
img_set: Option::None,
graphics_image_buffer: None,
image_buffer: Vec::new(),
compute_image_buffers: Vec::new(),
settings_buffer: Option::None,
xy: (0, 0),
vertex_buffer: Option::None,
vertex_buffer2: None,
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
graphics_image_swap_buffer: None,
shader_kernels: None,
compute_kernel: None,
vertex_buffer: None,
vertex_buffer2: None,
textures: vec![],
image_buffer_store: vec![],
compute_image: None,
swapchain: None,
swapchain_images: None
}
@ -201,7 +144,6 @@ impl<'a> VkProcessor<'a> {
pub fn compile_kernel(&mut self, filename: String) {
self.compute_kernel = Some(ComputeKernel::new(filename, self.device.clone()));
self.compute_pipeline = Some(self.compute_kernel.clone().unwrap().get_pipeline());
}
pub fn compile_shaders(&mut self, filename: String, surface: &'a Arc<Surface<Window>>) {
@ -323,40 +265,6 @@ impl<'a> VkProcessor<'a> {
{
self.load_compute_image(image_filename.clone());
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.clone()));
let img = image::open(compute_path).expect("Couldn't find image");
self.xy = img.dimensions();
let data_length = self.xy.0 * self.xy.1 * 4;
let pixel_count = img.raw_pixels().len();
println!("Pixel count {}", pixel_count);
if pixel_count != data_length as usize {
println!("Creating apha channel...");
for i in img.raw_pixels().iter() {
if (self.image_buffer.len() + 1) % 4 == 0 {
self.image_buffer.push(255);
}
self.image_buffer.push(*i);
}
self.image_buffer.push(255);
} else {
self.image_buffer = img.raw_pixels();
}
println!("Buffer length {}", self.image_buffer.len());
println!("Size {:?}", self.xy);
println!("Allocating Buffers...");
let color = [1.,0.,0.,0.];
let vertex_buffer = {
@ -399,7 +307,7 @@ impl<'a> VkProcessor<'a> {
let o : Box<DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), 0
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()
@ -416,7 +324,7 @@ impl<'a> VkProcessor<'a> {
let o : Box<DescriptorSet + Send + Sync> = Box::new(
PersistentDescriptorSet::start(
self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), 0
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()
@ -473,14 +381,16 @@ impl<'a> VkProcessor<'a> {
let mut v2 = Vec::new();
v2.push(self.vertex_buffer2.clone().unwrap().clone());
let xy = self.compute_image.clone().unwrap().get_size();
let command_buffer =
AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family())
.unwrap()
.dispatch([self.xy.0, self.xy.1, 1],
self.compute_pipeline.clone().unwrap().clone(),
self.compute_image.clone().unwrap().clone().get_descriptor_set(self.compute_pipeline.clone().unwrap().clone()).clone(), ()).unwrap()
//self.compute_set.clone().unwrap().clone(), ()).unwrap()
.dispatch([xy.0, xy.1, 1],
self.compute_kernel.clone().unwrap().clone().get_pipeline(),
self.compute_image.clone().unwrap().clone()
.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()
@ -488,12 +398,12 @@ impl<'a> VkProcessor<'a> {
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
.unwrap()
.draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
.draw(self.shader_kernels.clone().unwrap().get_pipeline(),
&self.dynamic_state.clone(), v,
vec![self.get_image_set()], ())
.unwrap()
.draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
.draw(self.shader_kernels.clone().unwrap().get_pipeline(),
&self.dynamic_state.clone(), v2,
vec![self.get_gui_image_set()], ())
.unwrap()

@ -37,9 +37,19 @@ use vulkano::format::Format;
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
use image::flat::NormalForm::ColumnMajorPacked;
use image::Rgba;
use crate::vkprocessor::SimpleSpecializationConstants;
use crate::vertex_2d::ColoredVertex2D;
/*
Compute Image holds read write swap and settings buffers for the kernel
This is a pretty specific use case. One in for settings. One in for data, two for the transfer.
multiple data inputs might be nice?
*/
#[derive(Clone)]
pub struct ComputeImage {
@ -47,10 +57,6 @@ pub struct ComputeImage {
compute_graphics_swap_buffer: std::sync::Arc<vulkano::image::attachment::AttachmentImage>,
image_buffer: Vec<u8>,
xy: (u32, u32),
pub rw_buffers: Vec<Arc<CpuAccessibleBuffer<[u8]>>>,
pub settings_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
}
@ -142,8 +148,7 @@ impl ComputeImage {
ComputeImage{
device: device.clone(),
compute_graphics_swap_buffer: compute_graphics_swap_buffer.unwrap(),
image_buffer: image_buffer,
xy: xy,
rw_buffers: vec![write_buffer, read_buffer],
settings_buffer: settings_buffer
}
@ -153,14 +158,21 @@ impl ComputeImage {
self.compute_graphics_swap_buffer.clone()
}
pub fn get_size(&self) -> (u32, u32) {
let xy = self.compute_graphics_swap_buffer.dimensions();
(xy[0], xy[1])
}
pub fn read_read_buffer(&self) -> ImageBuffer<Rgba<u8>, Vec<u8>>{
let xy = self.get_size();
let data_buffer_content = self.rw_buffers.get(0).unwrap().read().unwrap();
ImageBuffer::from_fn(self.xy.0, self.xy.1, |x, y| {
let r = data_buffer_content[((self.xy.0 * y + x) * 4 + 0) as usize] as u8;
let g = data_buffer_content[((self.xy.0 * y + x) * 4 + 1) as usize] as u8;
let b = data_buffer_content[((self.xy.0 * y + x) * 4 + 2) as usize] as u8;
let a = data_buffer_content[((self.xy.0 * y + x) * 4 + 3) as usize] as u8;
ImageBuffer::from_fn(xy.0, xy.1, |x, y| {
let r = data_buffer_content[((xy.0 * y + x) * 4 + 0) as usize] as u8;
let g = data_buffer_content[((xy.0 * y + x) * 4 + 1) as usize] as u8;
let b = data_buffer_content[((xy.0 * y + x) * 4 + 2) as usize] as u8;
let a = data_buffer_content[((xy.0 * y + x) * 4 + 3) as usize] as u8;
image::Rgba([r, g, b, a])
})

@ -36,7 +36,7 @@ use vulkano::image::{Dimensions, ImageUsage};
use vulkano::format::Format;
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
use image::flat::NormalForm::ColumnMajorPacked;
use crate::vkprocessor::SimpleSpecializationConstants;
#[derive(Clone)]
pub struct ComputeKernel {
@ -48,7 +48,7 @@ pub struct ComputeKernel {
entry: Entry,
shader_module: Arc<ShaderModule>,
device: Arc<Device>,
specialization_constants: SimpleSpecializationConstants,
specialization_constants: ComputeSpecializationConstants,
}
impl ComputeKernel {
@ -90,7 +90,7 @@ impl ComputeKernel {
compute_kernel_path: compute_path,
entry: entry,
shader_module: shader_module,
specialization_constants: SimpleSpecializationConstants {
specialization_constants: ComputeSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0
@ -141,3 +141,35 @@ impl ComputeKernel {
}
}
#[repr(C)]
#[derive(Default, Debug, Clone)]
struct ComputeSpecializationConstants {
first_constant: i32,
second_constant: u32,
third_constant: f32,
}
unsafe impl SpecializationConstants for ComputeSpecializationConstants {
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
}
}

@ -36,27 +36,21 @@ use vulkano::image::{Dimensions, ImageUsage};
use vulkano::format::Format;
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
use image::flat::NormalForm::ColumnMajorPacked;
use crate::vkprocessor::SimpleSpecializationConstants;
use crate::vertex_2d::ColoredVertex2D;
struct EntryPoint<'a> {
compiled_shaders: CompiledShaders,
frag_entry_point: Option<GraphicsEntryPoint<'a, SimpleSpecializationConstants, FragInput, FragOutput, FragLayout>>,
vertex_entry_point: Option<GraphicsEntryPoint<'a, SimpleSpecializationConstants, VertInput, VertOutput, VertLayout>>,
vertex_shader_module: Arc<ShaderModule>,
fragment_shader_module: Arc<ShaderModule>,
}
/*
Shaderkernel holds the pipeline and render pass for the inputted shader source
*/
#[derive(Clone)]
pub struct ShaderKernels {
// pub swapchain : Arc<Swapchain<Window>>,
// pub swapchain_images: Vec<Arc<SwapchainImage<Window>>>, // Surface which is drawn to
pub render_pass: Arc<RenderPassAbstract + Send + Sync>,
pub graphics_pipeline: Option<Arc<GraphicsPipelineAbstract + Sync + Send>>,
graphics_pipeline: Option<Arc<GraphicsPipelineAbstract + Sync + Send>>,
device: Arc<Device>,
}
impl ShaderKernels {
@ -82,74 +76,15 @@ impl ShaderKernels {
}
pub fn get_pipeline(&mut self) -> Arc<GraphicsPipelineAbstract + Sync + Send> {
match self.graphics_pipeline.clone() {
Some(t) => t,
None => {
// TODO: Create new graphics pipeline
self.graphics_pipeline.clone().unwrap()
}
}
self.graphics_pipeline.clone().unwrap()
}
// On resizes we have to recreate the swapchain
// pub fn recreate_swapchain(mut self, surface: &Arc<Surface<Window>>) -> Self {
// 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]
// } else {
// return self;
// };
//
// let (new_swapchain, new_images) = match self.swapchain.clone().recreate_with_dimension(dimensions) {
// Ok(r) => r,
// // This error tends to happen when the user is manually resizing the window.
// // Simply restarting the loop is the easiest way to fix this issue.
// Err(SwapchainCreationError::UnsupportedDimensions) => panic!("Uh oh"),
// Err(err) => panic!("{:?}", err)
// };
//
// self.swapchain = new_swapchain;
// self.swapchain_images = new_images;
// self
// }
pub fn new(filename: String,
surface: &Arc<Surface<Window>>,
queue: Arc<Queue>,
physical: PhysicalDevice,
device: Arc<Device>) -> ShaderKernels {
// let (mut swapchain, images) = {
// let capabilities = surface.capabilities(physical).unwrap();
// let usage = capabilities.supported_usage_flags;
// let alpha = capabilities.supported_composite_alpha.iter().next().unwrap();
// // Choosing the internal format that the images will have.
// let format = capabilities.supported_formats[0].0;
//
// // Set the swapchains window dimensions
// let initial_dimensions = if let Some(dimensions) = surface.window().get_inner_size() {
// // convert to physical pixels
// let dimensions: (u32, u32) = dimensions.to_physical(surface.window().get_hidpi_factor()).into();
// [dimensions.0, dimensions.1]
// } else {
// // The window no longer exists so exit the application.
// panic!("window closed");
// };
//
// Swapchain::new(device.clone(),
// surface.clone(),
// capabilities.min_image_count,
// format,
// initial_dimensions,
// 1, // Layers
// usage,
// &queue,
// SurfaceTransform::Identity,
// alpha,
// PresentMode::Fifo, true, None).unwrap()
// };
let capabilities = surface.capabilities(physical).unwrap();
let format = capabilities.supported_formats[0].0;
@ -225,33 +160,23 @@ impl ShaderKernels {
).unwrap());
ShaderKernels {
// swapchain: swapchain,
// swapchain_images: images,
//physical: physical,
//options: CompileOptions::new().ok_or(CompileError::CreateCompiler).unwrap(),
graphics_pipeline: Some(Arc::new(GraphicsPipeline::start()
// We need to indicate the layout of the vertices.
// The type `SingleBufferDefinition` actually contains a template parameter corresponding
// to the type of each vertex. But in this code it is automatically inferred.
.vertex_input_single_buffer::<ColoredVertex2D>()
// A Vulkan shader can in theory contain multiple entry points, so we have to specify
// which one. The `main` word of `main_entry_point` actually corresponds to the name of
// the entry point.
.vertex_shader(vertex_entry_point.clone().unwrap(), SimpleSpecializationConstants {
.vertex_shader(vertex_entry_point.clone().unwrap(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
})
// The content of the vertex buffer describes a list of triangles.
.triangle_fan()
// Use a resizable viewport set to draw over the entire window
.viewports_dynamic_scissors_irrelevant(1)
// See `vertex_shader`.
.fragment_shader(frag_entry_point.clone().unwrap(), SimpleSpecializationConstants {
.fragment_shader(frag_entry_point.clone().unwrap(), ShaderSpecializationConstants {
first_constant: 0,
second_constant: 0,
third_constant: 0.0,
@ -259,7 +184,7 @@ impl ShaderKernels {
// 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())
// Now that our builder is filled, we call `build()` to obtain an actual pipeline.
.build(device.clone())
.unwrap())),
@ -268,4 +193,37 @@ impl ShaderKernels {
}
}
}
#[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
}
}
Loading…
Cancel
Save