mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 00:04:15 +00:00
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:
parent
c57289f536
commit
9d46e08cc7
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
target
|
||||
/Cargo.lock
|
||||
.cargo
|
||||
examples/src/bin/triangle.png
|
||||
|
@ -17,17 +17,14 @@
|
||||
extern crate vulkano;
|
||||
extern crate vulkano_shaders;
|
||||
|
||||
use vulkano::buffer::BufferUsage;
|
||||
use vulkano::buffer::CpuAccessibleBuffer;
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::InstanceExtensions;
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||
use vulkano::pipeline::ComputePipeline;
|
||||
use vulkano::sync::now;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::sync;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -52,12 +49,10 @@ void main() {
|
||||
|
||||
fn main() {
|
||||
// As with other examples, the first step is to create an instance.
|
||||
let instance = Instance::new(None, &InstanceExtensions::none(), None)
|
||||
.expect("failed to create Vulkan instance");
|
||||
let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
|
||||
|
||||
// Choose which physical device to use.
|
||||
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
|
||||
.next().expect("no device available");
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
|
||||
// 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();
|
||||
|
||||
// Now initializing the device.
|
||||
let (device, mut queues) = {
|
||||
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(),
|
||||
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
||||
&DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
|
||||
// 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
|
||||
@ -97,10 +90,8 @@ fn main() {
|
||||
// If you are familiar with graphics pipeline, the principle is the same except that compute
|
||||
// pipelines are much simpler to create.
|
||||
let pipeline = Arc::new({
|
||||
let shader = cs::Shader::load(device.clone())
|
||||
.expect("failed to create shader module");
|
||||
ComputePipeline::new(device.clone(), &shader.main_entry_point(), &())
|
||||
.expect("failed to create compute pipeline")
|
||||
let shader = cs::Shader::load(device.clone()).unwrap();
|
||||
ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap()
|
||||
});
|
||||
|
||||
// We start by creating the buffer that will store the data.
|
||||
@ -108,8 +99,7 @@ fn main() {
|
||||
// Iterator that produces the data.
|
||||
let data_iter = (0 .. 65536u32).map(|n| n);
|
||||
// Builds the buffer and fills it with this iterator.
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
|
||||
data_iter).expect("failed to create buffer")
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
||||
};
|
||||
|
||||
// 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.
|
||||
// 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()
|
||||
|
||||
// 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
|
||||
// check it out.
|
||||
// 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 {
|
||||
assert_eq!(data_buffer_content[n as usize], n * 12);
|
||||
}
|
||||
|
@ -33,18 +33,16 @@ extern crate vulkano_shaders;
|
||||
extern crate winit;
|
||||
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::device::Device;
|
||||
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 winit::{EventsLoop, WindowBuilder, Event, WindowEvent};
|
||||
|
||||
use cgmath::Matrix4;
|
||||
use cgmath::SquareMatrix;
|
||||
@ -53,68 +51,61 @@ use cgmath::Vector3;
|
||||
mod frame;
|
||||
mod triangle_draw_system;
|
||||
|
||||
use frame::*;
|
||||
use triangle_draw_system::*;
|
||||
|
||||
fn main() {
|
||||
// Basic initialization. See the triangle example if you want more details about this.
|
||||
let instance = {
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
|
||||
};
|
||||
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
|
||||
.next().expect("no device available");
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
let instance = Instance::new(None, &extensions, None).unwrap();
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
|
||||
let mut events_loop = EventsLoop::new();
|
||||
let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
let window = surface.window();
|
||||
|
||||
let queue_family = physical.queue_families().find(|&q| {
|
||||
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
|
||||
}).expect("couldn't find a graphical queue family");
|
||||
|
||||
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,
|
||||
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
|
||||
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 mut dimensions;
|
||||
|
||||
let (mut swapchain, mut images) = {
|
||||
let caps = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities");
|
||||
let dimensions = if let Some(dimensions) = window.get_inner_size() {
|
||||
let caps = surface.capabilities(physical).unwrap();
|
||||
|
||||
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();
|
||||
[dimensions.0, dimensions.1]
|
||||
} else {
|
||||
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,
|
||||
dimensions, 1, caps.supported_usage_flags, &queue,
|
||||
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true,
|
||||
None).expect("failed to create swapchain")
|
||||
initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
|
||||
PresentMode::Fifo, true, None).unwrap()
|
||||
};
|
||||
|
||||
|
||||
// Here is the basic initialization for the deferred system.
|
||||
let mut frame_system = frame::FrameSystem::new(queue.clone(), swapchain.format());
|
||||
let triangle_draw_system = triangle_draw_system::TriangleDrawSystem::new(queue.clone(),
|
||||
frame_system.deferred_subpass());
|
||||
let mut frame_system = FrameSystem::new(queue.clone(), swapchain.format());
|
||||
let triangle_draw_system = TriangleDrawSystem::new(queue.clone(), frame_system.deferred_subpass());
|
||||
|
||||
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 {
|
||||
previous_frame_end.cleanup_finished();
|
||||
|
||||
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();
|
||||
[dimensions.0, dimensions.1]
|
||||
} else {
|
||||
@ -148,18 +139,18 @@ fn main() {
|
||||
let mut after_future = None;
|
||||
while let Some(pass) = frame.next_pass() {
|
||||
match pass {
|
||||
frame::Pass::Deferred(mut draw_pass) => {
|
||||
Pass::Deferred(mut draw_pass) => {
|
||||
let cb = triangle_draw_system.draw(draw_pass.viewport_dimensions());
|
||||
draw_pass.execute(cb);
|
||||
}
|
||||
frame::Pass::Lighting(mut lighting) => {
|
||||
Pass::Lighting(mut lighting) => {
|
||||
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.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.0, 0.5, -0.05), [0.0, 0.0, 1.0]);
|
||||
}
|
||||
frame::Pass::Finished(af) => {
|
||||
Pass::Finished(af) => {
|
||||
after_future = Some(af);
|
||||
}
|
||||
}
|
||||
@ -173,21 +164,21 @@ fn main() {
|
||||
Ok(future) => {
|
||||
previous_frame_end = Box::new(future) as Box<_>;
|
||||
}
|
||||
Err(vulkano::sync::FlushError::OutOfDate) => {
|
||||
Err(FlushError::OutOfDate) => {
|
||||
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) => {
|
||||
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;
|
||||
events_loop.poll_events(|ev| {
|
||||
match ev {
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true,
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true,
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
|
||||
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
|
||||
_ => ()
|
||||
}
|
||||
});
|
||||
|
@ -7,23 +7,36 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
extern crate cgmath;
|
||||
extern crate image;
|
||||
extern crate winit;
|
||||
|
||||
#[macro_use]
|
||||
extern crate vulkano;
|
||||
extern crate vulkano_shaders;
|
||||
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::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;
|
||||
|
||||
@ -32,33 +45,32 @@ fn main() {
|
||||
// `triangle` example if you haven't done so yet.
|
||||
|
||||
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)
|
||||
.next().expect("no device available");
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
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 queue_family = physical.queue_families().find(|&q| q.supports_graphics() &&
|
||||
surface.is_supported(q).unwrap_or(false))
|
||||
.expect("couldn't find a graphical queue family");
|
||||
let queue_family = physical.queue_families().find(|&q|
|
||||
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
|
||||
).unwrap();
|
||||
|
||||
let device_ext = vulkano::device::DeviceExtensions {
|
||||
khr_swapchain: true,
|
||||
.. vulkano::device::DeviceExtensions::none()
|
||||
};
|
||||
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 device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
|
||||
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 (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
|
||||
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
|
||||
[dimensions.0, dimensions.1]
|
||||
@ -66,15 +78,10 @@ fn main() {
|
||||
// The window no longer exists so exit the application.
|
||||
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,
|
||||
format, dimensions, 1,
|
||||
usage, &queue, vulkano::swapchain::SurfaceTransform::Identity,
|
||||
alpha,
|
||||
vulkano::swapchain::PresentMode::Fifo, true, None).expect("failed to create swapchain")
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
|
||||
initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
|
||||
PresentMode::Fifo, true, None).unwrap()
|
||||
};
|
||||
|
||||
|
||||
@ -82,17 +89,19 @@ fn main() {
|
||||
struct Vertex { position: [f32; 2] }
|
||||
impl_vertex!(Vertex, position);
|
||||
|
||||
let vertex_buffer = vulkano::buffer::cpu_access::CpuAccessibleBuffer::<[Vertex]>
|
||||
::from_iter(device.clone(), vulkano::buffer::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 ] },
|
||||
].iter().cloned()).expect("failed to create buffer");
|
||||
let vertex_buffer = CpuAccessibleBuffer::<[Vertex]>::from_iter(
|
||||
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 ] },
|
||||
].iter().cloned()
|
||||
).unwrap();
|
||||
|
||||
let vs = vs::Shader::load(device.clone()).expect("failed to create shader module");
|
||||
let fs = fs::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()).unwrap();
|
||||
|
||||
let render_pass = Arc::new(
|
||||
single_pass_renderpass!(device.clone(),
|
||||
@ -113,36 +122,33 @@ fn main() {
|
||||
|
||||
let (texture, tex_future) = {
|
||||
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();
|
||||
|
||||
vulkano::image::immutable::ImmutableImage::from_iter(
|
||||
ImmutableImage::from_iter(
|
||||
image_data.iter().cloned(),
|
||||
vulkano::image::Dimensions::Dim2d { width: 93, height: 93 },
|
||||
vulkano::format::R8G8B8A8Srgb,
|
||||
queue.clone()).unwrap()
|
||||
Dimensions::Dim2d { width: 93, height: 93 },
|
||||
Format::R8G8B8A8Srgb,
|
||||
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,
|
||||
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()
|
||||
let pipeline = Arc::new(GraphicsPipeline::start()
|
||||
.vertex_input_single_buffer::<Vertex>()
|
||||
.vertex_shader(vs.main_entry_point(), ())
|
||||
.triangle_strip()
|
||||
.viewports_dynamic_scissors_irrelevant(1)
|
||||
.fragment_shader(fs.main_entry_point(), ())
|
||||
.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())
|
||||
.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()
|
||||
.build().unwrap()
|
||||
);
|
||||
@ -151,7 +157,6 @@ fn main() {
|
||||
let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state);
|
||||
|
||||
let mut recreate_swapchain = false;
|
||||
|
||||
let mut previous_frame_end = Box::new(tex_future) as Box<GpuFuture>;
|
||||
|
||||
loop {
|
||||
@ -166,7 +171,7 @@ fn main() {
|
||||
|
||||
let (new_swapchain, new_images) = match swapchain.recreate_with_dimension(dimensions) {
|
||||
Ok(r) => r,
|
||||
Err(vulkano::swapchain::SwapchainCreationError::UnsupportedDimensions) => continue,
|
||||
Err(SwapchainCreationError::UnsupportedDimensions) => continue,
|
||||
Err(err) => panic!("{:?}", err)
|
||||
};
|
||||
|
||||
@ -176,24 +181,20 @@ fn main() {
|
||||
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,
|
||||
Err(vulkano::swapchain::AcquireError::OutOfDate) => {
|
||||
Err(AcquireError::OutOfDate) => {
|
||||
recreate_swapchain = true;
|
||||
continue;
|
||||
}
|
||||
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()
|
||||
.begin_render_pass(
|
||||
framebuffers[image_num].clone(), false,
|
||||
vec![[0.0, 0.0, 1.0, 1.0].into()]).unwrap()
|
||||
.draw(pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vertex_buffer.clone(),
|
||||
set.clone(), ()).unwrap()
|
||||
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values).unwrap()
|
||||
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), set.clone(), ()).unwrap()
|
||||
.end_render_pass().unwrap()
|
||||
.build().unwrap();
|
||||
|
||||
@ -206,21 +207,21 @@ fn main() {
|
||||
Ok(future) => {
|
||||
previous_frame_end = Box::new(future) as Box<_>;
|
||||
}
|
||||
Err(vulkano::sync::FlushError::OutOfDate) => {
|
||||
Err(FlushError::OutOfDate) => {
|
||||
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) => {
|
||||
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;
|
||||
events_loop.poll_events(|ev| {
|
||||
match ev {
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true,
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true,
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = 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(
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
render_pass: Arc<RenderPassAbstract + Send + Sync>,
|
||||
|
@ -72,25 +72,17 @@ extern crate vulkano_shaders;
|
||||
use std::sync::Arc;
|
||||
use image::ImageBuffer;
|
||||
use image::Rgba;
|
||||
use vulkano::buffer::BufferUsage;
|
||||
use vulkano::buffer::CpuAccessibleBuffer;
|
||||
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||
use vulkano::command_buffer::CommandBuffer;
|
||||
use vulkano::command_buffer::DynamicState;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBuffer, DynamicState};
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::format::Format;
|
||||
use vulkano::framebuffer::Framebuffer;
|
||||
use vulkano::framebuffer::Subpass;
|
||||
use vulkano::image::AttachmentImage;
|
||||
use vulkano::image::Dimensions;
|
||||
use vulkano::image::StorageImage;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::InstanceExtensions;
|
||||
use vulkano::instance::PhysicalDevice;
|
||||
use vulkano::framebuffer::{Framebuffer, Subpass};
|
||||
use vulkano::image::{AttachmentImage, Dimensions, StorageImage};
|
||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::format::ClearValue;
|
||||
|
||||
mod vs {
|
||||
vulkano_shaders::shader!{
|
||||
@ -122,34 +114,30 @@ void main() {
|
||||
|
||||
fn main() {
|
||||
// The usual Vulkan initialization.
|
||||
let instance = Instance::new(None, &InstanceExtensions::none(), None)
|
||||
.expect("failed to create instance");
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().expect("no device available");
|
||||
let queue_family = physical.queue_families()
|
||||
.find(|&q| q.supports_graphics())
|
||||
.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 instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
let queue_family = physical.queue_families().find(|&q| q.supports_graphics()).unwrap();
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
||||
&DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
// Creating our intermediate multisampled image.
|
||||
//
|
||||
// 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.
|
||||
let intermediary = AttachmentImage::transient_multisampled(device.clone(), [1024, 1024],
|
||||
4, Format::R8G8B8A8Unorm).unwrap();
|
||||
let intermediary = AttachmentImage::transient_multisampled(device.clone(),
|
||||
[1024, 1024], 4, Format::R8G8B8A8Unorm).unwrap();
|
||||
|
||||
// This is the final image that will receive the anti-aliased triangle.
|
||||
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
|
||||
// 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
|
||||
// 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: {
|
||||
// The first framebuffer attachment is the intermediary image.
|
||||
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,
|
||||
// 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 fs = fs::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()).unwrap();
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Vertex {
|
||||
position: [f32; 2],
|
||||
}
|
||||
impl_vertex!(Vertex, position);
|
||||
|
||||
let vertex1 = Vertex { position: [-0.5, -0.5] };
|
||||
let vertex2 = Vertex { position: [ 0.0, 0.5] };
|
||||
let vertex3 = Vertex { position: [ 0.5, -0.25] };
|
||||
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()
|
||||
.vertex_input_single_buffer::<Vertex>()
|
||||
@ -225,11 +214,10 @@ fn main() {
|
||||
};
|
||||
|
||||
let buf = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
|
||||
(0 .. 1024 * 1024 * 4).map(|_| 0u8))
|
||||
.expect("failed to create buffer");
|
||||
(0 .. 1024 * 1024 * 4).map(|_| 0u8)).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()
|
||||
|
||||
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
|
||||
@ -245,8 +233,7 @@ fn main() {
|
||||
.unwrap();
|
||||
|
||||
let finished = command_buffer.execute(queue.clone()).unwrap();
|
||||
finished.then_signal_fence_and_flush().unwrap()
|
||||
.wait(None).unwrap();
|
||||
finished.then_signal_fence_and_flush().unwrap().wait(None).unwrap();
|
||||
|
||||
let buffer_content = buf.read().unwrap();
|
||||
let image = ImageBuffer::<Rgba<u8>, _>::from_raw(1024, 1024, &buffer_content[..]).unwrap();
|
||||
|
@ -11,17 +11,14 @@
|
||||
extern crate vulkano;
|
||||
extern crate vulkano_shaders;
|
||||
|
||||
use vulkano::buffer::BufferUsage;
|
||||
use vulkano::buffer::CpuAccessibleBuffer;
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::InstanceExtensions;
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||
use vulkano::pipeline::ComputePipeline;
|
||||
use vulkano::sync::now;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::sync;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -55,29 +52,26 @@ void main() {
|
||||
|
||||
fn main() {
|
||||
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 (device, mut queues) = {
|
||||
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(),
|
||||
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
||||
&DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
let shader = cs::Shader::load(device.clone())
|
||||
.expect("failed to create shader module");
|
||||
let shader = cs::Shader::load(device.clone()).unwrap();
|
||||
let pipeline = Arc::new(ComputePipeline::new(device.clone(), &shader.main_entry_point(), &()).unwrap());
|
||||
|
||||
let data_buffer = {
|
||||
let data_iter = (0 .. 65536u32).map(|n| n);
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
|
||||
data_iter).expect("failed to create buffer")
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
||||
};
|
||||
|
||||
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
||||
.add_buffer(data_buffer.clone()).unwrap()
|
||||
.build().unwrap()
|
||||
let set = Arc::new(
|
||||
PersistentDescriptorSet::start(pipeline.clone(), 0)
|
||||
.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.
|
||||
let push_constants = cs::ty::PushConstantData {
|
||||
multiple: 1,
|
||||
@ -88,18 +82,18 @@ fn main() {
|
||||
// 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.
|
||||
// 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()
|
||||
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), push_constants).unwrap()
|
||||
.build().unwrap();
|
||||
|
||||
let future = now(device.clone())
|
||||
let future = sync::now(device.clone())
|
||||
.then_execute(queue.clone(), command_buffer).unwrap()
|
||||
.then_signal_fence_and_flush().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 {
|
||||
assert_eq!(data_buffer_content[n as usize], n * 1 + 1);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ use vulkano::descriptor::pipeline_layout::PipelineLayoutDesc;
|
||||
use vulkano::descriptor::pipeline_layout::PipelineLayoutDescPcRange;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::format;
|
||||
use vulkano::format::Format;
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
|
||||
use vulkano::image::SwapchainImage;
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
@ -65,77 +65,55 @@ pub struct Vertex {
|
||||
impl_vertex!(Vertex, position, color);
|
||||
|
||||
fn main() {
|
||||
let instance = vk::instance::Instance::new(
|
||||
None,
|
||||
&vulkano_win::required_extensions(),
|
||||
None,
|
||||
).expect("no instance with surface extension");
|
||||
let physical = vk::instance::PhysicalDevice::enumerate(&instance)
|
||||
.next()
|
||||
.expect("no graphics device");
|
||||
let instance = vk::instance::Instance::new(None, &vulkano_win::required_extensions(), None).unwrap();
|
||||
let physical = vk::instance::PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
let surface = winit::WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap();
|
||||
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 graphical_queue_family = physical
|
||||
.queue_families()
|
||||
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
|
||||
.expect("couldn't find a graphic queue family");
|
||||
let device_ext = DeviceExtensions {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::none()
|
||||
};
|
||||
Device::new(
|
||||
physical.clone(),
|
||||
physical.supported_features(),
|
||||
&device_ext,
|
||||
[(graphical_queue_family, 0.5)].iter().cloned(),
|
||||
).expect("failed to create device")
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
|
||||
Device::new(physical, physical.supported_features(), &device_ext,
|
||||
[(queue_family, 0.5)].iter().cloned()).unwrap()
|
||||
};
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let initial_dimensions = if let Some(dimensions) = window.get_inner_size() {
|
||||
let dimensions: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
|
||||
[dimensions.0, dimensions.1]
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let graphics_queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let caps = surface
|
||||
.capabilities(device.physical_device())
|
||||
.expect("failure to get surface capabilities");
|
||||
let caps = surface.capabilities(physical).unwrap();
|
||||
let usage = caps.supported_usage_flags;
|
||||
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
||||
let format = caps.supported_formats[0].0;
|
||||
let dimensions = caps.current_extent.unwrap_or([1024, 768]);
|
||||
let usage = caps.supported_usage_flags;
|
||||
|
||||
Swapchain::new(
|
||||
device.clone(),
|
||||
surface.clone(),
|
||||
caps.min_image_count,
|
||||
format,
|
||||
dimensions,
|
||||
1,
|
||||
usage,
|
||||
&graphics_queue,
|
||||
SurfaceTransform::Identity,
|
||||
alpha,
|
||||
PresentMode::Fifo,
|
||||
true,
|
||||
None,
|
||||
).expect("failed to create swapchain")
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, initial_dimensions,
|
||||
1, usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).unwrap()
|
||||
};
|
||||
|
||||
let render_pass = Arc::new(
|
||||
single_pass_renderpass!(
|
||||
device.clone(), attachments: {
|
||||
color: {
|
||||
load: Clear,
|
||||
store: Store,
|
||||
format: swapchain.format(),
|
||||
samples: 1,
|
||||
}
|
||||
},
|
||||
pass: {
|
||||
color: [color],
|
||||
depth_stencil: {}
|
||||
let render_pass = Arc::new(single_pass_renderpass!(
|
||||
device.clone(),
|
||||
attachments: {
|
||||
color: {
|
||||
load: Clear,
|
||||
store: Store,
|
||||
format: swapchain.format(),
|
||||
samples: 1,
|
||||
}
|
||||
).unwrap(),
|
||||
);
|
||||
},
|
||||
pass: {
|
||||
color: [color],
|
||||
depth_stencil: {}
|
||||
}
|
||||
).unwrap());
|
||||
|
||||
let vs = {
|
||||
let mut f = File::open("src/bin/runtime-shader/vert.spv")
|
||||
@ -155,10 +133,10 @@ fn main() {
|
||||
unsafe { ShaderModule::new(device.clone(), &v) }.unwrap()
|
||||
};
|
||||
|
||||
// This structure will tell Vulkan how input entries of our vertex shader
|
||||
// look like.
|
||||
// This structure will tell Vulkan how input entries of our vertex shader look like
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct VertInput;
|
||||
|
||||
unsafe impl ShaderInterfaceDef for VertInput {
|
||||
type Iter = VertInputIter;
|
||||
|
||||
@ -166,8 +144,10 @@ fn main() {
|
||||
VertInputIter(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct VertInputIter(u16);
|
||||
|
||||
impl Iterator for VertInputIter {
|
||||
type Item = ShaderInterfaceDefEntry;
|
||||
|
||||
@ -182,7 +162,7 @@ fn main() {
|
||||
self.0 += 1;
|
||||
return Some(ShaderInterfaceDefEntry {
|
||||
location: 1..2,
|
||||
format: format::Format::R32G32B32Sfloat,
|
||||
format: Format::R32G32B32Sfloat,
|
||||
name: Some(Cow::Borrowed("color"))
|
||||
})
|
||||
}
|
||||
@ -190,12 +170,13 @@ fn main() {
|
||||
self.0 += 1;
|
||||
return Some(ShaderInterfaceDefEntry {
|
||||
location: 0..1,
|
||||
format: format::Format::R32G32Sfloat,
|
||||
format: Format::R32G32Sfloat,
|
||||
name: Some(Cow::Borrowed("position"))
|
||||
})
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
// We must return exact number of entries left in iterator.
|
||||
@ -203,10 +184,12 @@ fn main() {
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
impl ExactSizeIterator for VertInputIter {
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for VertInputIter { }
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct VertOutput;
|
||||
|
||||
unsafe impl ShaderInterfaceDef for VertOutput {
|
||||
type Iter = VertOutputIter;
|
||||
|
||||
@ -214,10 +197,12 @@ fn main() {
|
||||
VertOutputIter(0)
|
||||
}
|
||||
}
|
||||
|
||||
// This structure will tell Vulkan how output entries (those passed to next
|
||||
// stage) of our vertex shader look like.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct VertOutputIter(u16);
|
||||
|
||||
impl Iterator for VertOutputIter {
|
||||
type Item = ShaderInterfaceDefEntry;
|
||||
|
||||
@ -227,20 +212,22 @@ fn main() {
|
||||
self.0 += 1;
|
||||
return Some(ShaderInterfaceDefEntry {
|
||||
location: 0..1,
|
||||
format: format::Format::R32G32B32Sfloat,
|
||||
format: Format::R32G32B32Sfloat,
|
||||
name: Some(Cow::Borrowed("v_color"))
|
||||
})
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = (1 - self.0) as usize;
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
impl ExactSizeIterator for VertOutputIter {
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for VertOutputIter { }
|
||||
|
||||
// This structure describes layout of this stage.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct VertLayout(ShaderStages);
|
||||
@ -248,22 +235,13 @@ fn main() {
|
||||
// Number of descriptor sets it takes.
|
||||
fn num_sets(&self) -> usize { 0 }
|
||||
// Number of entries (bindings) in each set.
|
||||
fn num_bindings_in_set(&self, set: usize) -> Option<usize> {
|
||||
match set { _ => None, }
|
||||
}
|
||||
fn num_bindings_in_set(&self, _set: usize) -> Option<usize> { None }
|
||||
// Descriptor descriptions.
|
||||
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
|
||||
match (set, binding) { _ => None, }
|
||||
}
|
||||
fn descriptor(&self, _set: usize, _binding: usize) -> Option<DescriptorDesc> { None }
|
||||
// Number of push constants ranges (think: number of push constants).
|
||||
fn num_push_constants_ranges(&self) -> usize { 0 }
|
||||
// Each push constant range in memory.
|
||||
fn push_constants_range(&self, num: usize) -> Option<PipelineLayoutDescPcRange> {
|
||||
if num != 0 || 0 == 0 { return None; }
|
||||
Some(PipelineLayoutDescPcRange { offset: 0,
|
||||
size: 0,
|
||||
stages: ShaderStages::all() })
|
||||
}
|
||||
fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> { None }
|
||||
}
|
||||
|
||||
// Same as with our vertex shader, but for fragment one instead.
|
||||
@ -278,6 +256,7 @@ fn main() {
|
||||
}
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct FragInputIter(u16);
|
||||
|
||||
impl Iterator for FragInputIter {
|
||||
type Item = ShaderInterfaceDefEntry;
|
||||
|
||||
@ -287,20 +266,22 @@ fn main() {
|
||||
self.0 += 1;
|
||||
return Some(ShaderInterfaceDefEntry {
|
||||
location: 0..1,
|
||||
format: format::Format::R32G32B32Sfloat,
|
||||
format: Format::R32G32B32Sfloat,
|
||||
name: Some(Cow::Borrowed("v_color"))
|
||||
})
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = (1 - self.0) as usize;
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
impl ExactSizeIterator for FragInputIter {
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for FragInputIter { }
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct FragOutput;
|
||||
unsafe impl ShaderInterfaceDef for FragOutput {
|
||||
@ -310,8 +291,10 @@ fn main() {
|
||||
FragOutputIter(0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct FragOutputIter(u16);
|
||||
|
||||
impl Iterator for FragOutputIter {
|
||||
type Item = ShaderInterfaceDefEntry;
|
||||
|
||||
@ -323,7 +306,7 @@ fn main() {
|
||||
self.0 += 1;
|
||||
return Some(ShaderInterfaceDefEntry {
|
||||
location: 0..1,
|
||||
format: format::Format::R32G32B32A32Sfloat,
|
||||
format: Format::R32G32B32A32Sfloat,
|
||||
name: Some(Cow::Borrowed("f_color"))
|
||||
})
|
||||
}
|
||||
@ -335,26 +318,18 @@ fn main() {
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
impl ExactSizeIterator for FragOutputIter {
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for FragOutputIter { }
|
||||
|
||||
// Layout same as with vertex shader.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct FragLayout(ShaderStages);
|
||||
unsafe impl PipelineLayoutDesc for FragLayout {
|
||||
fn num_sets(&self) -> usize { 0 }
|
||||
fn num_bindings_in_set(&self, set: usize) -> Option<usize> {
|
||||
match set { _ => None, }
|
||||
}
|
||||
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
|
||||
match (set, binding) { _ => None, }
|
||||
}
|
||||
fn num_bindings_in_set(&self, _set: usize) -> Option<usize> { None }
|
||||
fn descriptor(&self, _set: usize, _binding: usize) -> Option<DescriptorDesc> { None }
|
||||
fn num_push_constants_ranges(&self) -> usize { 0 }
|
||||
fn push_constants_range(&self, num: usize) -> Option<PipelineLayoutDescPcRange> {
|
||||
if num != 0 || 0 == 0 { return None; }
|
||||
Some(PipelineLayoutDescPcRange { offset: 0,
|
||||
size: 0,
|
||||
stages: ShaderStages::all() })
|
||||
}
|
||||
fn push_constants_range(&self, _num: usize) -> Option<PipelineLayoutDescPcRange> { None }
|
||||
}
|
||||
|
||||
// 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: [ 1.0, 1.0], color: [0.0, 0.0, 1.0] },
|
||||
].iter().cloned()
|
||||
).expect("failed to create vertex buffer");
|
||||
).unwrap();
|
||||
|
||||
// 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
|
||||
@ -448,28 +423,17 @@ fn main() {
|
||||
Err(err) => panic!("{:?}", err)
|
||||
};
|
||||
|
||||
let command_buffer = AutoCommandBufferBuilder::new(
|
||||
device.clone(),
|
||||
graphics_queue.family(),
|
||||
).unwrap()
|
||||
.begin_render_pass(
|
||||
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()
|
||||
|
||||
let clear_values = vec!([0.0, 0.0, 0.0, 1.0].into());
|
||||
let command_buffer = AutoCommandBufferBuilder::new(device.clone(), queue.family()).unwrap()
|
||||
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values).unwrap()
|
||||
.draw(graphics_pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ()).unwrap()
|
||||
.end_render_pass().unwrap()
|
||||
.build().unwrap();
|
||||
|
||||
let future = previous_frame_end.join(acquire_future)
|
||||
.then_execute(graphics_queue.clone(), command_buffer).unwrap()
|
||||
.then_swapchain_present(graphics_queue.clone(), swapchain.clone(), image_num)
|
||||
.then_execute(queue.clone(), command_buffer).unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
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(
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
render_pass: Arc<RenderPassAbstract + Send + Sync>,
|
||||
|
@ -11,17 +11,14 @@
|
||||
extern crate vulkano;
|
||||
extern crate vulkano_shaders;
|
||||
|
||||
use vulkano::buffer::BufferUsage;
|
||||
use vulkano::buffer::CpuAccessibleBuffer;
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::AutoCommandBufferBuilder;
|
||||
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::DeviceExtensions;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::InstanceExtensions;
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
|
||||
use vulkano::pipeline::ComputePipeline;
|
||||
use vulkano::sync::now;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::sync;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -53,16 +50,13 @@ void main() {
|
||||
|
||||
fn main() {
|
||||
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 (device, mut queues) = {
|
||||
Device::new(physical, physical.supported_features(), &DeviceExtensions::none(),
|
||||
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(),
|
||||
&DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let shader = cs::Shader::load(device.clone())
|
||||
.expect("failed to create shader module");
|
||||
let shader = cs::Shader::load(device.clone()).unwrap();
|
||||
let spec_consts = cs::SpecializationConstants {
|
||||
enable: 1,
|
||||
multiple: 1,
|
||||
@ -72,8 +66,7 @@ fn main() {
|
||||
|
||||
let data_buffer = {
|
||||
let data_iter = (0 .. 65536u32).map(|n| n);
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(),
|
||||
data_iter).expect("failed to create buffer")
|
||||
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
||||
};
|
||||
|
||||
let set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0)
|
||||
@ -85,13 +78,13 @@ fn main() {
|
||||
.dispatch([1024, 1, 1], pipeline.clone(), set.clone(), ()).unwrap()
|
||||
.build().unwrap();
|
||||
|
||||
let future = now(device.clone())
|
||||
let future = sync::now(device.clone())
|
||||
.then_execute(queue.clone(), command_buffer).unwrap()
|
||||
.then_signal_fence_and_flush().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 {
|
||||
assert_eq!(data_buffer_content[n as usize], n * 1 + 1);
|
||||
}
|
||||
|
@ -7,20 +7,18 @@
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
extern crate examples;
|
||||
extern crate cgmath;
|
||||
extern crate winit;
|
||||
extern crate time;
|
||||
|
||||
#[macro_use]
|
||||
extern crate vulkano;
|
||||
extern crate vulkano_win;
|
||||
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
extern crate winit;
|
||||
extern crate cgmath;
|
||||
extern crate time;
|
||||
extern crate examples;
|
||||
|
||||
use vulkano::buffer::cpu_pool::CpuBufferPool;
|
||||
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};
|
||||
@ -28,12 +26,15 @@ use vulkano::image::SwapchainImage;
|
||||
use vulkano::image::attachment::AttachmentImage;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::PhysicalDevice;
|
||||
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract};
|
||||
use vulkano::pipeline::vertex::TwoBuffersDefinition;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::pipeline::{GraphicsPipeline, GraphicsPipelineAbstract};
|
||||
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
use vulkano::swapchain;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::sync;
|
||||
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
|
||||
use winit::Window;
|
||||
|
||||
@ -41,17 +42,18 @@ use cgmath::{Matrix3, Matrix4, Point3, Vector3, Rad};
|
||||
|
||||
use examples::{Vertex, Normal, VERTICES, NORMALS, INDICES};
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::iter;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
fn main() {
|
||||
// The start of this example is exactly the same as `triangle`. You should read the
|
||||
// `triangle` example if you haven't done so yet.
|
||||
|
||||
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());
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
@ -69,24 +71,24 @@ fn main() {
|
||||
|
||||
let queue_family = physical.queue_families().find(|&q|
|
||||
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, mut queues) = Device::new(
|
||||
physical, physical.supported_features(), &device_ext, [(queue_family, 0.5)].iter().cloned()
|
||||
).expect("failed to create device");
|
||||
).unwrap();
|
||||
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
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 format = caps.supported_formats[0].0;
|
||||
let alpha = caps.supported_composite_alpha.iter().next().unwrap();
|
||||
|
||||
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();
|
||||
@ -100,8 +102,8 @@ fn main() {
|
||||
|
||||
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 fs = fs::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()).unwrap();
|
||||
|
||||
let render_pass = Arc::new(
|
||||
single_pass_renderpass!(device.clone(),
|
||||
@ -115,7 +117,7 @@ fn main() {
|
||||
depth: {
|
||||
load: Clear,
|
||||
store: DontCare,
|
||||
format: vulkano::format::Format::D16Unorm,
|
||||
format: Format::D16Unorm,
|
||||
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 recreate_swapchain = false;
|
||||
|
||||
let mut previous_frame = Box::new(vulkano::sync::now(device.clone())) as Box<GpuFuture>;
|
||||
let rotation_start = std::time::Instant::now();
|
||||
let mut previous_frame = Box::new(sync::now(device.clone())) as Box<GpuFuture>;
|
||||
let rotation_start = Instant::now();
|
||||
|
||||
loop {
|
||||
previous_frame.cleanup_finished();
|
||||
@ -178,7 +180,7 @@ fn main() {
|
||||
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()
|
||||
.build().unwrap()
|
||||
);
|
||||
@ -198,7 +200,8 @@ fn main() {
|
||||
vec![
|
||||
[0.0, 0.0, 1.0, 1.0].into(),
|
||||
1f32.into()
|
||||
]).unwrap()
|
||||
]
|
||||
).unwrap()
|
||||
.draw_indexed(
|
||||
pipeline.clone(),
|
||||
&DynamicState::none(),
|
||||
@ -216,13 +219,13 @@ fn main() {
|
||||
Ok(future) => {
|
||||
previous_frame = Box::new(future) as Box<_>;
|
||||
}
|
||||
Err(vulkano::sync::FlushError::OutOfDate) => {
|
||||
Err(sync::FlushError::OutOfDate) => {
|
||||
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) => {
|
||||
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(
|
||||
device: Arc<Device>,
|
||||
vs: &vs::Shader,
|
||||
|
@ -24,22 +24,22 @@ extern crate vulkano_shaders;
|
||||
extern crate winit;
|
||||
extern crate vulkano_win;
|
||||
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
|
||||
use vulkano::image::SwapchainImage;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::{Instance, PhysicalDevice};
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::swapchain;
|
||||
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
use vulkano::sync::now;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::swapchain;
|
||||
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;
|
||||
|
||||
@ -136,34 +136,26 @@ void main() {
|
||||
|
||||
|
||||
fn main() {
|
||||
let instance = {
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
|
||||
};
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
let instance = Instance::new(None, &extensions, None).unwrap();
|
||||
|
||||
let physical = vulkano::instance::PhysicalDevice::enumerate(&instance)
|
||||
.next().expect("no device available");
|
||||
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
|
||||
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
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 queue = physical.queue_families().find(|&q| {
|
||||
let queue_family = physical.queue_families().find(|&q| {
|
||||
q.supports_graphics() && surface.is_supported(q).unwrap_or(false)
|
||||
}).expect("couldn't find a graphical queue family");
|
||||
let (device, mut queues) = {
|
||||
let device_ext = vulkano::device::DeviceExtensions {
|
||||
khr_swapchain: true,
|
||||
.. vulkano::device::DeviceExtensions::none()
|
||||
};
|
||||
}).unwrap();
|
||||
|
||||
Device::new(physical, physical.supported_features(), &device_ext,
|
||||
[(queue, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
|
||||
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 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();
|
||||
[dimensions.0, dimensions.1]
|
||||
} else {
|
||||
@ -171,16 +163,13 @@ fn main() {
|
||||
};
|
||||
|
||||
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 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,
|
||||
dimensions, 1, caps.supported_usage_flags, &queue,
|
||||
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true,
|
||||
None).expect("failed to create swapchain")
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format, initial_dimensions,
|
||||
1, usage, &queue, SurfaceTransform::Identity, alpha, PresentMode::Fifo, true, None).unwrap()
|
||||
};
|
||||
|
||||
let vertex_buffer = {
|
||||
@ -198,15 +187,16 @@ fn main() {
|
||||
Vertex { position: [-0.9, 0.9] },
|
||||
Vertex { position: [-0.7, 0.6] },
|
||||
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 tcs = tcs::Shader::load(device.clone()).expect("failed to create shader module");
|
||||
let tes = tes::Shader::load(device.clone()).expect("failed to create shader module");
|
||||
let fs = fs::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()).unwrap();
|
||||
let tes = tes::Shader::load(device.clone()).unwrap();
|
||||
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: {
|
||||
color: {
|
||||
load: Clear,
|
||||
@ -239,14 +229,14 @@ fn main() {
|
||||
.unwrap());
|
||||
|
||||
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 framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut dynamic_state);
|
||||
|
||||
loop {
|
||||
previous_frame_end.cleanup_finished();
|
||||
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();
|
||||
[dimensions.0, dimensions.1]
|
||||
} else {
|
||||
@ -279,9 +269,7 @@ fn main() {
|
||||
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()])
|
||||
.unwrap()
|
||||
.draw(pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vertex_buffer.clone(), (), ())
|
||||
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
|
||||
.unwrap()
|
||||
.end_render_pass()
|
||||
.unwrap()
|
||||
@ -296,21 +284,21 @@ fn main() {
|
||||
Ok(future) => {
|
||||
previous_frame_end = Box::new(future) as Box<_>;
|
||||
}
|
||||
Err(vulkano::sync::FlushError::OutOfDate) => {
|
||||
Err(FlushError::OutOfDate) => {
|
||||
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) => {
|
||||
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;
|
||||
events_loop.poll_events(|ev| {
|
||||
match ev {
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true,
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true,
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = 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(
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
render_pass: Arc<RenderPassAbstract + Send + Sync>,
|
||||
|
@ -30,23 +30,22 @@ extern crate winit;
|
||||
// the two.
|
||||
extern crate vulkano_win;
|
||||
|
||||
use vulkano_win::VkSurfaceBuild;
|
||||
|
||||
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
|
||||
use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
|
||||
use vulkano::device::Device;
|
||||
use vulkano::device::{Device, DeviceExtensions};
|
||||
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
|
||||
use vulkano::image::SwapchainImage;
|
||||
use vulkano::instance::Instance;
|
||||
use vulkano::instance::PhysicalDevice;
|
||||
use vulkano::instance::{Instance, PhysicalDevice};
|
||||
use vulkano::pipeline::GraphicsPipeline;
|
||||
use vulkano::pipeline::viewport::Viewport;
|
||||
use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain, SwapchainCreationError};
|
||||
use vulkano::swapchain;
|
||||
use vulkano::sync::GpuFuture;
|
||||
use vulkano::sync::now;
|
||||
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;
|
||||
|
||||
@ -97,7 +96,7 @@ fn main() {
|
||||
let extensions = vulkano_win::required_extensions();
|
||||
|
||||
// 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.
|
||||
@ -114,7 +113,7 @@ fn main() {
|
||||
//
|
||||
// For the sake of the example we are just going to use the first device, which should work
|
||||
// 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.
|
||||
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
|
||||
// window and a cross-platform Vulkan surface that represents the surface of the window.
|
||||
let mut events_loop = winit::EventsLoop::new();
|
||||
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();
|
||||
|
||||
// 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| {
|
||||
// We take the first queue that supports drawing to our window.
|
||||
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.
|
||||
//
|
||||
@ -167,43 +166,24 @@ fn main() {
|
||||
// much it should prioritize queues between one another.
|
||||
//
|
||||
// The list of created queues is returned by the function alongside with the device.
|
||||
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,
|
||||
[(queue_family, 0.5)].iter().cloned()).expect("failed to create device")
|
||||
};
|
||||
let device_ext = DeviceExtensions { khr_swapchain: true, .. DeviceExtensions::none() };
|
||||
let (device, mut queues) = Device::new(physical, physical.supported_features(), &device_ext,
|
||||
[(queue_family, 0.5)].iter().cloned()).unwrap();
|
||||
|
||||
// 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
|
||||
// iterator and throw it away.
|
||||
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
|
||||
// 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.
|
||||
let (mut swapchain, images) = {
|
||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||
// pass values that are allowed by the capabilities.
|
||||
let caps = surface.capabilities(physical)
|
||||
.expect("failed to get surface capabilities");
|
||||
let caps = surface.capabilities(physical).unwrap();
|
||||
|
||||
// We choose the dimensions of the swapchain to match the current extent of the surface.
|
||||
// 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.
|
||||
let usage = caps.supported_usage_flags;
|
||||
|
||||
// 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.
|
||||
@ -212,11 +192,30 @@ fn main() {
|
||||
// Choosing the internal format that the images will have.
|
||||
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.
|
||||
Swapchain::new(device.clone(), surface.clone(), caps.min_image_count, format,
|
||||
initial_dimensions, 1, caps.supported_usage_flags, &queue,
|
||||
SurfaceTransform::Identity, alpha, PresentMode::Fifo, true,
|
||||
None).expect("failed to create swapchain")
|
||||
initial_dimensions, 1, usage, &queue, SurfaceTransform::Identity, alpha,
|
||||
PresentMode::Fifo, true, None).unwrap()
|
||||
|
||||
};
|
||||
|
||||
// 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.0, 0.5] },
|
||||
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 fs = fs::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()).unwrap();
|
||||
|
||||
// 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
|
||||
@ -242,7 +241,8 @@ fn main() {
|
||||
// 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
|
||||
// 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: {
|
||||
// `color` is a custom name we give to the first and only attachment.
|
||||
color: {
|
||||
@ -255,8 +255,7 @@ fn main() {
|
||||
// `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
|
||||
// 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
|
||||
// advance.
|
||||
// same format as the swapchain.
|
||||
format: swapchain.format(),
|
||||
// TODO:
|
||||
samples: 1,
|
||||
@ -324,7 +323,7 @@ fn main() {
|
||||
//
|
||||
// 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.
|
||||
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 {
|
||||
// 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.
|
||||
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
|
||||
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: (u32, u32) = dimensions.to_physical(window.get_hidpi_factor()).into();
|
||||
[dimensions.0, dimensions.1]
|
||||
@ -376,6 +375,9 @@ fn main() {
|
||||
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
|
||||
// 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
|
||||
// is similar to the list of attachments when building the framebuffers, except that
|
||||
// only the attachments that use `load: Clear` appear in the list.
|
||||
.begin_render_pass(framebuffers[image_num].clone(), false,
|
||||
vec![[0.0, 0.0, 1.0, 1.0].into()])
|
||||
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
|
||||
.unwrap()
|
||||
|
||||
// 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.
|
||||
// Since we used an `EmptyPipeline` object, the objects have to be `()`.
|
||||
.draw(pipeline.clone(),
|
||||
&dynamic_state,
|
||||
vertex_buffer.clone(), (), ())
|
||||
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ())
|
||||
.unwrap()
|
||||
|
||||
// We leave the render pass by calling `draw_end`. Note that if we had multiple
|
||||
@ -431,13 +430,13 @@ fn main() {
|
||||
Ok(future) => {
|
||||
previous_frame_end = Box::new(future) as Box<_>;
|
||||
}
|
||||
Err(vulkano::sync::FlushError::OutOfDate) => {
|
||||
Err(FlushError::OutOfDate) => {
|
||||
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) => {
|
||||
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;
|
||||
events_loop.poll_events(|ev| {
|
||||
match ev {
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::CloseRequested, .. } => done = true,
|
||||
winit::Event::WindowEvent { event: winit::WindowEvent::Resized(_), .. } => recreate_swapchain = true,
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = 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(
|
||||
images: &[Arc<SwapchainImage<Window>>],
|
||||
render_pass: Arc<RenderPassAbstract + Send + Sync>,
|
||||
|
@ -107,10 +107,6 @@
|
||||
//!
|
||||
//! 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: "..."`
|
||||
//!
|
||||
//! This defines what shader type the given GLSL source will be compiled into.
|
||||
|
Loading…
Reference in New Issue
Block a user