This commit is contained in:
2019-07-23 21:55:02 +02:00
parent 7d50d00ab6
commit 1f980e7c12
4 changed files with 91 additions and 38 deletions

View File

@@ -3,7 +3,7 @@ use vulkano::command_buffer::{AutoCommandBufferBuilder, DynamicState};
use vulkano::device::{Device, DeviceExtensions};
use vulkano::framebuffer::{Framebuffer, FramebufferAbstract, Subpass, RenderPassAbstract};
use vulkano::image::SwapchainImage;
use vulkano::instance::{Instance, PhysicalDevice};
use vulkano::instance::{Instance, PhysicalDevice, ApplicationInfo, Version, RawInstanceExtensions};
use vulkano::pipeline::{GraphicsPipeline};
use vulkano::pipeline::shader::{GraphicsShaderType, ShaderModule};
use vulkano::pipeline::viewport::Viewport;
@@ -11,6 +11,8 @@ use vulkano::swapchain::{AcquireError, PresentMode, SurfaceTransform, Swapchain,
use vulkano::swapchain;
use vulkano::sync::{GpuFuture, FlushError};
use vulkano::sync;
use vulkano::pipeline::vertex::SingleBufferDefinition;
use vulkano::descriptor::PipelineLayoutAbstract;
use vulkano_win::VkSurfaceBuild;
@@ -19,15 +21,14 @@ use winit::{EventsLoop, Window, WindowBuilder, Event, WindowEvent};
use std::sync::Arc;
use std::time::SystemTime;
use std::path::PathBuf;
use std::ffi::CStr;
use std::ffi::{CStr, CString};
use shade_runner;
use shade_runner::{CompiledShaders, Entry};
use shaderc;
use vulkano::pipeline::vertex::SingleBufferDefinition;
use vulkano::descriptor::PipelineLayoutAbstract;
use crate::PushConstants;
use vulkano::instance::debug::{DebugCallback, MessageTypes};
const VALIDATION_LAYERS: &[&str] = &[
"VK_LAYER_LUNARG_standard_validation"
@@ -52,15 +53,45 @@ pub struct GameData<'a> {
}
pub fn init(mut game: GameData) {
if ENABLE_VALIDATION_LAYERS {
println!("Enabling validation layers...");
}
let instance = {
let extensions = vulkano_win::required_extensions();
// let mut extensions = RawInstanceExtensions::from(&vulkano_win::required_extensions());
let mut extensions = vulkano_win::required_extensions();
let app_info = ApplicationInfo {
application_name: Some("Asuro Editor".into()),
application_version: Some(Version { major: 0, minor: 1, patch: 0 }),
engine_name: Some("Asuro Rust Engine".into()),
engine_version: Some(Version { major: 0, minor: 1, patch: 0 })
};
if ENABLE_VALIDATION_LAYERS {
Instance::new(None, &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
let available_layers = vulkano::instance::layers_list().unwrap().map(|layer| String::from(layer.name())).collect::<Vec<String>>();
VALIDATION_LAYERS.iter().for_each(|wanted_layer_name| {
if !available_layers.iter().any(|available_layer_name| available_layer_name == wanted_layer_name) {
panic!("Validation layer not found: {:?}. Available layers: {:?}", wanted_layer_name, &available_layers.join(", "));
}
});
extensions.ext_debug_report = true;
// extensions.insert(CString::new("VK_EXT_debug_utils").unwrap());
Instance::new(Some(&app_info), &extensions, VALIDATION_LAYERS.iter().cloned()).expect("failed to create Vulkan instance")
} else {
Instance::new(None, &extensions, None).expect("failed to create Vulkan instance")
Instance::new(Some(&app_info), &extensions, None).expect("failed to create Vulkan instance")
}
};
if ENABLE_VALIDATION_LAYERS {
let debug_callback = setup_debug_callback(&instance);
assert!(debug_callback.is_some());
println!("Debug callback created.");
}
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
println!("Using device: {} (type: {:?})", physical.name(), physical.ty());
@@ -155,24 +186,8 @@ pub fn init(mut game: GameData) {
};
let mesh_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.mesh_vertices.iter().cloned()).unwrap();
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.mesh_vertices.iter().cloned()).unwrap();
let line_vertex_buffer = CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), game.line_vertices.iter().cloned()).unwrap();
// The next step is to create the shaders.
//
// The raw shader creation API provided by the vulkano library is unsafe, for various reasons.
//
// An overview of what the `vulkano_shaders::shader!` macro generates can be found in the
// `vulkano-shaders` crate docs. You can view them at https://docs.rs/vulkano-shaders/
//
// TODO: explain this in details
// 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
// manually.
// 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(vulkano::single_pass_renderpass!(
device.clone(),
attachments: {
@@ -394,13 +409,12 @@ pub fn init(mut game: GameData) {
// it.
let mut done = false;
events_loop.poll_events(|ev| {
match ev {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
Event::WindowEvent { event: WindowEvent::KeyboardInput { device_id, input }, .. } => {
game.on_keyboard_event(device_id, input);
if !game.on_window_event(&ev) {
match ev {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
_ => {}
}
_ => {}
}
});
if done { return; }
@@ -499,4 +513,22 @@ fn read_shader(vert_path_relative: &str, frag_path_relative: &str) -> (CompiledS
}
Err(error) => panic!("Shader compilation error: {:?}", error)
}
}
}
fn setup_debug_callback(instance: &Arc<Instance>) -> Option<DebugCallback> {
if !ENABLE_VALIDATION_LAYERS {
return None;
}
let msg_types = MessageTypes {
error: true,
warning: true,
performance_warning: true,
information: true,
debug: true,
};
DebugCallback::new(&instance, msg_types, |msg| {
println!("validation layer: {:?}", msg.description);
}).ok()
}