Cleanup examples (#1096)

*   replaced `.expect()` that provided no useful information with `.unwrap()`
*   used `use` consistently (all types are `use`d all functions have the parent module `use`d)
*   other formatting consistencies
This commit is contained in:
Lucas Kent 2018-10-28 14:02:29 +11:00 committed by GitHub
parent c57289f536
commit 9d46e08cc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 396 additions and 488 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
target target
/Cargo.lock /Cargo.lock
.cargo .cargo
examples/src/bin/triangle.png

View File

@ -17,17 +17,14 @@
extern crate vulkano; extern crate vulkano;
extern crate vulkano_shaders; extern crate vulkano_shaders;
use vulkano::buffer::BufferUsage; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Device; use vulkano::device::{Device, DeviceExtensions};
use vulkano::device::DeviceExtensions; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::instance::Instance;
use vulkano::instance::InstanceExtensions;
use vulkano::pipeline::ComputePipeline; use vulkano::pipeline::ComputePipeline;
use vulkano::sync::now;
use vulkano::sync::GpuFuture; use vulkano::sync::GpuFuture;
use vulkano::sync;
use std::sync::Arc; use std::sync::Arc;
@ -52,12 +49,10 @@ void main() {
fn main() { fn main() {
// As with other examples, the first step is to create an instance. // As with other examples, the first step is to create an instance.
let instance = Instance::new(None, &InstanceExtensions::none(), None) let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
.expect("failed to create Vulkan instance");
// Choose which physical device to use. // Choose which physical device to use.
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance) let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
.next().expect("no device available");
// Choose the queue of the physical device which is going to run our compute operation. // Choose the queue of the physical device which is going to run our compute operation.
// //
@ -66,10 +61,8 @@ fn main() {
let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap(); let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
// Now initializing the device. // Now initializing the device.
let (device, mut queues) = { let (device, mut queues) = Device::new(physical, physical.supported_features(),
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(), &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
// Since we can request multiple queues, the `queues` variable is in fact an iterator. In this // Since we can request multiple queues, the `queues` variable is in fact an iterator. In this
// example we use only one queue, so we just retrieve the first and only element of the // example we use only one queue, so we just retrieve the first and only element of the
@ -97,10 +90,8 @@ fn main() {
// If you are familiar with graphics pipeline, the principle is the same except that compute // If you are familiar with graphics pipeline, the principle is the same except that compute
// pipelines are much simpler to create. // pipelines are much simpler to create.
let pipeline = Arc::new({ let pipeline = Arc::new({
let shader = cs::Shader::load(device.clone()) let shader = cs::Shader::load(device.clone()).unwrap();
.expect("failed to create shader module"); ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap()
ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
.expect("failed to create compute pipeline")
}); });
// We start by creating the buffer that will store the data. // We start by creating the buffer that will store the data.
@ -108,8 +99,7 @@ fn main() {
// Iterator that produces the data. // Iterator that produces the data.
let data_iter = (0 .. 65536u32).map(|n| n); let data_iter = (0 .. 65536u32).map(|n| n);
// Builds the buffer and fills it with this iterator. // Builds the buffer and fills it with this iterator.
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
data_iter).expect("failed to create buffer")
}; };
// In order to let the shader access the buffer, we need to build a *descriptor set* that // In order to let the shader access the buffer, we need to build a *descriptor set* that
@ -140,7 +130,7 @@ fn main() {
// Let's execute this command buffer now. // Let's execute this command buffer now.
// To do so, we TODO: this is a bit clumsy, probably needs a shortcut // To do so, we TODO: this is a bit clumsy, probably needs a shortcut
let future = now(device.clone()) let future = sync::now(device.clone())
.then_execute(queue.clone(), command_buffer).unwrap() .then_execute(queue.clone(), command_buffer).unwrap()
// This line instructs the GPU to signal a *fence* once the command buffer has finished // This line instructs the GPU to signal a *fence* once the command buffer has finished
@ -166,7 +156,7 @@ fn main() {
// Now that the GPU is done, the content of the buffer should have been modified. Let's // Now that the GPU is done, the content of the buffer should have been modified. Let's
// check it out. // check it out.
// The call to `read()` would return an error if the buffer was still in use by the GPU. // The call to `read()` would return an error if the buffer was still in use by the GPU.
let data_buffer_content = data_buffer.read().expect("failed to lock buffer for reading"); let data_buffer_content = data_buffer.read().unwrap();
for n in 0 .. 65536u32 { for n in 0 .. 65536u32 {
assert_eq!(data_buffer_content[n as usize], n * 12); assert_eq!(data_buffer_content[n as usize], n * 12);
} }

View File

@ -33,18 +33,16 @@ extern crate vulkano_shaders;
extern crate winit; extern crate winit;
extern crate vulkano_win; extern crate vulkano_win;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
use vulkano::swapchain;
use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use vulkano_win::VkSurfaceBuild; use vulkano_win::VkSurfaceBuild;
use vulkano::device::Device; use winit::{EventsLoop, WindowBuilder, Event, WindowEvent};
use vulkano::instance::Instance;
use vulkano::swapchain;
use vulkano::swapchain::PresentMode;
use vulkano::swapchain::SurfaceTransform;
use vulkano::swapchain::Swapchain;
use vulkano::swapchain::AcquireError;
use vulkano::swapchain::SwapchainCreationError;
use vulkano::sync::now;
use vulkano::sync::GpuFuture;
use cgmath::Matrix4; use cgmath::Matrix4;
use cgmath::SquareMatrix; use cgmath::SquareMatrix;
@ -53,68 +51,61 @@ use cgmath::Vector3;
mod frame; mod frame;
mod triangle_draw_system; mod triangle_draw_system;
use frame::*;
use triangle_draw_system::*;
fn main() { fn main() {
// Basic initialization. See the triangle example if you want more details about this. // Basic initialization. See the triangle example if you want more details about this.
let instance = { let extensions = vulkano_win::required_extensions();
let extensions = vulkano_win::required_extensions(); let instance = Instance::new(None, &extensions, None).unwrap();
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
};
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
.next().expect("no device available");
let mut events_loop = winit::EventsLoop::new(); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let mut events_loop = EventsLoop::new();
let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let window = surface.window(); let window = surface.window();
let queue_family = physical.queue_families().find(|&q| { let queue_family = physical.queue_families().find(|&q| {
q.supports_graphics() && surface.is_supported(q).unwrap_or(false) q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
}).expect("couldn't find a graphical queue family"); }).expect("couldn't find a graphical queue family");
let (device, mut queues) = { let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
let device_ext = vulkano::device::DeviceExtensions { let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
khr_swapchain: true, [(queue_family, 0.5)].iter().cloned()).unwrap();
.. vulkano::device::DeviceExtensions::none()
};
Device::new(physical, physical.supported_features(), &device_ext,
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let mut dimensions;
let (mut swapchain, mut images) = { let (mut swapchain, mut images) = {
let caps = surface.capabilities(physical) let caps = surface.capabilities(physical).unwrap();
.expect("failed to get surface capabilities");
let dimensions = if let Some(dimensions) = window.get_inner_size() { let usage = caps.supported_usage_flags;
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0;
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
} else { } else {
return; return;
}; };
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0;
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
dimensions, 1, caps.supported_usage_flags, &queue, initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, PresentMode::Fifo, true, None).unwrap()
None).expect("failed to create swapchain")
}; };
// Here is the basic initialization for the deferred system. // Here is the basic initialization for the deferred system.
let mut frame_system = frame::FrameSystem::new(queue.clone(), swapchain.format()); let mut frame_system = FrameSystem::new(queue.clone(), swapchain.format());
let triangle_draw_system = triangle_draw_system::TriangleDrawSystem::new(queue.clone(), let triangle_draw_system = TriangleDrawSystem::new(queue.clone(), frame_system.deferred_subpass());
frame_system.deferred_subpass());
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame_end = Box::new(now(device.clone())) as Box<GpuFuture>; let mut previous_frame_end = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
loop { loop {
previous_frame_end.cleanup_finished(); previous_frame_end.cleanup_finished();
if recreate_swapchain { if recreate_swapchain {
dimensions = if let Some(dimensions) = window.get_inner_size() { let dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
} else { } else {
@ -148,18 +139,18 @@ fn main() {
let mut after_future = None; let mut after_future = None;
while let Some(pass) = frame.next_pass() { while let Some(pass) = frame.next_pass() {
match pass { match pass {
frame::Pass::Deferred(mut draw_pass) => { Pass::Deferred(mut draw_pass) => {
let cb = triangle_draw_system.draw(draw_pass.viewport_dimensions()); let cb = triangle_draw_system.draw(draw_pass.viewport_dimensions());
draw_pass.execute(cb); draw_pass.execute(cb);
} }
frame::Pass::Lighting(mut lighting) => { Pass::Lighting(mut lighting) => {
lighting.ambient_light([0.1, 0.1, 0.1]); lighting.ambient_light([0.1, 0.1, 0.1]);
lighting.directional_light(Vector3::new(0.2, -0.1, -0.7), [0.6, 0.6, 0.6]); lighting.directional_light(Vector3::new(0.2, -0.1, -0.7), [0.6, 0.6, 0.6]);
lighting.point_light(Vector3::new(0.5, -0.5, -0.1), [1.0, 0.0, 0.0]); lighting.point_light(Vector3::new(0.5, -0.5, -0.1), [1.0, 0.0, 0.0]);
lighting.point_light(Vector3::new(-0.9, 0.2, -0.15), [0.0, 1.0, 0.0]); lighting.point_light(Vector3::new(-0.9, 0.2, -0.15), [0.0, 1.0, 0.0]);
lighting.point_light(Vector3::new(0.0, 0.5, -0.05), [0.0, 0.0, 1.0]); lighting.point_light(Vector3::new(0.0, 0.5, -0.05), [0.0, 0.0, 1.0]);
} }
frame::Pass::Finished(af) => { Pass::Finished(af) => {
after_future = Some(af); after_future = Some(af);
} }
} }
@ -173,21 +164,21 @@ fn main() {
Ok(future) => { Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>; previous_frame_end = Box::new(future) as Box<_>;
} }
Err(vulkano::sync::FlushError::OutOfDate) => { Err(FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
let mut done = false; let mut done = false;
events_loop.poll_events(|ev| { events_loop.poll_events(|ev| {
match ev { match ev {
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true, Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true, Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => () _ => ()
} }
}); });

View File

@ -7,23 +7,36 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
extern crate cgmath;
extern crate image;
extern crate winit;
#[macro_use] #[macro_use]
extern crate vulkano; extern crate vulkano;
extern crate vulkano_shaders; extern crate vulkano_shaders;
extern crate vulkano_win; extern crate vulkano_win;
extern crate winit;
extern crate cgmath;
extern crate image;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::Format;
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::{SwapchainImage, ImmutableImage, Dimensions};
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::viewport::Viewport;
use vulkano::sampler::{Sampler, SamplerAddressMode, Filter, MipmapMode};
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
use vulkano::swapchain;
use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use vulkano_win::VkSurfaceBuild; use vulkano_win::VkSurfaceBuild;
use vulkano::sync::GpuFuture;
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, RenderPassAbstract};
use vulkano::command_buffer::DynamicState;
use vulkano::image::SwapchainImage;
use vulkano::pipeline::viewport::Viewport;
use winit::Window; use winit::{EventsLoop, Window, WindowBuilder, Event, WindowEvent};
use image::ImageFormat;
use std::sync::Arc; use std::sync::Arc;
@ -32,33 +45,32 @@ fn main() {
// `triangle` example if you haven't done so yet. // `triangle` example if you haven't done so yet.
let extensions = vulkano_win::required_extensions(); let extensions = vulkano_win::required_extensions();
let instance = vulkano::instance::Instance::new(None, &extensions, None).expect("failed to create instance"); let instance = Instance::new(None, &extensions, None).unwrap();
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance) let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
.next().expect("no device available");
println!("Using device: {} (type: {:?})", physical.name(), physical.ty()); println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
let mut events_loop = winit::EventsLoop::new(); let mut events_loop = EventsLoop::new();
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let window = surface.window(); let window = surface.window();
let queue_family = physical.queue_families().find(|&q| q.supports_graphics() && let queue_family = physical.queue_families().find(|&q|
surface.is_supported(q).unwrap_or(false)) q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
.expect("couldn't find a graphical queue family"); ).unwrap();
let device_ext = vulkano::device::DeviceExtensions { let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
khr_swapchain: true, let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
.. vulkano::device::DeviceExtensions::none() [(queue_family, 0.5)].iter().cloned()).unwrap();
};
let (device, mut queues) = vulkano::device::Device::new(physical, physical.supported_features(),
&device_ext, [(queue_family, 0.5)].iter().cloned())
.expect("failed to create device");
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let (mut swapchain, images) = { let (mut swapchain, images) = {
let caps = surface.capabilities(physical).expect("failed to get surface capabilities"); let caps = surface.capabilities(physical).unwrap();
let dimensions = if let Some(dimensions) = window.get_inner_size() { let usage = caps.supported_usage_flags;
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0;
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
// convert to physical pixels // convert to physical pixels
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
@ -66,15 +78,10 @@ fn main() {
// The window no longer exists so exit the application. // The window no longer exists so exit the application.
return; return;
}; };
let usage = caps.supported_usage_flags;
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0;
vulkano::swapchain::Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
format, dimensions, 1, initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
usage, &queue, vulkano::swapchain::SurfaceTransform::Identity, PresentMode::Fifo, true, None).unwrap()
alpha,
vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
}; };
@ -82,17 +89,19 @@ fn main() {
struct Vertex { position: [f32; 2] } struct Vertex { position: [f32; 2] }
impl_vertex!(Vertex, position); impl_vertex!(Vertex, position);
let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[Vertex]> let vertex_buffer = CpuAccessibleBuffer::<[Vertex]>::from_iter(
::from_iter(device.clone(), vulkano::buffer::BufferUsage::all(), device.clone(),
[ BufferUsage::all(),
Vertex { position: [-0.5, -0.5 ] }, [
Vertex { position: [-0.5, 0.5 ] }, Vertex { position: [-0.5, -0.5 ] },
Vertex { position: [ 0.5, -0.5 ] }, Vertex { position: [-0.5, 0.5 ] },
Vertex { position: [ 0.5, 0.5 ] }, Vertex { position: [ 0.5, -0.5 ] },
].iter().cloned()).expect("failed to create buffer"); Vertex { position: [ 0.5, 0.5 ] },
].iter().cloned()
).unwrap();
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module"); let vs = vs::Shader::load(device.clone()).unwrap();
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module"); let fs = fs::Shader::load(device.clone()).unwrap();
let render_pass = Arc::new( let render_pass = Arc::new(
single_pass_renderpass!(device.clone(), single_pass_renderpass!(device.clone(),
@ -113,36 +122,33 @@ fn main() {
let (texture, tex_future) = { let (texture, tex_future) = {
let image = image::load_from_memory_with_format(include_bytes!("image_img.png"), let image = image::load_from_memory_with_format(include_bytes!("image_img.png"),
image::ImageFormat::PNG).unwrap().to_rgba(); ImageFormat::PNG).unwrap().to_rgba();
let image_data = image.into_raw().clone(); let image_data = image.into_raw().clone();
vulkano::image::immutable::ImmutableImage::from_iter( ImmutableImage::from_iter(
image_data.iter().cloned(), image_data.iter().cloned(),
vulkano::image::Dimensions::Dim2d { width: 93, height: 93 }, Dimensions::Dim2d { width: 93, height: 93 },
vulkano::format::R8G8B8A8Srgb, Format::R8G8B8A8Srgb,
queue.clone()).unwrap() queue.clone()
).unwrap()
}; };
let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear,
MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat,
SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap();
let sampler = vulkano::sampler::Sampler::new(device.clone(), vulkano::sampler::Filter::Linear, let pipeline = Arc::new(GraphicsPipeline::start()
vulkano::sampler::Filter::Linear, vulkano::sampler::MipmapMode::Nearest,
vulkano::sampler::SamplerAddressMode::Repeat,
vulkano::sampler::SamplerAddressMode::Repeat,
vulkano::sampler::SamplerAddressMode::Repeat,
0.0, 1.0, 0.0, 0.0).unwrap();
let pipeline = Arc::new(vulkano::pipeline::GraphicsPipeline::start()
.vertex_input_single_buffer::<Vertex>() .vertex_input_single_buffer::<Vertex>()
.vertex_shader(vs.main_entry_point(), ()) .vertex_shader(vs.main_entry_point(), ())
.triangle_strip() .triangle_strip()
.viewports_dynamic_scissors_irrelevant(1) .viewports_dynamic_scissors_irrelevant(1)
.fragment_shader(fs.main_entry_point(), ()) .fragment_shader(fs.main_entry_point(), ())
.blend_alpha_blending() .blend_alpha_blending()
.render_pass(vulkano::framebuffer::Subpass::from(render_pass.clone(), 0).unwrap()) .render_pass(Subpass::from(render_pass.clone(), 0).unwrap())
.build(device.clone()) .build(device.clone())
.unwrap()); .unwrap());
let set = Arc::new(vulkano::descriptor::descriptor_set::PersistentDescriptorSet::start(pipeline.clone(), 0) let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
.add_sampled_image(texture.clone(), sampler.clone()).unwrap() .add_sampled_image(texture.clone(), sampler.clone()).unwrap()
.build().unwrap() .build().unwrap()
); );
@ -151,7 +157,6 @@ fn main() {
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state); let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state);
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame_end = Box::new(tex_future) as Box<GpuFuture>; let mut previous_frame_end = Box::new(tex_future) as Box<GpuFuture>;
loop { loop {
@ -166,7 +171,7 @@ fn main() {
let (new_swapchain, new_images) = match swapchain.recreate_with_dimension(dimensions) { let (new_swapchain, new_images) = match swapchain.recreate_with_dimension(dimensions) {
Ok(r) => r, Ok(r) => r,
Err(vulkano::swapchain::SwapchainCreationError::UnsupportedDimensions) => continue, Err(SwapchainCreationError::UnsupportedDimensions) => continue,
Err(err) => panic!("{:?}", err) Err(err) => panic!("{:?}", err)
}; };
@ -176,24 +181,20 @@ fn main() {
recreate_swapchain = false; recreate_swapchain = false;
} }
let (image_num, future) = match vulkano::swapchain::acquire_next_image(swapchain.clone(), None) { let (image_num, future) = match swapchain::acquire_next_image(swapchain.clone(), None) {
Ok(r) => r, Ok(r) => r,
Err(vulkano::swapchain::AcquireError::OutOfDate) => { Err(AcquireError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
continue; continue;
} }
Err(err) => panic!("{:?}", err) Err(err) => panic!("{:?}", err)
}; };
let cb = vulkano::command_buffer::AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()) let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
let cb = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family())
.unwrap() .unwrap()
.begin_render_pass( .begin_render_pass(framebuffers[image_num].clone(), false, clear_values).unwrap()
framebuffers[image_num].clone(), false, .draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), set.clone(), ()).unwrap()
vec![[0.0, 0.0, 1.0, 1.0].into()]).unwrap()
.draw(pipeline.clone(),
&dynamic_state,
vertex_buffer.clone(),
set.clone(), ()).unwrap()
.end_render_pass().unwrap() .end_render_pass().unwrap()
.build().unwrap(); .build().unwrap();
@ -206,21 +207,21 @@ fn main() {
Ok(future) => { Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>; previous_frame_end = Box::new(future) as Box<_>;
} }
Err(vulkano::sync::FlushError::OutOfDate) => { Err(FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
let mut done = false; let mut done = false;
events_loop.poll_events(|ev| { events_loop.poll_events(|ev| {
match ev { match ev {
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true, Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true, Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => () _ => ()
} }
}); });
@ -228,7 +229,7 @@ fn main() {
} }
} }
/// This method is called once during initialization then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage<Window>>],
render_pass: Arc<RenderPassAbstract + Send + Sync>, render_pass: Arc<RenderPassAbstract + Send + Sync>,

View File

@ -72,25 +72,17 @@ extern crate vulkano_shaders;
use std::sync::Arc; use std::sync::Arc;
use image::ImageBuffer; use image::ImageBuffer;
use image::Rgba; use image::Rgba;
use vulkano::buffer::BufferUsage; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::buffer::CpuAccessibleBuffer; use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBuffer, DynamicState};
use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::device::{Device, DeviceExtensions};
use vulkano::command_buffer::CommandBuffer;
use vulkano::command_buffer::DynamicState;
use vulkano::device::Device;
use vulkano::device::DeviceExtensions;
use vulkano::format::Format; use vulkano::format::Format;
use vulkano::framebuffer::Framebuffer; use vulkano::framebuffer::{Framebuffer, Subpass};
use vulkano::framebuffer::Subpass; use vulkano::image::{AttachmentImage, Dimensions, StorageImage};
use vulkano::image::AttachmentImage; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::image::Dimensions;
use vulkano::image::StorageImage;
use vulkano::instance::Instance;
use vulkano::instance::InstanceExtensions;
use vulkano::instance::PhysicalDevice;
use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::viewport::Viewport; use vulkano::pipeline::viewport::Viewport;
use vulkano::sync::GpuFuture; use vulkano::sync::GpuFuture;
use vulkano::format::ClearValue;
mod vs { mod vs {
vulkano_shaders::shader!{ vulkano_shaders::shader!{
@ -122,34 +114,30 @@ void main() {
fn main() { fn main() {
// The usual Vulkan initialization. // The usual Vulkan initialization.
let instance = Instance::new(None, &InstanceExtensions::none(), None) let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
.expect("failed to create instance"); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().expect("no device available"); let queue_family = physical.queue_families().find(|&q| q.supports_graphics()).unwrap();
let queue_family = physical.queue_families() let (device, mut queues) = Device::new(physical, physical.supported_features(),
.find(|&q| q.supports_graphics()) &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
.expect("couldn't find a graphical queue family");
let (device, mut queues) = {
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(),
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
// Creating our intermediate multisampled image. // Creating our intermediate multisampled image.
// //
// As explained in the introduction, we pass the same dimensions and format as for the final // As explained in the introduction, we pass the same dimensions and format as for the final
// image. But we also pass the number of samples-per-pixel, which is 4 here. // image. But we also pass the number of samples-per-pixel, which is 4 here.
let intermediary = AttachmentImage::transient_multisampled(device.clone(), [1024, 1024], let intermediary = AttachmentImage::transient_multisampled(device.clone(),
4, Format::R8G8B8A8Unorm).unwrap(); [1024, 1024], 4, Format::R8G8B8A8Unorm).unwrap();
// This is the final image that will receive the anti-aliased triangle. // This is the final image that will receive the anti-aliased triangle.
let image = StorageImage::new(device.clone(), Dimensions::Dim2d { width: 1024, height: 1024 }, let image = StorageImage::new(device.clone(), Dimensions::Dim2d { width: 1024, height: 1024 },
Format::R8G8B8A8Unorm, Some(queue.family())).unwrap(); Format::R8G8B8A8Unorm, Some(queue.family())).unwrap();
// In this example, we are going to perform the *resolve* (ie. turning a multisampled image // In this example, we are going to perform the *resolve* (ie. turning a multisampled image
// into a non-multisampled one) as part of the render pass. This is the preferred method of // into a non-multisampled one) as part of the render pass. This is the preferred method of
// doing so, as it the advantage that the Vulkan implementation doesn't have to write the // doing so, as it the advantage that the Vulkan implementation doesn't have to write the
// content of the multisampled image back to memory at the end. // content of the multisampled image back to memory at the end.
let render_pass = Arc::new(single_pass_renderpass!(device.clone(), let render_pass = Arc::new(single_pass_renderpass!(
device.clone(),
attachments: { attachments: {
// The first framebuffer attachment is the intermediary image. // The first framebuffer attachment is the intermediary image.
intermediary: { intermediary: {
@ -192,19 +180,20 @@ fn main() {
// At the end of the example, we copy the content of `image` (ie. the final image) to a buffer, // At the end of the example, we copy the content of `image` (ie. the final image) to a buffer,
// then read the content of that buffer and save it to a PNG file. // then read the content of that buffer and save it to a PNG file.
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module"); let vs = vs::Shader::load(device.clone()).unwrap();
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module"); let fs = fs::Shader::load(device.clone()).unwrap();
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct Vertex { struct Vertex {
position: [f32; 2], position: [f32; 2],
} }
impl_vertex!(Vertex, position); impl_vertex!(Vertex, position);
let vertex1 = Vertex { position: [-0.5, -0.5] }; let vertex1 = Vertex { position: [-0.5, -0.5] };
let vertex2 = Vertex { position: [ 0.0, 0.5] }; let vertex2 = Vertex { position: [ 0.0, 0.5] };
let vertex3 = Vertex { position: [ 0.5, -0.25] }; let vertex3 = Vertex { position: [ 0.5, -0.25] };
let vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), let vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
vec![vertex1, vertex2, vertex3].into_iter()).unwrap(); vec![vertex1, vertex2, vertex3].into_iter()).unwrap();
let pipeline = Arc::new(GraphicsPipeline::start() let pipeline = Arc::new(GraphicsPipeline::start()
.vertex_input_single_buffer::<Vertex>() .vertex_input_single_buffer::<Vertex>()
@ -225,11 +214,10 @@ fn main() {
}; };
let buf = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), let buf = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
(0 .. 1024 * 1024 * 4).map(|_| 0u8)) (0 .. 1024 * 1024 * 4).map(|_| 0u8)).unwrap();
.expect("failed to create buffer");
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()
.begin_render_pass(framebuffer.clone(), false, vec![[0.0, 0.0, 1.0, 1.0].into(), vulkano::format::ClearValue::None]) .begin_render_pass(framebuffer.clone(), false, vec![[0.0, 0.0, 1.0, 1.0].into(), ClearValue::None])
.unwrap() .unwrap()
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ()) .draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
@ -245,8 +233,7 @@ fn main() {
.unwrap(); .unwrap();
let finished = command_buffer.execute(queue.clone()).unwrap(); let finished = command_buffer.execute(queue.clone()).unwrap();
finished.then_signal_fence_and_flush().unwrap() finished.then_signal_fence_and_flush().unwrap().wait(None).unwrap();
.wait(None).unwrap();
let buffer_content = buf.read().unwrap(); let buffer_content = buf.read().unwrap();
let image = ImageBuffer::<Rgba<u8>, _>::from_raw(1024, 1024, &buffer_content[..]).unwrap(); let image = ImageBuffer::<Rgba<u8>, _>::from_raw(1024, 1024, &buffer_content[..]).unwrap();

View File

@ -11,17 +11,14 @@
extern crate vulkano; extern crate vulkano;
extern crate vulkano_shaders; extern crate vulkano_shaders;
use vulkano::buffer::BufferUsage; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Device; use vulkano::device::{Device, DeviceExtensions};
use vulkano::device::DeviceExtensions; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::instance::Instance;
use vulkano::instance::InstanceExtensions;
use vulkano::pipeline::ComputePipeline; use vulkano::pipeline::ComputePipeline;
use vulkano::sync::now;
use vulkano::sync::GpuFuture; use vulkano::sync::GpuFuture;
use vulkano::sync;
use std::sync::Arc; use std::sync::Arc;
@ -55,29 +52,26 @@ void main() {
fn main() { fn main() {
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap(); let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance).next().unwrap(); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap(); let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
let (device, mut queues) = { let (device, mut queues) = Device::new(physical, physical.supported_features(),
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(), &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let shader = cs::Shader::load(device.clone()) let shader = cs::Shader::load(device.clone()).unwrap();
.expect("failed to create shader module");
let pipeline = Arc::new(ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap()); let pipeline = Arc::new(ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap());
let data_buffer = { let data_buffer = {
let data_iter = (0 .. 65536u32).map(|n| n); let data_iter = (0 .. 65536u32).map(|n| n);
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
data_iter).expect("failed to create buffer")
}; };
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0) let set = Arc::new(
.add_buffer(data_buffer.clone()).unwrap() PersistentDescriptorSet::start(pipeline.clone(), 0)
.build().unwrap() .add_buffer(data_buffer.clone()).unwrap()
.build().unwrap()
); );
// The `vulkano_shaders!` macro generates a struct with the correct representation of the push constants struct specified in the shader. // The `vulkano_shaders::shaders!` macro generates a struct with the correct representation of the push constants struct specified in the shader.
// Here we create an instance of the generated struct. // Here we create an instance of the generated struct.
let push_constants = cs::ty::PushConstantData { let push_constants = cs::ty::PushConstantData {
multiple: 1, multiple: 1,
@ -88,18 +82,18 @@ fn main() {
// For a compute pipeline, push constants are passed to the `dispatch` method. // For a compute pipeline, push constants are passed to the `dispatch` method.
// For a graphics pipeline, push constants are passed to the `draw` and `draw_indexed` methods. // For a graphics pipeline, push constants are passed to the `draw` and `draw_indexed` methods.
// Note that there is no type safety for the push constants argument. // Note that there is no type safety for the push constants argument.
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders!` macro. // So be careful to only pass an instance of the struct generated by the `vulkano_shaders::shaders!` macro.
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([1024, 1, 1], pipeline.clone(), set.clone(), push_constants).unwrap() .dispatch([1024, 1, 1], pipeline.clone(), set.clone(), push_constants).unwrap()
.build().unwrap(); .build().unwrap();
let future = now(device.clone()) let future = sync::now(device.clone())
.then_execute(queue.clone(), command_buffer).unwrap() .then_execute(queue.clone(), command_buffer).unwrap()
.then_signal_fence_and_flush().unwrap(); .then_signal_fence_and_flush().unwrap();
future.wait(None).unwrap(); future.wait(None).unwrap();
let data_buffer_content = data_buffer.read().expect("failed to lock buffer for reading"); let data_buffer_content = data_buffer.read().unwrap();
for n in 0 .. 65536u32 { for n in 0 .. 65536u32 {
assert_eq!(data_buffer_content[n as usize], n * 1 + 1); assert_eq!(data_buffer_content[n as usize], n * 1 + 1);
} }

View File

@ -34,7 +34,7 @@ use vulkano::descriptor::pipeline_layout::PipelineLayoutDesc;
use vulkano::descriptor::pipeline_layout::PipelineLayoutDescPcRange; use vulkano::descriptor::pipeline_layout::PipelineLayoutDescPcRange;
use vulkano::device::Device; use vulkano::device::Device;
use vulkano::device::DeviceExtensions; use vulkano::device::DeviceExtensions;
use vulkano::format; use vulkano::format::Format;
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::SwapchainImage; use vulkano::image::SwapchainImage;
use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipeline;
@ -65,77 +65,55 @@ pub struct Vertex {
impl_vertex!(Vertex, position, color); impl_vertex!(Vertex, position, color);
fn main() { fn main() {
let instance = vk::instance::Instance::new( let instance = vk::instance::Instance::new(None, &vulkano_win::required_extensions(), None).unwrap();
None, let physical = vk::instance::PhysicalDevice::enumerate(&instance).next().unwrap();
&vulkano_win::required_extensions(),
None,
).expect("no instance with surface extension");
let physical = vk::instance::PhysicalDevice::enumerate(&instance)
.next()
.expect("no graphics device");
let mut events_loop = winit::EventsLoop::new(); let mut events_loop = winit::EventsLoop::new();
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let window = surface.window(); let window = surface.window();
let queue_family = physical.queue_families().find(|&q| {
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
}).unwrap();
let (device, mut queues) = { let (device, mut queues) = {
let graphical_queue_family = physical let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
.queue_families() Device::new(physical, physical.supported_features(), &device_ext,
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false)) [(queue_family, 0.5)].iter().cloned()).unwrap()
.expect("couldn't find a graphic queue family"); };
let device_ext = DeviceExtensions { let queue = queues.next().unwrap();
khr_swapchain: true,
..DeviceExtensions::none() let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
}; let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
Device::new( [dimensions.0, dimensions.1]
physical.clone(), } else {
physical.supported_features(), return;
&device_ext,
[(graphical_queue_family, 0.5)].iter().cloned(),
).expect("failed to create device")
}; };
let graphics_queue = queues.next().unwrap();
let (mut swapchain, images) = { let (mut swapchain, images) = {
let caps = surface let caps = surface.capabilities(physical).unwrap();
.capabilities(device.physical_device()) let usage = caps.supported_usage_flags;
.expect("failure to get surface capabilities");
let alpha = caps.supported_composite_alpha.iter().next().unwrap(); let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0; let format = caps.supported_formats[0].0;
let dimensions = caps.current_extent.unwrap_or([1024, 768]);
let usage = caps.supported_usage_flags;
Swapchain::new( Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, initial_dimensions,
device.clone(), 1, usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).unwrap()
surface.clone(),
caps.min_image_count,
format,
dimensions,
1,
usage,
&graphics_queue,
SurfaceTransform::Identity,
alpha,
PresentMode::Fifo,
true,
None,
).expect("failed to create swapchain")
}; };
let render_pass = Arc::new( let render_pass = Arc::new(single_pass_renderpass!(
single_pass_renderpass!( device.clone(),
device.clone(), attachments: { attachments: {
color: { color: {
load: Clear, load: Clear,
store: Store, store: Store,
format: swapchain.format(), format: swapchain.format(),
samples: 1, samples: 1,
}
},
pass: {
color: [color],
depth_stencil: {}
} }
).unwrap(), },
); pass: {
color: [color],
depth_stencil: {}
}
).unwrap());
let vs = { let vs = {
let mut f = File::open("src/bin/runtime-shader/vert.spv") let mut f = File::open("src/bin/runtime-shader/vert.spv")
@ -155,10 +133,10 @@ fn main() {
unsafe { ShaderModule::new(device.clone(), &v) }.unwrap() unsafe { ShaderModule::new(device.clone(), &v) }.unwrap()
}; };
// This structure will tell Vulkan how input entries of our vertex shader // This structure will tell Vulkan how input entries of our vertex shader look like
// look like.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
struct VertInput; struct VertInput;
unsafe impl ShaderInterfaceDef for VertInput { unsafe impl ShaderInterfaceDef for VertInput {
type Iter = VertInputIter; type Iter = VertInputIter;
@ -166,8 +144,10 @@ fn main() {
VertInputIter(0) VertInputIter(0)
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct VertInputIter(u16); struct VertInputIter(u16);
impl Iterator for VertInputIter { impl Iterator for VertInputIter {
type Item = ShaderInterfaceDefEntry; type Item = ShaderInterfaceDefEntry;
@ -182,7 +162,7 @@ fn main() {
self.0 += 1; self.0 += 1;
return Some(ShaderInterfaceDefEntry { return Some(ShaderInterfaceDefEntry {
location: 1..2, location: 1..2,
format: format::Format::R32G32B32Sfloat, format: Format::R32G32B32Sfloat,
name: Some(Cow::Borrowed("color")) name: Some(Cow::Borrowed("color"))
}) })
} }
@ -190,12 +170,13 @@ fn main() {
self.0 += 1; self.0 += 1;
return Some(ShaderInterfaceDefEntry { return Some(ShaderInterfaceDefEntry {
location: 0..1, location: 0..1,
format: format::Format::R32G32Sfloat, format: Format::R32G32Sfloat,
name: Some(Cow::Borrowed("position")) name: Some(Cow::Borrowed("position"))
}) })
} }
None None
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
// We must return exact number of entries left in iterator. // We must return exact number of entries left in iterator.
@ -203,10 +184,12 @@ fn main() {
(len, Some(len)) (len, Some(len))
} }
} }
impl ExactSizeIterator for VertInputIter {
} impl ExactSizeIterator for VertInputIter { }
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
struct VertOutput; struct VertOutput;
unsafe impl ShaderInterfaceDef for VertOutput { unsafe impl ShaderInterfaceDef for VertOutput {
type Iter = VertOutputIter; type Iter = VertOutputIter;
@ -214,10 +197,12 @@ fn main() {
VertOutputIter(0) VertOutputIter(0)
} }
} }
// This structure will tell Vulkan how output entries (those passed to next // This structure will tell Vulkan how output entries (those passed to next
// stage) of our vertex shader look like. // stage) of our vertex shader look like.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct VertOutputIter(u16); struct VertOutputIter(u16);
impl Iterator for VertOutputIter { impl Iterator for VertOutputIter {
type Item = ShaderInterfaceDefEntry; type Item = ShaderInterfaceDefEntry;
@ -227,20 +212,22 @@ fn main() {
self.0 += 1; self.0 += 1;
return Some(ShaderInterfaceDefEntry { return Some(ShaderInterfaceDefEntry {
location: 0..1, location: 0..1,
format: format::Format::R32G32B32Sfloat, format: Format::R32G32B32Sfloat,
name: Some(Cow::Borrowed("v_color")) name: Some(Cow::Borrowed("v_color"))
}) })
} }
None None
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
let len = (1 - self.0) as usize; let len = (1 - self.0) as usize;
(len, Some(len)) (len, Some(len))
} }
} }
impl ExactSizeIterator for VertOutputIter {
} impl ExactSizeIterator for VertOutputIter { }
// This structure describes layout of this stage. // This structure describes layout of this stage.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct VertLayout(ShaderStages); struct VertLayout(ShaderStages);
@ -248,22 +235,13 @@ fn main() {
// Number of descriptor sets it takes. // Number of descriptor sets it takes.
fn num_sets(&self) -> usize { 0 } fn num_sets(&self) -> usize { 0 }
// Number of entries (bindings) in each set. // Number of entries (bindings) in each set.
fn num_bindings_in_set(&self, set: usize) -> Option<usize> { fn num_bindings_in_set(&self, _set: usize) -> Option<usize> { None }
match set { _ => None, }
}
// Descriptor descriptions. // Descriptor descriptions.
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> { fn descriptor(&self, _set: usize, _binding: usize) -> Option<DescriptorDesc> { None }
match (set, binding) { _ => None, }
}
// Number of push constants ranges (think: number of push constants). // Number of push constants ranges (think: number of push constants).
fn num_push_constants_ranges(&self) -> usize { 0 } fn num_push_constants_ranges(&self) -> usize { 0 }
// Each push constant range in memory. // Each push constant range in memory.
fn push_constants_range(&self, num: usize) -> Option<PipelineLayoutDescPcRange> { fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> { None }
if num != 0 || 0 == 0 { return None; }
Some(PipelineLayoutDescPcRange { offset: 0,
size: 0,
stages: ShaderStages::all() })
}
} }
// Same as with our vertex shader, but for fragment one instead. // Same as with our vertex shader, but for fragment one instead.
@ -278,6 +256,7 @@ fn main() {
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct FragInputIter(u16); struct FragInputIter(u16);
impl Iterator for FragInputIter { impl Iterator for FragInputIter {
type Item = ShaderInterfaceDefEntry; type Item = ShaderInterfaceDefEntry;
@ -287,20 +266,22 @@ fn main() {
self.0 += 1; self.0 += 1;
return Some(ShaderInterfaceDefEntry { return Some(ShaderInterfaceDefEntry {
location: 0..1, location: 0..1,
format: format::Format::R32G32B32Sfloat, format: Format::R32G32B32Sfloat,
name: Some(Cow::Borrowed("v_color")) name: Some(Cow::Borrowed("v_color"))
}) })
} }
None None
} }
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
let len = (1 - self.0) as usize; let len = (1 - self.0) as usize;
(len, Some(len)) (len, Some(len))
} }
} }
impl ExactSizeIterator for FragInputIter {
} impl ExactSizeIterator for FragInputIter { }
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
struct FragOutput; struct FragOutput;
unsafe impl ShaderInterfaceDef for FragOutput { unsafe impl ShaderInterfaceDef for FragOutput {
@ -310,8 +291,10 @@ fn main() {
FragOutputIter(0) FragOutputIter(0)
} }
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct FragOutputIter(u16); struct FragOutputIter(u16);
impl Iterator for FragOutputIter { impl Iterator for FragOutputIter {
type Item = ShaderInterfaceDefEntry; type Item = ShaderInterfaceDefEntry;
@ -323,7 +306,7 @@ fn main() {
self.0 += 1; self.0 += 1;
return Some(ShaderInterfaceDefEntry { return Some(ShaderInterfaceDefEntry {
location: 0..1, location: 0..1,
format: format::Format::R32G32B32A32Sfloat, format: Format::R32G32B32A32Sfloat,
name: Some(Cow::Borrowed("f_color")) name: Some(Cow::Borrowed("f_color"))
}) })
} }
@ -335,26 +318,18 @@ fn main() {
(len, Some(len)) (len, Some(len))
} }
} }
impl ExactSizeIterator for FragOutputIter {
} impl ExactSizeIterator for FragOutputIter { }
// Layout same as with vertex shader. // Layout same as with vertex shader.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct FragLayout(ShaderStages); struct FragLayout(ShaderStages);
unsafe impl PipelineLayoutDesc for FragLayout { unsafe impl PipelineLayoutDesc for FragLayout {
fn num_sets(&self) -> usize { 0 } fn num_sets(&self) -> usize { 0 }
fn num_bindings_in_set(&self, set: usize) -> Option<usize> { fn num_bindings_in_set(&self, _set: usize) -> Option<usize> { None }
match set { _ => None, } fn descriptor(&self, _set: usize, _binding: usize) -> Option<DescriptorDesc> { None }
}
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
match (set, binding) { _ => None, }
}
fn num_push_constants_ranges(&self) -> usize { 0 } fn num_push_constants_ranges(&self) -> usize { 0 }
fn push_constants_range(&self, num: usize) -> Option<PipelineLayoutDescPcRange> { fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> { None }
if num != 0 || 0 == 0 { return None; }
Some(PipelineLayoutDescPcRange { offset: 0,
size: 0,
stages: ShaderStages::all() })
}
} }
// NOTE: ShaderModule::*_shader_entry_point calls do not do any error // NOTE: ShaderModule::*_shader_entry_point calls do not do any error
@ -405,7 +380,7 @@ fn main() {
Vertex { position: [ 0.0, -1.0], color: [0.0, 1.0, 0.0] }, Vertex { position: [ 0.0, -1.0], color: [0.0, 1.0, 0.0] },
Vertex { position: [ 1.0, 1.0], color: [0.0, 0.0, 1.0] }, Vertex { position: [ 1.0, 1.0], color: [0.0, 0.0, 1.0] },
].iter().cloned() ].iter().cloned()
).expect("failed to create vertex buffer"); ).unwrap();
// NOTE: We don't create any descriptor sets in this example, but you should // NOTE: We don't create any descriptor sets in this example, but you should
// note that passing wrong types, providing sets at wrong indexes will cause // note that passing wrong types, providing sets at wrong indexes will cause
@ -448,28 +423,17 @@ fn main() {
Err(err) => panic!("{:?}", err) Err(err) => panic!("{:?}", err)
}; };
let command_buffer = AutoCommandBufferBuilder::new(
device.clone(), let clear_values = vec!([0.0, 0.0, 0.0, 1.0].into());
graphics_queue.family(), let command_buffer = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
).unwrap() .begin_render_pass(framebuffers[image_num].clone(), false, clear_values).unwrap()
.begin_render_pass( .draw(graphics_pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ()).unwrap()
framebuffers[image_num].clone(),
false,
vec![[0.0, 0.0, 0.0, 1.0].into()],
).unwrap()
.draw(
graphics_pipeline.clone(),
&dynamic_state,
vertex_buffer.clone(),
(),
(),
).unwrap()
.end_render_pass().unwrap() .end_render_pass().unwrap()
.build().unwrap(); .build().unwrap();
let future = previous_frame_end.join(acquire_future) let future = previous_frame_end.join(acquire_future)
.then_execute(graphics_queue.clone(), command_buffer).unwrap() .then_execute(queue.clone(), command_buffer).unwrap()
.then_swapchain_present(graphics_queue.clone(), swapchain.clone(), image_num) .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
.then_signal_fence_and_flush(); .then_signal_fence_and_flush();
match future { match future {
@ -498,7 +462,7 @@ fn main() {
} }
} }
/// This method is called once during initialization then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage<Window>>],
render_pass: Arc<RenderPassAbstract + Send + Sync>, render_pass: Arc<RenderPassAbstract + Send + Sync>,

View File

@ -11,17 +11,14 @@
extern crate vulkano; extern crate vulkano;
extern crate vulkano_shaders; extern crate vulkano_shaders;
use vulkano::buffer::BufferUsage; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::buffer::CpuAccessibleBuffer;
use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::Device; use vulkano::device::{Device, DeviceExtensions};
use vulkano::device::DeviceExtensions; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::instance::Instance;
use vulkano::instance::InstanceExtensions;
use vulkano::pipeline::ComputePipeline; use vulkano::pipeline::ComputePipeline;
use vulkano::sync::now;
use vulkano::sync::GpuFuture; use vulkano::sync::GpuFuture;
use vulkano::sync;
use std::sync::Arc; use std::sync::Arc;
@ -53,16 +50,13 @@ void main() {
fn main() { fn main() {
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap(); let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance).next().unwrap(); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap(); let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap();
let (device, mut queues) = { let (device, mut queues) = Device::new(physical, physical.supported_features(),
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(), &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let shader = cs::Shader::load(device.clone()) let shader = cs::Shader::load(device.clone()).unwrap();
.expect("failed to create shader module");
let spec_consts = cs::SpecializationConstants { let spec_consts = cs::SpecializationConstants {
enable: 1, enable: 1,
multiple: 1, multiple: 1,
@ -72,8 +66,7 @@ fn main() {
let data_buffer = { let data_buffer = {
let data_iter = (0 .. 65536u32).map(|n| n); let data_iter = (0 .. 65536u32).map(|n| n);
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
data_iter).expect("failed to create buffer")
}; };
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0) let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
@ -85,13 +78,13 @@ fn main() {
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), ()).unwrap() .dispatch([1024, 1, 1], pipeline.clone(), set.clone(), ()).unwrap()
.build().unwrap(); .build().unwrap();
let future = now(device.clone()) let future = sync::now(device.clone())
.then_execute(queue.clone(), command_buffer).unwrap() .then_execute(queue.clone(), command_buffer).unwrap()
.then_signal_fence_and_flush().unwrap(); .then_signal_fence_and_flush().unwrap();
future.wait(None).unwrap(); future.wait(None).unwrap();
let data_buffer_content = data_buffer.read().expect("failed to lock buffer for reading"); let data_buffer_content = data_buffer.read().unwrap();
for n in 0 .. 65536u32 { for n in 0 .. 65536u32 {
assert_eq!(data_buffer_content[n as usize], n * 1 + 1); assert_eq!(data_buffer_content[n as usize], n * 1 + 1);
} }

View File

@ -7,20 +7,18 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
extern crate examples;
extern crate cgmath;
extern crate winit;
extern crate time;
#[macro_use] #[macro_use]
extern crate vulkano; extern crate vulkano;
extern crate vulkano_win; extern crate vulkano_win;
extern crate winit;
use vulkano_win::VkSurfaceBuild; extern crate cgmath;
extern crate time;
extern crate examples;
use vulkano::buffer::cpu_pool::CpuBufferPool; use vulkano::buffer::cpu_pool::CpuBufferPool;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions}; use vulkano::device::{Device, DeviceExtensions};
use vulkano::format::Format; use vulkano::format::Format;
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
@ -28,12 +26,15 @@ use vulkano::image::SwapchainImage;
use vulkano::image::attachment::AttachmentImage; use vulkano::image::attachment::AttachmentImage;
use vulkano::instance::Instance; use vulkano::instance::Instance;
use vulkano::instance::PhysicalDevice; use vulkano::instance::PhysicalDevice;
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract};
use vulkano::pipeline::vertex::TwoBuffersDefinition; use vulkano::pipeline::vertex::TwoBuffersDefinition;
use vulkano::pipeline::viewport::Viewport; use vulkano::pipeline::viewport::Viewport;
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract};
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError}; use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
use vulkano::swapchain; use vulkano::swapchain;
use vulkano::sync::GpuFuture; use vulkano::sync::GpuFuture;
use vulkano::sync;
use vulkano_win::VkSurfaceBuild;
use winit::Window; use winit::Window;
@ -41,17 +42,18 @@ use cgmath::{Matrix3, Matrix4, Point3, Vector3, Rad};
use examples::{Vertex, Normal, VERTICES, NORMALS, INDICES}; use examples::{Vertex, Normal, VERTICES, NORMALS, INDICES};
use std::sync::Arc;
use std::iter; use std::iter;
use std::sync::Arc;
use std::time::Instant;
fn main() { fn main() {
// The start of this example is exactly the same as `triangle`. You should read the // The start of this example is exactly the same as `triangle`. You should read the
// `triangle` example if you haven't done so yet. // `triangle` example if you haven't done so yet.
let extensions = vulkano_win::required_extensions(); let extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, &extensions, None).expect("failed to create instance"); let instance = Instance::new(None, &extensions, None).unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().expect("no device available"); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
println!("Using device: {} (type: {:?})", physical.name(), physical.ty()); println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
let mut events_loop = winit::EventsLoop::new(); let mut events_loop = winit::EventsLoop::new();
@ -69,24 +71,24 @@ fn main() {
let queue_family = physical.queue_families().find(|&q| let queue_family = physical.queue_families().find(|&q|
q.supports_graphics() && surface.is_supported(q).unwrap_or(false) q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
).expect("couldn't find a graphical queue family"); ).unwrap();
let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() }; let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
let (device, mut queues) = Device::new( let (device, mut queues) = Device::new(
physical, physical.supported_features(), &device_ext, [(queue_family, 0.5)].iter().cloned() physical, physical.supported_features(), &device_ext, [(queue_family, 0.5)].iter().cloned()
).expect("failed to create device"); ).unwrap();
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let (mut swapchain, images) = { let (mut swapchain, images) = {
let caps = surface.capabilities(physical).expect("failed to get surface capabilities"); let caps = surface.capabilities(physical).unwrap();
let usage = caps.supported_usage_flags; let usage = caps.supported_usage_flags;
let format = caps.supported_formats[0].0; let format = caps.supported_formats[0].0;
let alpha = caps.supported_composite_alpha.iter().next().unwrap(); let alpha = caps.supported_composite_alpha.iter().next().unwrap();
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, dimensions, 1, Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, dimensions, 1,
usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).expect("failed to create swapchain") usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).unwrap()
}; };
let vertices = VERTICES.iter().cloned(); let vertices = VERTICES.iter().cloned();
@ -100,8 +102,8 @@ fn main() {
let uniform_buffer = CpuBufferPool::<vs::ty::Data>::new(device.clone(), BufferUsage::all()); let uniform_buffer = CpuBufferPool::<vs::ty::Data>::new(device.clone(), BufferUsage::all());
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module"); let vs = vs::Shader::load(device.clone()).unwrap();
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module"); let fs = fs::Shader::load(device.clone()).unwrap();
let render_pass = Arc::new( let render_pass = Arc::new(
single_pass_renderpass!(device.clone(), single_pass_renderpass!(device.clone(),
@ -115,7 +117,7 @@ fn main() {
depth: { depth: {
load: Clear, load: Clear,
store: DontCare, store: DontCare,
format: vulkano::format::Format::D16Unorm, format: Format::D16Unorm,
samples: 1, samples: 1,
} }
}, },
@ -129,8 +131,8 @@ fn main() {
let (mut pipeline, mut framebuffers) = window_size_dependent_setup(device.clone(), &vs, &fs, &images, render_pass.clone()); let (mut pipeline, mut framebuffers) = window_size_dependent_setup(device.clone(), &vs, &fs, &images, render_pass.clone());
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>; let mut previous_frame = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
let rotation_start = std::time::Instant::now(); let rotation_start = Instant::now();
loop { loop {
previous_frame.cleanup_finished(); previous_frame.cleanup_finished();
@ -178,7 +180,7 @@ fn main() {
uniform_buffer.next(uniform_data).unwrap() uniform_buffer.next(uniform_data).unwrap()
}; };
let set = Arc::new(vulkano::descriptor::descriptor_set::PersistentDescriptorSet::start(pipeline.clone(), 0) let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
.add_buffer(uniform_buffer_subbuffer).unwrap() .add_buffer(uniform_buffer_subbuffer).unwrap()
.build().unwrap() .build().unwrap()
); );
@ -198,7 +200,8 @@ fn main() {
vec![ vec![
[0.0, 0.0, 1.0, 1.0].into(), [0.0, 0.0, 1.0, 1.0].into(),
1f32.into() 1f32.into()
]).unwrap() ]
).unwrap()
.draw_indexed( .draw_indexed(
pipeline.clone(), pipeline.clone(),
&DynamicState::none(), &DynamicState::none(),
@ -216,13 +219,13 @@ fn main() {
Ok(future) => { Ok(future) => {
previous_frame = Box::new(future) as Box<_>; previous_frame = Box::new(future) as Box<_>;
} }
Err(vulkano::sync::FlushError::OutOfDate) => { Err(sync::FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame = Box::new(sync::now(device.clone())) as Box<_>;
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
@ -238,7 +241,7 @@ fn main() {
} }
} }
/// This method is called once during initialization then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
device: Arc<Device>, device: Arc<Device>,
vs: &vs::Shader, vs: &vs::Shader,

View File

@ -24,22 +24,22 @@ extern crate vulkano_shaders;
extern crate winit; extern crate winit;
extern crate vulkano_win; extern crate vulkano_win;
use vulkano_win::VkSurfaceBuild;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::device::Device; use vulkano::device::{Device, DeviceExtensions};
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::SwapchainImage; use vulkano::image::SwapchainImage;
use vulkano::instance::Instance; use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::viewport::Viewport; use vulkano::pipeline::viewport::Viewport;
use vulkano::swapchain;
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError}; use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
use vulkano::sync::now; use vulkano::swapchain;
use vulkano::sync::GpuFuture; use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use winit::Window; use vulkano_win::VkSurfaceBuild;
use winit::{EventsLoop, Window, WindowBuilder, Event, WindowEvent};
use std::sync::Arc; use std::sync::Arc;
@ -136,34 +136,26 @@ void main() {
fn main() { fn main() {
let instance = { let extensions = vulkano_win::required_extensions();
let extensions = vulkano_win::required_extensions(); let instance = Instance::new(None, &extensions, None).unwrap();
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
};
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance) let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
.next().expect("no device available");
println!("Using device: {} (type: {:?})", physical.name(), physical.ty()); println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
let mut events_loop = winit::EventsLoop::new(); let mut events_loop = EventsLoop::new();
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let window = surface.window(); let window = surface.window();
let queue = physical.queue_families().find(|&q| { let queue_family = physical.queue_families().find(|&q| {
q.supports_graphics() && surface.is_supported(q).unwrap_or(false) q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
}).expect("couldn't find a graphical queue family"); }).unwrap();
let (device, mut queues) = {
let device_ext = vulkano::device::DeviceExtensions {
khr_swapchain: true,
.. vulkano::device::DeviceExtensions::none()
};
Device::new(physical, physical.supported_features(), &device_ext, let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
[(queue, 0.5)].iter().cloned()).expect("failed to create device") let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
}; [(queue_family, 0.5)].iter().cloned()).unwrap();
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
let mut dimensions = if let Some(dimensions) = window.get_inner_size() { let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
} else { } else {
@ -171,16 +163,13 @@ fn main() {
}; };
let (mut swapchain, images) = { let (mut swapchain, images) = {
let caps = surface.capabilities(physical) let caps = surface.capabilities(physical).unwrap();
.expect("failed to get surface capabilities"); let usage = caps.supported_usage_flags;
let alpha = caps.supported_composite_alpha.iter().next().unwrap(); let alpha = caps.supported_composite_alpha.iter().next().unwrap();
let format = caps.supported_formats[0].0; let format = caps.supported_formats[0].0;
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, initial_dimensions,
dimensions, 1, caps.supported_usage_flags, &queue, 1, usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).unwrap()
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true,
None).expect("failed to create swapchain")
}; };
let vertex_buffer = { let vertex_buffer = {
@ -198,15 +187,16 @@ fn main() {
Vertex { position: [-0.9, 0.9] }, Vertex { position: [-0.9, 0.9] },
Vertex { position: [-0.7, 0.6] }, Vertex { position: [-0.7, 0.6] },
Vertex { position: [-0.5, 0.9] }, Vertex { position: [-0.5, 0.9] },
].iter().cloned()).expect("failed to create buffer") ].iter().cloned()).unwrap()
}; };
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module"); let vs = vs::Shader::load(device.clone()).unwrap();
let tcs = tcs::Shader::load(device.clone()).expect("failed to create shader module"); let tcs = tcs::Shader::load(device.clone()).unwrap();
let tes = tes::Shader::load(device.clone()).expect("failed to create shader module"); let tes = tes::Shader::load(device.clone()).unwrap();
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module"); let fs = fs::Shader::load(device.clone()).unwrap();
let render_pass = Arc::new(single_pass_renderpass!(device.clone(), let render_pass = Arc::new(single_pass_renderpass!(
device.clone(),
attachments: { attachments: {
color: { color: {
load: Clear, load: Clear,
@ -239,14 +229,14 @@ fn main() {
.unwrap()); .unwrap());
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
let mut previous_frame_end = Box::new(now(device.clone())) as Box<GpuFuture>; let mut previous_frame_end = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
let mut dynamic_state = DynamicState { line_width: None, viewports: None, scissors: None }; let mut dynamic_state = DynamicState { line_width: None, viewports: None, scissors: None };
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state); let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state);
loop { loop {
previous_frame_end.cleanup_finished(); previous_frame_end.cleanup_finished();
if recreate_swapchain { if recreate_swapchain {
dimensions = if let Some(dimensions) = window.get_inner_size() { let dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
} else { } else {
@ -279,9 +269,7 @@ fn main() {
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()
.begin_render_pass(framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into()]) .begin_render_pass(framebuffers[image_num].clone(), false, vec![[0.0, 0.0, 0.0, 1.0].into()])
.unwrap() .unwrap()
.draw(pipeline.clone(), .draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
&dynamic_state,
vertex_buffer.clone(), (), ())
.unwrap() .unwrap()
.end_render_pass() .end_render_pass()
.unwrap() .unwrap()
@ -296,21 +284,21 @@ fn main() {
Ok(future) => { Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>; previous_frame_end = Box::new(future) as Box<_>;
} }
Err(vulkano::sync::FlushError::OutOfDate) => { Err(FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
let mut done = false; let mut done = false;
events_loop.poll_events(|ev| { events_loop.poll_events(|ev| {
match ev { match ev {
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true, Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true, Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => () _ => ()
} }
}); });
@ -318,6 +306,7 @@ fn main() {
} }
} }
/// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage<Window>>],
render_pass: Arc<RenderPassAbstract + Send + Sync>, render_pass: Arc<RenderPassAbstract + Send + Sync>,

View File

@ -30,23 +30,22 @@ extern crate winit;
// the two. // the two.
extern crate vulkano_win; extern crate vulkano_win;
use vulkano_win::VkSurfaceBuild;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState}; use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::device::Device; use vulkano::device::{Device, DeviceExtensions};
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract}; use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::SwapchainImage; use vulkano::image::SwapchainImage;
use vulkano::instance::Instance; use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::instance::PhysicalDevice;
use vulkano::pipeline::GraphicsPipeline; use vulkano::pipeline::GraphicsPipeline;
use vulkano::pipeline::viewport::Viewport; use vulkano::pipeline::viewport::Viewport;
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError}; use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
use vulkano::swapchain; use vulkano::swapchain;
use vulkano::sync::GpuFuture; use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync::now; use vulkano::sync;
use winit::Window; use vulkano_win::VkSurfaceBuild;
use winit::{EventsLoop, Window, WindowBuilder, Event, WindowEvent};
use std::sync::Arc; use std::sync::Arc;
@ -97,7 +96,7 @@ fn main() {
let extensions = vulkano_win::required_extensions(); let extensions = vulkano_win::required_extensions();
// Now creating the instance. // Now creating the instance.
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance") Instance::new(None, &extensions, None).unwrap()
}; };
// We then choose which physical device to use. // We then choose which physical device to use.
@ -114,7 +113,7 @@ fn main() {
// //
// For the sake of the example we are just going to use the first device, which should work // For the sake of the example we are just going to use the first device, which should work
// most of the time. // most of the time.
let physical = PhysicalDevice::enumerate(&instance).next().expect("no device available"); let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
// Some little debug infos. // Some little debug infos.
println!("Using device: {} (type: {:?})", physical.name(), physical.ty()); println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
@ -129,8 +128,8 @@ fn main() {
// //
// This returns a `vulkano::swapchain::Surface` object that contains both a cross-platform winit // This returns a `vulkano::swapchain::Surface` object that contains both a cross-platform winit
// window and a cross-platform Vulkan surface that represents the surface of the window. // window and a cross-platform Vulkan surface that represents the surface of the window.
let mut events_loop = winit::EventsLoop::new(); let mut events_loop = EventsLoop::new();
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
let window = surface.window(); let window = surface.window();
// The next step is to choose which GPU queue will execute our draw commands. // The next step is to choose which GPU queue will execute our draw commands.
@ -146,7 +145,7 @@ fn main() {
let queue_family = physical.queue_families().find(|&q| { let queue_family = physical.queue_families().find(|&q| {
// We take the first queue that supports drawing to our window. // We take the first queue that supports drawing to our window.
q.supports_graphics() && surface.is_supported(q).unwrap_or(false) q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
}).expect("couldn't find a graphical queue family"); }).unwrap();
// Now initializing the device. This is probably the most important object of Vulkan. // Now initializing the device. This is probably the most important object of Vulkan.
// //
@ -167,43 +166,24 @@ fn main() {
// much it should prioritize queues between one another. // much it should prioritize queues between one another.
// //
// The list of created queues is returned by the function alongside with the device. // The list of created queues is returned by the function alongside with the device.
let (device, mut queues) = { let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
let device_ext = vulkano::device::DeviceExtensions { let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
khr_swapchain: true, [(queue_family, 0.5)].iter().cloned()).unwrap();
.. vulkano::device::DeviceExtensions::none()
};
Device::new(physical, physical.supported_features(), &device_ext,
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
};
// Since we can request multiple queues, the `queues` variable is in fact an iterator. In this // Since we can request multiple queues, the `queues` variable is in fact an iterator. In this
// example we use only one queue, so we just retrieve the first and only element of the // example we use only one queue, so we just retrieve the first and only element of the
// iterator and throw it away. // iterator and throw it away.
let queue = queues.next().unwrap(); let queue = queues.next().unwrap();
// The dimensions of the window, only used to initially setup the swapchain.
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
// convert to physical pixels
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1]
} else {
// The window no longer exists so exit the application.
return;
};
// Before we can draw on the surface, we have to create what is called a swapchain. Creating // Before we can draw on the surface, we have to create what is called a swapchain. Creating
// a swapchain allocates the color buffers that will contain the image that will ultimately // a swapchain allocates the color buffers that will contain the image that will ultimately
// be visible on the screen. These images are returned alongside with the swapchain. // be visible on the screen. These images are returned alongside with the swapchain.
let (mut swapchain, images) = { let (mut swapchain, images) = {
// Querying the capabilities of the surface. When we create the swapchain we can only // Querying the capabilities of the surface. When we create the swapchain we can only
// pass values that are allowed by the capabilities. // pass values that are allowed by the capabilities.
let caps = surface.capabilities(physical) let caps = surface.capabilities(physical).unwrap();
.expect("failed to get surface capabilities");
// We choose the dimensions of the swapchain to match the current extent of the surface. let usage = caps.supported_usage_flags;
// If `caps.current_extent` is `None`, this means that the window size will be determined
// by the dimensions of the swapchain, in which case we just use the width and height defined above.
// The alpha mode indicates how the alpha value of the final image will behave. For example // The alpha mode indicates how the alpha value of the final image will behave. For example
// you can choose whether the window will be opaque or transparent. // you can choose whether the window will be opaque or transparent.
@ -212,11 +192,30 @@ fn main() {
// Choosing the internal format that the images will have. // Choosing the internal format that the images will have.
let format = caps.supported_formats[0].0; let format = caps.supported_formats[0].0;
// The dimensions of the window, only used to initially setup the swapchain.
// NOTE:
// On some drivers the swapchain dimensions are specified by `caps.current_extent` and the
// swapchain size must use these dimensions.
// These dimensions are always the same as the window dimensions
//
// However other drivers dont specify a value i.e. `caps.current_extent` is `None`
// These drivers will allow anything but the only sensible value is the window dimensions.
//
// Because for both of these cases, the swapchain needs to be the window dimensions, we just use that.
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
// convert to physical pixels
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1]
} else {
// The window no longer exists so exit the application.
return;
};
// Please take a look at the docs for the meaning of the parameters we didn't mention. // Please take a look at the docs for the meaning of the parameters we didn't mention.
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
initial_dimensions, 1, caps.supported_usage_flags, &queue, initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, PresentMode::Fifo, true, None).unwrap()
None).expect("failed to create swapchain")
}; };
// We now create a buffer that will store the shape of our triangle. // We now create a buffer that will store the shape of our triangle.
@ -229,11 +228,11 @@ fn main() {
Vertex { position: [-0.5, -0.25] }, Vertex { position: [-0.5, -0.25] },
Vertex { position: [0.0, 0.5] }, Vertex { position: [0.0, 0.5] },
Vertex { position: [0.25, -0.1] } Vertex { position: [0.25, -0.1] }
].iter().cloned()).expect("failed to create buffer") ].iter().cloned()).unwrap()
}; };
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module"); let vs = vs::Shader::load(device.clone()).unwrap();
let fs = fs::Shader::load(device.clone()).expect("failed to create shader module"); let fs = fs::Shader::load(device.clone()).unwrap();
// At this point, OpenGL initialization would be finished. However in Vulkan it is not. OpenGL // At this point, OpenGL initialization would be finished. However in Vulkan it is not. OpenGL
// implicitly does a lot of computation whenever you draw. In Vulkan, you have to do all this // implicitly does a lot of computation whenever you draw. In Vulkan, you have to do all this
@ -242,7 +241,8 @@ fn main() {
// The next step is to create a *render pass*, which is an object that describes where the // The next step is to create a *render pass*, which is an object that describes where the
// output of the graphics pipeline will go. It describes the layout of the images // output of the graphics pipeline will go. It describes the layout of the images
// where the colors, depth and/or stencil information will be written. // where the colors, depth and/or stencil information will be written.
let render_pass = Arc::new(single_pass_renderpass!(device.clone(), let render_pass = Arc::new(single_pass_renderpass!(
device.clone(),
attachments: { attachments: {
// `color` is a custom name we give to the first and only attachment. // `color` is a custom name we give to the first and only attachment.
color: { color: {
@ -254,9 +254,8 @@ fn main() {
store: Store, store: Store,
// `format: <ty>` indicates the type of the format of the image. This has to // `format: <ty>` indicates the type of the format of the image. This has to
// be one of the types of the `vulkano::format` module (or alternatively one // be one of the types of the `vulkano::format` module (or alternatively one
// of your structs that implements the `FormatDesc` trait). Here we use the // of your structs that implements the `FormatDesc` trait). Here we use the
// generic `vulkano::format::Format` enum because we don't know the format in // same format as the swapchain.
// advance.
format: swapchain.format(), format: swapchain.format(),
// TODO: // TODO:
samples: 1, samples: 1,
@ -324,7 +323,7 @@ fn main() {
// //
// Destroying the `GpuFuture` blocks until the GPU is finished executing it. In order to avoid // Destroying the `GpuFuture` blocks until the GPU is finished executing it. In order to avoid
// that, we store the submission of the previous frame here. // that, we store the submission of the previous frame here.
let mut previous_frame_end = Box::new(now(device.clone())) as Box<GpuFuture>; let mut previous_frame_end = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
loop { loop {
// It is important to call this function from time to time, otherwise resources will keep // It is important to call this function from time to time, otherwise resources will keep
@ -336,7 +335,7 @@ fn main() {
// Whenever the window resizes we need to recreate everything dependent on the window size. // Whenever the window resizes we need to recreate everything dependent on the window size.
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport. // In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
if recreate_swapchain { if recreate_swapchain {
// Get the new dimensions for the viewport/framebuffers. // Get the new dimensions of the window.
let dimensions = if let Some(dimensions) = window.get_inner_size() { let dimensions = if let Some(dimensions) = window.get_inner_size() {
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into(); let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
[dimensions.0, dimensions.1] [dimensions.0, dimensions.1]
@ -376,6 +375,9 @@ fn main() {
Err(err) => panic!("{:?}", err) Err(err) => panic!("{:?}", err)
}; };
// Specify the color to clear the framebuffer with i.e. blue
let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
// 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.
// //
@ -393,17 +395,14 @@ fn main() {
// The third parameter builds the list of values to clear the attachments with. The API // The third parameter builds the list of values to clear the attachments with. The API
// is similar to the list of attachments when building the framebuffers, except that // is similar to the list of attachments when building the framebuffers, except that
// only the attachments that use `load: Clear` appear in the list. // only the attachments that use `load: Clear` appear in the list.
.begin_render_pass(framebuffers[image_num].clone(), false, .begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
vec![[0.0, 0.0, 1.0, 1.0].into()])
.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.
// Since we used an `EmptyPipeline` object, the objects have to be `()`. // Since we used an `EmptyPipeline` object, the objects have to be `()`.
.draw(pipeline.clone(), .draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
&dynamic_state,
vertex_buffer.clone(), (), ())
.unwrap() .unwrap()
// We leave the render pass by calling `draw_end`. Note that if we had multiple // We leave the render pass by calling `draw_end`. Note that if we had multiple
@ -431,13 +430,13 @@ fn main() {
Ok(future) => { Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>; previous_frame_end = Box::new(future) as Box<_>;
} }
Err(vulkano::sync::FlushError::OutOfDate) => { Err(FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame_end = Box::new(vulkano::sync::now(device.clone())) as Box<_>; previous_frame_end = Box::new(sync::now(device.clone())) as Box<_>;
} }
} }
@ -454,8 +453,8 @@ fn main() {
let mut done = false; let mut done = false;
events_loop.poll_events(|ev| { events_loop.poll_events(|ev| {
match ev { match ev {
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true, Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true, Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => () _ => ()
} }
}); });
@ -463,7 +462,7 @@ fn main() {
} }
} }
/// This method is called once during initialization then again whenever the window is resized /// This method is called once during initialization, then again whenever the window is resized
fn window_size_dependent_setup( fn window_size_dependent_setup(
images: &[Arc<SwapchainImage<Window>>], images: &[Arc<SwapchainImage<Window>>],
render_pass: Arc<RenderPassAbstract + Send + Sync>, render_pass: Arc<RenderPassAbstract + Send + Sync>,

View File

@ -107,10 +107,6 @@
//! //!
//! The options available are in the form of the following attributes: //! The options available are in the form of the following attributes:
//! //!
//! ## `mod_name: ...`
//!
//! Specifies the identifier for the module that the generated code goes in.
//!
//! ## `ty: "..."` //! ## `ty: "..."`
//! //!
//! This defines what shader type the given GLSL source will be compiled into. //! This defines what shader type the given GLSL source will be compiled into.