diff --git a/Cargo.lock b/Cargo.lock index c96f9c1..326b178 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,6 +1229,15 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + [[package]] name = "owned_ttf_parser" version = "0.21.0" @@ -2027,6 +2036,7 @@ dependencies = [ "gltf", "image", "log", + "ordered-float", "tobj", "vent-rendering", "vent-sdk", @@ -2070,6 +2080,7 @@ dependencies = [ "ash", "image", "log", + "ordered-float", "raw-window-handle", "raw-window-metal", "spirv", diff --git a/crates/vent-assets/Cargo.toml b/crates/vent-assets/Cargo.toml index 627d6cd..ca01c7e 100644 --- a/crates/vent-assets/Cargo.toml +++ b/crates/vent-assets/Cargo.toml @@ -9,6 +9,8 @@ edition = "2021" vent-sdk = { path = "../vent-sdk" } vent-rendering = { path = "../vent-rendering"} +ordered-float = "4.2.0" + image = "0.25" log = "0.4" diff --git a/crates/vent-assets/src/model/gltf.rs b/crates/vent-assets/src/model/gltf.rs index 5e24911..fb8d676 100644 --- a/crates/vent-assets/src/model/gltf.rs +++ b/crates/vent-assets/src/model/gltf.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashMap, ffi::CStr, fs::{self, File}, io::BufReader, @@ -195,6 +196,8 @@ impl GLTFLoader { loaded_materials.push(material); }); + let mut cached_pipeline = HashMap::new(); + for (i, material) in loaded_materials.into_iter().enumerate() { let mut all_meshes = vec![]; for primitive in mesh @@ -214,7 +217,7 @@ impl GLTFLoader { } let pipeline_info = MaterialPipelineInfo { mode: vk::PrimitiveTopology::TRIANGLE_LIST, // TODO - alpha_cut: Some(material.alpha_cut), + alpha_cut: Some(ordered_float::OrderedFloat(material.alpha_cut)), double_sided: material.double_sided, }; @@ -224,71 +227,81 @@ impl GLTFLoader { meshes: all_meshes, }; - let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { - topology: pipeline_info.mode, - ..Default::default() - }; - let rasterization_info = vk::PipelineRasterizationStateCreateInfo { - front_face: vk::FrontFace::COUNTER_CLOCKWISE, - line_width: 1.0, - polygon_mode: vk::PolygonMode::FILL, - cull_mode: if pipeline_info.double_sided { - vk::CullModeFlags::NONE - } else { - vk::CullModeFlags::BACK - }, - ..Default::default() - }; - { - let multisample_state_info = vk::PipelineMultisampleStateCreateInfo { - rasterization_samples: vk::SampleCountFlags::TYPE_1, + if cached_pipeline.contains_key(&pipeline_info) { + pipelines.push(ModelPipeline { + pipeline: *cached_pipeline.get(&pipeline_info).unwrap(), + materials: vec![model_material], // TODO + }); + } else { + let vertex_input_assembly_state_info = vk::PipelineInputAssemblyStateCreateInfo { + topology: pipeline_info.mode, ..Default::default() }; - - let depth_state_info = vk::PipelineDepthStencilStateCreateInfo::default() - .depth_test_enable(true) - .depth_write_enable(true) - .depth_compare_op(vk::CompareOp::LESS) - .max_depth_bounds(1.0); - let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { - color_write_mask: vk::ColorComponentFlags::RGBA, + let rasterization_info = vk::PipelineRasterizationStateCreateInfo { + front_face: vk::FrontFace::COUNTER_CLOCKWISE, + line_width: 1.0, + polygon_mode: vk::PolygonMode::FILL, + cull_mode: if pipeline_info.double_sided { + vk::CullModeFlags::NONE + } else { + vk::CullModeFlags::BACK + }, ..Default::default() - }]; - let color_blend_state = vk::PipelineColorBlendStateCreateInfo::default() - .logic_op(vk::LogicOp::COPY) - .attachments(&color_blend_attachment_states); - - let dynamic_state = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; // TODO - let dynamic_state_info = - vk::PipelineDynamicStateCreateInfo::default().dynamic_states(&dynamic_state); - - let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::default() - .stages(&shader_stage_create_info) - .vertex_input_state(&vertex_input_state_info) - .input_assembly_state(&vertex_input_assembly_state_info) - .viewport_state(&viewport_state_info) - .rasterization_state(&rasterization_info) - .multisample_state(&multisample_state_info) - .depth_stencil_state(&depth_state_info) - .color_blend_state(&color_blend_state) - .dynamic_state(&dynamic_state_info) - .layout(pipeline_layout) - .render_pass(instance.render_pass); - - let graphics_pipelines = unsafe { - instance.device.create_graphics_pipelines( - vk::PipelineCache::null(), - &[graphic_pipeline_info], - None, - ) - } - .expect("Unable to create graphics pipeline"); + }; - pipelines.push(ModelPipeline { - pipeline: graphics_pipelines[0], - materials: vec![model_material], // TODO - }); + { + let multisample_state_info = vk::PipelineMultisampleStateCreateInfo { + rasterization_samples: vk::SampleCountFlags::TYPE_1, + ..Default::default() + }; + + let depth_state_info = vk::PipelineDepthStencilStateCreateInfo::default() + .depth_test_enable(true) + .depth_write_enable(true) + .depth_compare_op(vk::CompareOp::LESS) + .max_depth_bounds(1.0); + let color_blend_attachment_states = [vk::PipelineColorBlendAttachmentState { + color_write_mask: vk::ColorComponentFlags::RGBA, + ..Default::default() + }]; + let color_blend_state = vk::PipelineColorBlendStateCreateInfo::default() + .logic_op(vk::LogicOp::COPY) + .attachments(&color_blend_attachment_states); + + let dynamic_state = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; // TODO + let dynamic_state_info = vk::PipelineDynamicStateCreateInfo::default() + .dynamic_states(&dynamic_state); + + let graphic_pipeline_info = vk::GraphicsPipelineCreateInfo::default() + .stages(&shader_stage_create_info) + .vertex_input_state(&vertex_input_state_info) + .input_assembly_state(&vertex_input_assembly_state_info) + .viewport_state(&viewport_state_info) + .rasterization_state(&rasterization_info) + .multisample_state(&multisample_state_info) + .depth_stencil_state(&depth_state_info) + .color_blend_state(&color_blend_state) + .dynamic_state(&dynamic_state_info) + .layout(pipeline_layout) + .render_pass(instance.render_pass); + + let graphics_pipelines = unsafe { + instance.device.create_graphics_pipelines( + vk::PipelineCache::null(), + &[graphic_pipeline_info], + None, + ) + } + .expect("Unable to create graphics pipeline"); + + pipelines.push(ModelPipeline { + pipeline: graphics_pipelines[0], + materials: vec![model_material], // TODO + }); + + cached_pipeline.insert(pipeline_info, graphics_pipelines[0]); + } } } diff --git a/crates/vent-rendering/Cargo.toml b/crates/vent-rendering/Cargo.toml index fd6a0bb..f68348c 100644 --- a/crates/vent-rendering/Cargo.toml +++ b/crates/vent-rendering/Cargo.toml @@ -10,6 +10,8 @@ vent-window = { path= "../vent-window"} ash = { version= "0.38", default-features = false, features = ["linked", "debug", "std"] } spirv = "0.3.0" +ordered-float = "4.2.0" + image = "0.25" raw-window-handle = "0.6" diff --git a/crates/vent-rendering/src/instance.rs b/crates/vent-rendering/src/instance.rs index 96ccbb6..f35897e 100644 --- a/crates/vent-rendering/src/instance.rs +++ b/crates/vent-rendering/src/instance.rs @@ -389,14 +389,14 @@ impl VulkanInstance { tiling: vk::ImageTiling, features: vk::FormatFeatureFlags, ) -> Option { - candidates.iter().cloned().find(|f| { - let properties = unsafe { instance.get_physical_device_format_properties(pdevice, *f) }; + candidates.iter().find(|f| { + let properties = unsafe { instance.get_physical_device_format_properties(pdevice, **f) }; match tiling { vk::ImageTiling::LINEAR => properties.linear_tiling_features.contains(features), vk::ImageTiling::OPTIMAL => properties.optimal_tiling_features.contains(features), _ => false, } - }) + }).copied() } fn create_frame_buffers( @@ -550,9 +550,8 @@ impl VulkanInstance { .unwrap(); let present_mode = present_modes .iter() - .cloned() - .find(|&mode| mode == vk::PresentModeKHR::MAILBOX) - .unwrap_or(vk::PresentModeKHR::FIFO); + .find(|&mode| *mode == vk::PresentModeKHR::MAILBOX) + .unwrap_or(&vk::PresentModeKHR::FIFO); let swapchain_create_info = vk::SwapchainCreateInfoKHR::default() .surface(surface) @@ -564,7 +563,7 @@ impl VulkanInstance { .image_sharing_mode(vk::SharingMode::EXCLUSIVE) .pre_transform(pre_transform) .composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE) - .present_mode(present_mode) + .present_mode(*present_mode) .clipped(true) .image_array_layers(1) .old_swapchain(old_swapchain.unwrap_or_default()); diff --git a/crates/vent-rendering/src/lib.rs b/crates/vent-rendering/src/lib.rs index c05c42b..e45a011 100644 --- a/crates/vent-rendering/src/lib.rs +++ b/crates/vent-rendering/src/lib.rs @@ -1,6 +1,7 @@ use std::mem::{self, offset_of}; use ash::vk; +use ordered_float::OrderedFloat; pub mod allocator; pub mod buffer; @@ -12,10 +13,10 @@ mod surface; const DEFAULT_FENCE_TIMEOUT: u64 = 100000000000; -#[derive(PartialEq)] +#[derive(PartialEq, Eq, Hash)] pub struct MaterialPipelineInfo { pub mode: vk::PrimitiveTopology, - pub alpha_cut: Option, // Default 0.5 + pub alpha_cut: Option>, // Default 0.5 pub double_sided: bool, } diff --git a/crates/vent-rendering/src/surface.rs b/crates/vent-rendering/src/surface.rs index 6534f3c..b82d47b 100644 --- a/crates/vent-rendering/src/surface.rs +++ b/crates/vent-rendering/src/surface.rs @@ -2,11 +2,7 @@ use std::os::raw::c_char; -use ash::{ - khr::surface, - prelude::*, - vk, Entry, Instance, -}; +use ash::{khr::surface, prelude::*, vk, Entry, Instance}; use raw_window_handle::{DisplayHandle, RawDisplayHandle, RawWindowHandle, WindowHandle}; pub unsafe fn create_surface( diff --git a/crates/vent-window/src/platform/wayland/mod.rs b/crates/vent-window/src/platform/wayland/mod.rs index 1a25235..1eb4f2e 100644 --- a/crates/vent-window/src/platform/wayland/mod.rs +++ b/crates/vent-window/src/platform/wayland/mod.rs @@ -8,7 +8,10 @@ use std::{ time::Duration, }; -use sctk::{reexports::protocols::xdg::shell::client::xdg_toplevel::ResizeEdge as XdgResizeEdge, seat::pointer::{ThemeSpec, ThemedPointer}}; +use sctk::{ + reexports::protocols::xdg::shell::client::xdg_toplevel::ResizeEdge as XdgResizeEdge, + seat::pointer::{ThemeSpec, ThemedPointer}, +}; use rwh_06::{RawDisplayHandle, RawWindowHandle, WaylandDisplayHandle, WaylandWindowHandle}; use sctk::{