-
-
Save AtheMathmo/3fed0665400fd6850cf0d144bb9b9070 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use vulkano::instance::Instance; | |
use vulkano::instance::PhysicalDevice; | |
use vulkano::device::Device; | |
use vulkano::swapchain; | |
use vulkano::swapchain::AcquireError; | |
use vulkano::buffer::BufferUsage; | |
use vulkano::buffer::CpuAccessibleBuffer; | |
use vulkano::framebuffer::Framebuffer; | |
use vulkano::pipeline::GraphicsPipeline; | |
use vulkano::framebuffer::Subpass; | |
use vulkano::command_buffer::DynamicState; | |
use vulkano::pipeline::viewport::Viewport; | |
use vulkano::command_buffer::AutoCommandBufferBuilder; | |
use vulkano::command_buffer::CommandBuffer; | |
use vulkano::sync::GpuFuture; | |
use vulkano_win::VkSurfaceBuild; | |
use winit::{ | |
event::{Event, WindowEvent}, | |
event_loop::{ControlFlow, EventLoop}, | |
window::WindowBuilder, | |
}; | |
use vulkano::swapchain::{Swapchain, SurfaceTransform, PresentMode, ColorSpace, FullscreenExclusive}; | |
use vulkano::image::ImageUsage; | |
use std::sync::Arc; | |
#[derive(Default, Copy, Clone)] | |
struct Vertex { | |
position: [f32; 2], | |
} | |
vulkano::impl_vertex!(Vertex, position); | |
mod vs { | |
vulkano_shaders::shader!{ | |
ty: "vertex", | |
path: "examples/triangle.vert" | |
} | |
} | |
mod fs { | |
vulkano_shaders::shader!{ | |
ty: "fragment", | |
path: "examples/triangle.frag" | |
} | |
} | |
fn main() { | |
let instance = { | |
let extensions = vulkano_win::required_extensions(); | |
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance") | |
}; | |
let physical = PhysicalDevice::enumerate(&instance).next().expect("no device available"); | |
for family in physical.queue_families() { | |
println!("Found a queue family with {:?} queue(s)", family.queues_count()); | |
} | |
let queue_family = physical.queue_families() | |
.find(|&q| q.supports_graphics()) | |
.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 queue = queues.next().unwrap(); | |
// Set up surface and swapchain | |
let events_loop = EventLoop::new(); | |
let surface = WindowBuilder::new().build_vk_surface(&events_loop, instance.clone()).unwrap(); | |
let caps = surface.capabilities(physical) | |
.expect("failed to get surface capabilities"); | |
let dimensions = caps.current_extent.unwrap_or([1280, 1024]); | |
let alpha = caps.supported_composite_alpha.iter().next().unwrap(); | |
let format = caps.supported_formats[0].0; | |
let mut swapchain = Swapchain::new(device.clone(), surface.clone(), | |
caps.min_image_count, format, dimensions, 1, ImageUsage::color_attachment(), &queue, | |
SurfaceTransform::Identity, alpha, PresentMode::Fifo, FullscreenExclusive::Default, | |
true, ColorSpace::SrgbNonLinear) | |
.expect("failed to create swapchain"); | |
// Get shaders | |
let vs = vs::Shader::load(device.clone()).expect("failed to create vertex shader module"); | |
let fs = fs::Shader::load(device.clone()).expect("failed to create fragment shader module"); | |
// Create vertex buffer | |
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(), false, | |
vec![vertex1, vertex2, vertex3].into_iter()).unwrap(); | |
let render_pass = Arc::new(vulkano::single_pass_renderpass!(device.clone(), | |
attachments: { | |
color: { | |
load: Clear, | |
store: Store, | |
format: format, | |
samples: 1, | |
} | |
}, | |
pass: { | |
color: [color], | |
depth_stencil: {} | |
} | |
).unwrap()); | |
let dynamic_state = DynamicState { | |
viewports: Some(vec![Viewport { | |
origin: [0.0, 0.0], | |
dimensions: [1024.0, 1024.0], | |
depth_range: 0.0 .. 1.0, | |
}]), | |
.. DynamicState::none() | |
}; | |
let pipeline = Arc::new(GraphicsPipeline::start() | |
// Defines what kind of vertex input is expected. | |
.vertex_input_single_buffer::<Vertex>() | |
// The vertex shader. | |
.vertex_shader(vs.main_entry_point(), ()) | |
// Defines the viewport (explanations below). | |
.viewports_dynamic_scissors_irrelevant(1) | |
// The fragment shader. | |
.fragment_shader(fs.main_entry_point(), ()) | |
// This graphics pipeline object concerns the first pass of the render pass. | |
.render_pass(Subpass::from(render_pass.clone(), 0).unwrap()) | |
// Now that everything is specified, we call `build`. | |
.build(device.clone()) | |
.unwrap()); | |
let mut staleSwapchain = false; | |
events_loop.run(move |event, _, control_flow| { | |
match event { | |
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { | |
*control_flow = ControlFlow::Exit; | |
}, | |
_ => { | |
*control_flow = ControlFlow::Poll; | |
if staleSwapchain { | |
let size = surface.window().inner_size(); | |
swapchain = swapchain.0.recreate_with_dimensions([size.width, size.height]).unwrap(); | |
staleSwapchain = false; | |
} | |
let (image_num, _suboptimal, acquire_future) | |
= match swapchain::acquire_next_image(swapchain.0.clone(), None) { | |
Ok(r) => r, | |
Err(AcquireError::OutOfDate) => { | |
staleSwapchain = true; | |
return (); | |
} | |
Err(err) => panic!("{:?}", err) | |
}; | |
let framebuffer = Arc::new(Framebuffer::start(render_pass.clone()) | |
.add(swapchain.1[image_num].clone()).unwrap() | |
.build().unwrap()); | |
let mut builder = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap(); | |
builder | |
.begin_render_pass(framebuffer.clone(), false, vec![[0.0, 0.0, 1.0, 1.0].into()]) | |
.unwrap() | |
.draw(pipeline.clone(), &dynamic_state, vertex_buffer.clone(), (), ()) | |
.unwrap() | |
.end_render_pass() | |
.unwrap(); | |
let command_buffer = builder.build().unwrap(); | |
acquire_future | |
.then_execute(queue.clone(), command_buffer).unwrap() | |
.then_swapchain_present(queue.clone(), swapchain.0.clone(), image_num) | |
.then_signal_fence_and_flush().unwrap().wait(None).unwrap(); | |
} | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment