Got the compute thing going. Needs to be run before the rasterizer but that's fine

master
mitchellhansen 6 years ago
parent 751b7641b2
commit d6b81ae468

@ -11,13 +11,13 @@ simple-stopwatch="0.1.4"
nalgebra = "0.18.0" nalgebra = "0.18.0"
image = "0.21.2" image = "0.21.2"
rand = "0.6.5" rand = "0.6.5"
#vulkano = "0.12.0" vulkano = "0.13.0"
vulkano = {path = "../vulkano/vulkano"} #vulkano = {path = "../vulkano/vulkano"}
#vulkano-shaders = "0.12.0" vulkano-shaders = "0.13.0"
#vulkano-win = "0.13.0" vulkano-win = "0.13.0"
time = "0.1.38" time = "0.1.38"
shaderc = "0.5.0" shaderc = "0.5.0"
#shade_runner = {version = "0.1.1", git = "https://github.com/MitchellHansen/shade_runner"} shade_runner = {version = "0.1.1", git = "https://github.com/MitchellHansen/shade_runner"}
shade_runner = {path = "../shade_runner"} #shade_runner = {path = "../shade_runner"}
winit = "0.19.1" winit = "0.19.1"

@ -3,6 +3,8 @@
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow(unused_mut)] #![allow(unused_mut)]
/*
extern crate cgmath; extern crate cgmath;
extern crate image; extern crate image;
extern crate nalgebra as na; extern crate nalgebra as na;
@ -58,7 +60,6 @@ What next?
Second sprite for rendering paths at x10 or so resolution Second sprite for rendering paths at x10 or so resolution
color bucketing color bucketing
Textures and Sprites cannot live in the same struct as there is no way for a sprite to own Textures and Sprites cannot live in the same struct as there is no way for a sprite to own
its texture and become a single object (rust self-referencing structs) its texture and become a single object (rust self-referencing structs)
@ -81,8 +82,6 @@ frequent updates to the screen...
Let's take a look at how easy it would be to replace SFML... Let's take a look at how easy it would be to replace SFML...
*/ */
fn main() { fn main() {
let font = Font::from_file("resources/fonts/sansation.ttf").unwrap(); let font = Font::from_file("resources/fonts/sansation.ttf").unwrap();
@ -206,13 +205,12 @@ fn main() {
window.display(); window.display();
} }
} }
*/
/*
//use vulkano::buffer::{BufferAccess, BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer}; //use vulkano::buffer::{BufferAccess, BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer};
//use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; //use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
//use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, PersistentDescriptorSetBuf, StdDescriptorPoolAlloc}; //use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, PersistentDescriptorSetBuf, StdDescriptorPoolAlloc};
@ -553,7 +551,7 @@ void main() {
vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader.compute) vulkano::pipeline::shader::ShaderModule::from_words(device.clone(), &shader.compute)
}.unwrap(); }.unwrap();
let pipeline = Arc::new({ let c_pipeline = Arc::new({
unsafe { unsafe {
ComputePipeline::new(device.clone(), &x.compute_entry_point( ComputePipeline::new(device.clone(), &x.compute_entry_point(
CStr::from_bytes_with_nul_unchecked(b"main\0"), CStr::from_bytes_with_nul_unchecked(b"main\0"),
@ -561,7 +559,82 @@ void main() {
).unwrap() ).unwrap()
} }
}); });
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("funky-bird.jpg"));
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();
println!("Pixel count {}", pixel_count);
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();
}
println!("Buffer length {}", image_buffer.len());
println!("Size {:?}", xy);
println!("Allocating Buffers...");
// Pull out the image data and place it in a buffer for the kernel to write to and for us to read from
let write_buffer = {
let mut buff = image_buffer.iter();
let data_iter = (0..data_length).map(|n| *(buff.next().unwrap()));
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
};
// Pull out the image data and place it in a buffer for the kernel to read from
let read_buffer = {
let mut buff = image_buffer.iter();
let data_iter = (0..data_length).map(|n| *(buff.next().unwrap()));
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
};
// A buffer to hold many i32 values to use as settings
let settings_buffer = {
let vec = vec![xy.0, xy.1];
let mut buff = vec.iter();
let data_iter =
(0..2).map(|n| *(buff.next().unwrap()));
CpuAccessibleBuffer::from_iter(device.clone(),
BufferUsage::all(),
data_iter).unwrap()
};
println!("Done");
// Create the data descriptor set for our previously created shader pipeline
let mut set =
PersistentDescriptorSet::start(c_pipeline.clone(), 0)
.add_buffer(write_buffer.clone()).unwrap()
.add_buffer(read_buffer.clone()).unwrap()
.add_buffer(settings_buffer.clone()).unwrap();
let mut set = Arc::new(set.build().unwrap());
// In order to draw, we have to build a *command buffer*. The command buffer object holds // In order to draw, we have to build a *command buffer*. The command buffer object holds
// the list of commands that are going to be executed. // the list of commands that are going to be executed.
@ -572,7 +645,13 @@ void main() {
// //
// Note that we have to pass a queue family when we create the command buffer. The command // Note that we have to pass a queue family when we create the command buffer. The command
// buffer will only be executable on that given queue family. // buffer will only be executable on that given queue family.
let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap() let command_buffer =
AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap()
.dispatch([xy.0, xy.1, 1],
c_pipeline.clone(),
set.clone(), ()).unwrap()
// Before we can draw, we have to *enter a render pass*. There are two methods to do // Before we can draw, we have to *enter a render pass*. There are two methods to do
// this: `draw_inline` and `draw_secondary`. The latter is a bit more advanced and is // this: `draw_inline` and `draw_secondary`. The latter is a bit more advanced and is
// not covered here. // not covered here.
@ -583,6 +662,7 @@ void main() {
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values) .begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
.unwrap() .unwrap()
// We are now inside the first subpass of the render pass. We add a draw command. // We are now inside the first subpass of the render pass. We add a draw command.
// //
// The last two parameters contain the list of resources to pass to the shaders. // The last two parameters contain the list of resources to pass to the shaders.
@ -624,7 +704,7 @@ void main() {
previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
}
// Note that in more complex programs it is likely that one of `acquire_next_image`, // Note that in more complex programs it is likely that one of `acquire_next_image`,
// `command_buffer::submit`, or `present` will block for some time. This happens when the // `command_buffer::submit`, or `present` will block for some time. This happens when the
// GPU's queue is full and the driver has to wait until the GPU finished some work. // GPU's queue is full and the driver has to wait until the GPU finished some work.
@ -671,5 +751,3 @@ fn window_size_dependent_setup(
}).collect::<Vec<_>>() }).collect::<Vec<_>>()
} }
*/
Loading…
Cancel
Save