added compute kernel helper
This commit is contained in:
19
src/main.rs
19
src/main.rs
@@ -56,7 +56,26 @@ mod util;
|
|||||||
mod button;
|
mod button;
|
||||||
mod workpiece;
|
mod workpiece;
|
||||||
|
|
||||||
|
|
||||||
|
//struct Sprite {
|
||||||
|
// pub texture:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
How the F am I going to do sprites?
|
||||||
|
|
||||||
|
I need sprites for the slider and buttons at least
|
||||||
|
|
||||||
|
The background + render of the toolpath can probably just be straight up hand manipulated textures
|
||||||
|
|
||||||
|
Sprite will have 4 verticies and a texture along with position and size attributes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use image::{DynamicImage, ImageBuffer};
|
|||||||
use image::GenericImageView;
|
use image::GenericImageView;
|
||||||
use vulkano::descriptor::pipeline_layout::PipelineLayout;
|
use vulkano::descriptor::pipeline_layout::PipelineLayout;
|
||||||
use image::GenericImage;
|
use image::GenericImage;
|
||||||
use shade_runner::{ComputeLayout, CompileError, FragLayout, FragInput, FragOutput, VertInput, VertOutput, VertLayout};
|
use shade_runner::{ComputeLayout, CompileError, FragLayout, FragInput, FragOutput, VertInput, VertOutput, VertLayout, CompiledShaders, Entry};
|
||||||
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, PersistentDescriptorSetImg, PersistentDescriptorSetSampler};
|
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSetBuf, PersistentDescriptorSetImg, PersistentDescriptorSetSampler};
|
||||||
use shaderc::CompileOptions;
|
use shaderc::CompileOptions;
|
||||||
use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
|
use vulkano::framebuffer::{Subpass, RenderPass, RenderPassAbstract, Framebuffer, FramebufferAbstract};
|
||||||
@@ -35,6 +35,10 @@ use vulkano::image::attachment::AttachmentImage;
|
|||||||
use vulkano::image::{Dimensions, ImageUsage};
|
use vulkano::image::{Dimensions, ImageUsage};
|
||||||
use vulkano::format::Format;
|
use vulkano::format::Format;
|
||||||
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
|
use vulkano::sampler::{Sampler, Filter, MipmapMode, SamplerAddressMode};
|
||||||
|
use image::flat::NormalForm::ColumnMajorPacked;
|
||||||
|
|
||||||
|
mod compute_kernel;
|
||||||
|
use crate::vkprocessor::compute_kernel::ComputeKernel;
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
struct tVertex { position: [f32; 2] }
|
struct tVertex { position: [f32; 2] }
|
||||||
@@ -64,13 +68,14 @@ fn window_size_dependent_setup(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct MySpecConstants {
|
#[derive(Clone)]
|
||||||
my_integer_constant: i32,
|
struct SimpleSpecializationConstants {
|
||||||
a_boolean: u32,
|
first_constant: i32,
|
||||||
floating_point: f32,
|
second_constant: u32,
|
||||||
|
third_constant: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SpecializationConstants for MySpecConstants {
|
unsafe impl SpecializationConstants for SimpleSpecializationConstants {
|
||||||
fn descriptors() -> &'static [SpecializationMapEntry] {
|
fn descriptors() -> &'static [SpecializationMapEntry] {
|
||||||
static DESCRIPTORS: [SpecializationMapEntry; 3] = [
|
static DESCRIPTORS: [SpecializationMapEntry; 3] = [
|
||||||
SpecializationMapEntry {
|
SpecializationMapEntry {
|
||||||
@@ -96,6 +101,9 @@ unsafe impl SpecializationConstants for MySpecConstants {
|
|||||||
|
|
||||||
|
|
||||||
pub struct VkProcessor<'a> {
|
pub struct VkProcessor<'a> {
|
||||||
|
pub compute_kernel: Option<ComputeKernel>,
|
||||||
|
pub vertex_shader_path: PathBuf,
|
||||||
|
pub fragment_shader_path: PathBuf,
|
||||||
pub instance: Arc<Instance>,
|
pub instance: Arc<Instance>,
|
||||||
pub physical: PhysicalDevice<'a>,
|
pub physical: PhysicalDevice<'a>,
|
||||||
pub graphics_pipeline: Option<Arc<GraphicsPipelineAbstract + Sync + Send>>,
|
pub graphics_pipeline: Option<Arc<GraphicsPipelineAbstract + Sync + Send>>,
|
||||||
@@ -107,7 +115,7 @@ pub struct VkProcessor<'a> {
|
|||||||
pub img_set: Option<Arc<PersistentDescriptorSet<Arc<dyn GraphicsPipelineAbstract + Send + Sync>, ((((), PersistentDescriptorSetImg<Arc<ImmutableImage<Format>>>), PersistentDescriptorSetSampler), PersistentDescriptorSetImg<Arc<AttachmentImage>>)>>>,
|
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 graphics_image_buffer: Option<Arc<ImmutableImage<Format>>>,
|
||||||
pub image_buffer: Vec<u8>,
|
pub image_buffer: Vec<u8>,
|
||||||
pub img_buffers: Vec<Arc<CpuAccessibleBuffer<[u8]>>>,
|
pub compute_image_buffers: Vec<Arc<CpuAccessibleBuffer<[u8]>>>,
|
||||||
pub settings_buffer: Option<Arc<CpuAccessibleBuffer<[u32]>>>,
|
pub settings_buffer: Option<Arc<CpuAccessibleBuffer<[u32]>>>,
|
||||||
pub swapchain: Option<Arc<Swapchain<Window>>>,
|
pub swapchain: Option<Arc<Swapchain<Window>>>,
|
||||||
pub images: Option<Vec<Arc<SwapchainImage<Window>>>>,
|
pub images: Option<Vec<Arc<SwapchainImage<Window>>>>,
|
||||||
@@ -115,7 +123,7 @@ pub struct VkProcessor<'a> {
|
|||||||
pub render_pass: Option<Arc<RenderPassAbstract + Send + Sync>>,
|
pub render_pass: Option<Arc<RenderPassAbstract + Send + Sync>>,
|
||||||
pub vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
|
pub vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
|
||||||
pub dynamic_state: DynamicState,
|
pub dynamic_state: DynamicState,
|
||||||
pub graphics_iamge_swap_buffer: Option<std::sync::Arc<vulkano::image::attachment::AttachmentImage>>,
|
pub graphics_image_swap_buffer: Option<std::sync::Arc<vulkano::image::attachment::AttachmentImage>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +148,9 @@ impl<'a> VkProcessor<'a> {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
VkProcessor {
|
VkProcessor {
|
||||||
|
compute_kernel: Option::None,
|
||||||
|
vertex_shader_path: Default::default(),
|
||||||
|
fragment_shader_path: Default::default(),
|
||||||
instance: instance.clone(),
|
instance: instance.clone(),
|
||||||
physical: physical.clone(),
|
physical: physical.clone(),
|
||||||
graphics_pipeline: Option::None,
|
graphics_pipeline: Option::None,
|
||||||
@@ -151,7 +162,7 @@ impl<'a> VkProcessor<'a> {
|
|||||||
img_set: Option::None,
|
img_set: Option::None,
|
||||||
graphics_image_buffer: None,
|
graphics_image_buffer: None,
|
||||||
image_buffer: Vec::new(),
|
image_buffer: Vec::new(),
|
||||||
img_buffers: Vec::new(),
|
compute_image_buffers: Vec::new(),
|
||||||
settings_buffer: Option::None,
|
settings_buffer: Option::None,
|
||||||
swapchain: Option::None,
|
swapchain: Option::None,
|
||||||
images: Option::None,
|
images: Option::None,
|
||||||
@@ -159,49 +170,18 @@ impl<'a> VkProcessor<'a> {
|
|||||||
render_pass: Option::None,
|
render_pass: Option::None,
|
||||||
vertex_buffer: Option::None,
|
vertex_buffer: Option::None,
|
||||||
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
|
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
|
||||||
graphics_iamge_swap_buffer: None,
|
graphics_image_swap_buffer: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn compile_kernel(&mut self, filename: String) {
|
pub fn compile_kernel(&mut self, filename: String) {
|
||||||
let project_root =
|
|
||||||
std::env::current_dir()
|
|
||||||
.expect("failed to get root directory");
|
|
||||||
|
|
||||||
let mut compute_path = project_root.clone();
|
self.compute_kernel = Some(ComputeKernel::new(filename, self.device.clone()));
|
||||||
compute_path.push(PathBuf::from("resources/shaders/"));
|
self.compute_pipeline = Some(self.compute_kernel.clone().unwrap().get_pipeline());
|
||||||
compute_path.push(PathBuf::from(filename));
|
|
||||||
|
|
||||||
|
|
||||||
let mut options = CompileOptions::new().ok_or(CompileError::CreateCompiler).unwrap();
|
|
||||||
options.add_macro_definition("SETTING_POS_X", Some("0"));
|
|
||||||
options.add_macro_definition("SETTING_POS_Y", Some("1"));
|
|
||||||
options.add_macro_definition("SETTING_BUCKETS_START", Some("2"));
|
|
||||||
options.add_macro_definition("SETTING_BUCKETS_LEN", Some("2"));
|
|
||||||
|
|
||||||
let shader =
|
|
||||||
sr::load_compute_with_options(compute_path, options)
|
|
||||||
.expect("Failed to compile");
|
|
||||||
|
|
||||||
let vulkano_entry =
|
|
||||||
sr::parse_compute(&shader)
|
|
||||||
.expect("failed to parse");
|
|
||||||
|
|
||||||
let x = unsafe {
|
|
||||||
vulkano::pipeline::shader::ShaderModule::from_words(self.device.clone(), &shader.compute)
|
|
||||||
}.unwrap();
|
|
||||||
|
|
||||||
let compute_pipeline = Arc::new({
|
|
||||||
unsafe {
|
|
||||||
ComputePipeline::new(self.device.clone(), &x.compute_entry_point(
|
|
||||||
CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
|
||||||
vulkano_entry.compute_layout), &(),
|
|
||||||
).unwrap()
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
self.compute_pipeline = Some(compute_pipeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
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>>) {
|
||||||
|
|
||||||
@@ -262,16 +242,9 @@ impl<'a> VkProcessor<'a> {
|
|||||||
options.add_macro_definition("SETTING_BUCKETS_START", Some("2"));
|
options.add_macro_definition("SETTING_BUCKETS_START", Some("2"));
|
||||||
options.add_macro_definition("SETTING_BUCKETS_LEN", Some("2"));
|
options.add_macro_definition("SETTING_BUCKETS_LEN", Some("2"));
|
||||||
|
|
||||||
let shader = sr::load(vertex_shader_path, fragment_shader_path).expect("");
|
// TODO: better compile message, run til successful compile
|
||||||
// let shader = match sr::load(vertex_shader_path, fragment_shader_path) {
|
let shader = sr::load(vertex_shader_path, fragment_shader_path)
|
||||||
// Ok(t) => t,
|
.expect("Shader didn't compile");
|
||||||
// Err(e) => {
|
|
||||||
//
|
|
||||||
// panic!(e);
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let vulkano_entry =
|
let vulkano_entry =
|
||||||
sr::parse(&shader)
|
sr::parse(&shader)
|
||||||
@@ -285,7 +258,7 @@ impl<'a> VkProcessor<'a> {
|
|||||||
vulkano::pipeline::shader::ShaderModule::from_words(self.device.clone(), &shader.vertex)
|
vulkano::pipeline::shader::ShaderModule::from_words(self.device.clone(), &shader.vertex)
|
||||||
}.unwrap();
|
}.unwrap();
|
||||||
|
|
||||||
let frag_entry_point: GraphicsEntryPoint<MySpecConstants, FragInput, FragOutput, FragLayout> = unsafe {
|
let frag_entry_point: GraphicsEntryPoint<SimpleSpecializationConstants, FragInput, FragOutput, FragLayout> = unsafe {
|
||||||
x1.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
x1.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
||||||
vulkano_entry.frag_input,
|
vulkano_entry.frag_input,
|
||||||
vulkano_entry.frag_output,
|
vulkano_entry.frag_output,
|
||||||
@@ -293,7 +266,7 @@ impl<'a> VkProcessor<'a> {
|
|||||||
GraphicsShaderType::Fragment)
|
GraphicsShaderType::Fragment)
|
||||||
};
|
};
|
||||||
|
|
||||||
let vert_entry_point: GraphicsEntryPoint<MySpecConstants, VertInput, VertOutput, VertLayout> = unsafe {
|
let vert_entry_point: GraphicsEntryPoint<SimpleSpecializationConstants, VertInput, VertOutput, VertLayout> = unsafe {
|
||||||
x2.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
x2.graphics_entry_point(CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
||||||
vulkano_entry.vert_input,
|
vulkano_entry.vert_input,
|
||||||
vulkano_entry.vert_output,
|
vulkano_entry.vert_output,
|
||||||
@@ -345,20 +318,20 @@ impl<'a> VkProcessor<'a> {
|
|||||||
// A Vulkan shader can in theory contain multiple entry points, so we have to specify
|
// 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
|
// which one. The `main` word of `main_entry_point` actually corresponds to the name of
|
||||||
// the entry point.
|
// the entry point.
|
||||||
.vertex_shader(vert_entry_point, MySpecConstants {
|
.vertex_shader(vert_entry_point, SimpleSpecializationConstants {
|
||||||
my_integer_constant: 0,
|
first_constant: 0,
|
||||||
a_boolean: 0,
|
second_constant: 0,
|
||||||
floating_point: 0.0,
|
third_constant: 0.0,
|
||||||
})
|
})
|
||||||
// The content of the vertex buffer describes a list of triangles.
|
// The content of the vertex buffer describes a list of triangles.
|
||||||
.triangle_fan()
|
.triangle_fan()
|
||||||
// Use a resizable viewport set to draw over the entire window
|
// Use a resizable viewport set to draw over the entire window
|
||||||
.viewports_dynamic_scissors_irrelevant(1)
|
.viewports_dynamic_scissors_irrelevant(1)
|
||||||
// See `vertex_shader`.
|
// See `vertex_shader`.
|
||||||
.fragment_shader(frag_entry_point, MySpecConstants {
|
.fragment_shader(frag_entry_point, SimpleSpecializationConstants {
|
||||||
my_integer_constant: 0,
|
first_constant: 0,
|
||||||
a_boolean: 0,
|
second_constant: 0,
|
||||||
floating_point: 0.0,
|
third_constant: 0.0,
|
||||||
})
|
})
|
||||||
// We have to indicate which subpass of which render pass this pipeline is going to be used
|
// 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.
|
// in. The pipeline will only be usable from this particular subpass.
|
||||||
@@ -467,8 +440,8 @@ impl<'a> VkProcessor<'a> {
|
|||||||
|
|
||||||
self.compute_set = Some(Arc::new(set.build().unwrap()));
|
self.compute_set = Some(Arc::new(set.build().unwrap()));
|
||||||
|
|
||||||
self.img_buffers.push(write_buffer);
|
self.compute_image_buffers.push(write_buffer);
|
||||||
self.img_buffers.push(read_buffer);
|
self.compute_image_buffers.push(read_buffer);
|
||||||
self.settings_buffer = Some(settings_buffer);
|
self.settings_buffer = Some(settings_buffer);
|
||||||
|
|
||||||
|
|
||||||
@@ -493,9 +466,6 @@ impl<'a> VkProcessor<'a> {
|
|||||||
Dimensions::Dim2d { width: self.xy.0, height: self.xy.1 },
|
Dimensions::Dim2d { width: self.xy.0, height: self.xy.1 },
|
||||||
Format::R8G8B8A8Srgb,
|
Format::R8G8B8A8Srgb,
|
||||||
self.queue.clone()
|
self.queue.clone()
|
||||||
// self.image_buffer.iter().cloned(),
|
|
||||||
// Format::R8G8B8A8Uint,
|
|
||||||
|
|
||||||
).unwrap()
|
).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -516,14 +486,13 @@ impl<'a> VkProcessor<'a> {
|
|||||||
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
|
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
|
||||||
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
|
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
|
||||||
|
|
||||||
|
|
||||||
self.img_set = Some(Arc::new(PersistentDescriptorSet::start(self.graphics_pipeline.clone().unwrap().clone(), 0)
|
self.img_set = Some(Arc::new(PersistentDescriptorSet::start(self.graphics_pipeline.clone().unwrap().clone(), 0)
|
||||||
.add_sampled_image(texture.clone(), sampler.clone()).unwrap()
|
.add_sampled_image(texture.clone(), sampler.clone()).unwrap()
|
||||||
.add_image(attachment_image.clone().unwrap().clone()).unwrap()
|
.add_image(attachment_image.clone().unwrap().clone()).unwrap()
|
||||||
.build().unwrap()));
|
.build().unwrap()));
|
||||||
|
|
||||||
self.graphics_image_buffer = Some(texture.clone());
|
self.graphics_image_buffer = Some(texture.clone());
|
||||||
self.graphics_iamge_swap_buffer = Some(attachment_image.clone().unwrap());
|
self.graphics_image_swap_buffer = Some(attachment_image.clone().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, surface: &'a Arc<Surface<Window>>, mut frame_future: Box<dyn GpuFuture>) -> Box<dyn GpuFuture> {
|
pub fn run(&mut self, surface: &'a Arc<Surface<Window>>, mut frame_future: Box<dyn GpuFuture>) -> Box<dyn GpuFuture> {
|
||||||
@@ -585,8 +554,8 @@ impl<'a> VkProcessor<'a> {
|
|||||||
self.compute_pipeline.clone().unwrap().clone(),
|
self.compute_pipeline.clone().unwrap().clone(),
|
||||||
self.compute_set.clone().unwrap().clone(), ()).unwrap()
|
self.compute_set.clone().unwrap().clone(), ()).unwrap()
|
||||||
|
|
||||||
.copy_buffer_to_image(self.img_buffers.get(0).unwrap().clone(),
|
.copy_buffer_to_image(self.compute_image_buffers.get(0).unwrap().clone(),
|
||||||
self.graphics_iamge_swap_buffer.clone().unwrap()).unwrap()
|
self.graphics_image_swap_buffer.clone().unwrap()).unwrap()
|
||||||
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
|
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
||||||
@@ -600,7 +569,7 @@ impl<'a> VkProcessor<'a> {
|
|||||||
|
|
||||||
.build().unwrap();
|
.build().unwrap();
|
||||||
|
|
||||||
let mut data_buffer_content = self.img_buffers.get(0).unwrap().read().unwrap();
|
let mut data_buffer_content = self.compute_image_buffers.get(0).unwrap().read().unwrap();
|
||||||
let img = ImageBuffer::from_fn(self.xy.0, self.xy.1, |x, y| {
|
let img = 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 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 g = data_buffer_content[((self.xy.0 * y + x) * 4 + 1) as usize] as u8;
|
||||||
|
|||||||
143
src/vkprocessor/compute_kernel.rs
Normal file
143
src/vkprocessor/compute_kernel.rs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess};
|
||||||
|
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
|
||||||
|
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, StdDescriptorPoolAlloc};
|
||||||
|
use vulkano::device::{Device, DeviceExtensions, QueuesIter, Queue};
|
||||||
|
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice, QueueFamily};
|
||||||
|
use vulkano::pipeline::{ComputePipeline, GraphicsPipeline, GraphicsPipelineAbstract};
|
||||||
|
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};
|
||||||
|
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;
|
||||||
|
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};
|
||||||
|
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 {
|
||||||
|
|
||||||
|
compute_pipeline: Option<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>>,
|
||||||
|
compute_kernel_path: PathBuf,
|
||||||
|
|
||||||
|
shader: CompiledShaders,
|
||||||
|
entry: Entry,
|
||||||
|
shader_module: Arc<ShaderModule>,
|
||||||
|
device: Arc<Device>,
|
||||||
|
specialization_constants: SimpleSpecializationConstants,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComputeKernel {
|
||||||
|
|
||||||
|
fn get_path(filename: String) -> PathBuf {
|
||||||
|
|
||||||
|
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/shaders/"));
|
||||||
|
compute_path.push(PathBuf::from(filename));
|
||||||
|
|
||||||
|
compute_path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(filename: String, device: Arc<Device>) -> ComputeKernel {
|
||||||
|
|
||||||
|
let compute_path = ComputeKernel::get_path(filename);
|
||||||
|
|
||||||
|
let mut options = CompileOptions::new().ok_or(CompileError::CreateCompiler).unwrap();
|
||||||
|
|
||||||
|
let shader = sr::load_compute_with_options(compute_path.clone(), options)
|
||||||
|
.expect("Failed to compile");
|
||||||
|
|
||||||
|
let entry = sr::parse_compute(&shader)
|
||||||
|
.expect("Failed to parse");
|
||||||
|
|
||||||
|
let shader_module = unsafe {
|
||||||
|
vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader.compute)
|
||||||
|
}.unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
ComputeKernel {
|
||||||
|
device: device,
|
||||||
|
shader: shader,
|
||||||
|
compute_pipeline: Option::None,
|
||||||
|
compute_kernel_path: compute_path,
|
||||||
|
entry: entry,
|
||||||
|
shader_module: shader_module,
|
||||||
|
specialization_constants: SimpleSpecializationConstants {
|
||||||
|
first_constant: 0,
|
||||||
|
second_constant: 0,
|
||||||
|
third_constant: 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_pipeline(&mut self) -> std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>> {
|
||||||
|
|
||||||
|
match self.compute_pipeline.clone() {
|
||||||
|
Some(t) => t,
|
||||||
|
None => {
|
||||||
|
self.compute_pipeline = Some(Arc::new({
|
||||||
|
unsafe {
|
||||||
|
ComputePipeline::new(self.device.clone(), &self.shader_module.compute_entry_point(
|
||||||
|
CStr::from_bytes_with_nul_unchecked(b"main\0"),
|
||||||
|
self.entry.compute_layout.clone()), &self.specialization_constants,
|
||||||
|
).unwrap()
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
self.compute_pipeline.clone().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recompile_kernel(&mut self) {
|
||||||
|
self.compile_kernel(String::from(self.compute_kernel_path.clone().to_str().unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compile_kernel(&mut self, filename: String) -> std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>> {
|
||||||
|
|
||||||
|
let mut options = CompileOptions::new().ok_or(CompileError::CreateCompiler).unwrap();
|
||||||
|
self.compute_kernel_path = ComputeKernel::get_path(filename);
|
||||||
|
|
||||||
|
self.shader =
|
||||||
|
sr::load_compute_with_options(self.compute_kernel_path.clone(), options)
|
||||||
|
.expect("Failed to compile");
|
||||||
|
|
||||||
|
self.entry =
|
||||||
|
sr::parse_compute(&self.shader)
|
||||||
|
.expect("Failed to parse");
|
||||||
|
|
||||||
|
self.shader_module = unsafe {
|
||||||
|
vulkano::pipeline::shader::ShaderModule::from_words(self.device.clone(), &self.shader.compute)
|
||||||
|
}.unwrap();
|
||||||
|
|
||||||
|
self.get_pipeline()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user