From f5fe3e37ef7b3fd944f261acb711ef1ddc8a3ea3 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 5 Feb 2023 19:48:24 -0500 Subject: [PATCH] rt(d3d11/vk): allow for parallel shader compilation OpenGL is for obvious reasons incompatible, and for DX12 the graphics pipeline creation has to be on the main thread so there isn't that much gain to be had. --- Cargo.lock | 100 ++++++++++++- librashader-reflect/src/back/cross.rs | 4 +- librashader-reflect/src/back/dxil.rs | 6 +- librashader-reflect/src/back/spirv.rs | 6 +- librashader-reflect/src/front/shaderc.rs | 11 +- librashader-reflect/src/reflect/cross.rs | 15 +- librashader-reflect/src/reflect/naga.rs | 8 +- librashader-runtime-d3d11/Cargo.toml | 1 + librashader-runtime-d3d11/src/filter_chain.rs | 139 +++++++++--------- librashader-runtime-d3d11/src/filter_pass.rs | 1 - librashader-runtime-d3d11/src/lib.rs | 5 +- librashader-runtime-vk/Cargo.toml | 2 + librashader-runtime-vk/src/filter_chain.rs | 114 +++++++------- .../src/vulkan_primitives.rs | 4 + 14 files changed, 265 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d54e9e..b73f2af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,6 +301,49 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.7.1", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossfont" version = "0.5.1" @@ -606,6 +649,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -822,6 +874,7 @@ dependencies = [ "librashader-reflect", "librashader-runtime", "librashader-spirv-cross", + "rayon", "rustc-hash", "thiserror", "windows", @@ -841,6 +894,7 @@ dependencies = [ "librashader-reflect", "librashader-runtime", "librashader-spirv-cross", + "rayon", "rustc-hash", "thiserror", "windows", @@ -879,6 +933,7 @@ dependencies = [ "librashader-spirv-cross", "num", "raw-window-handle 0.5.0", + "rayon", "rustc-hash", "thiserror", "winit", @@ -947,6 +1002,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1059,7 +1123,7 @@ dependencies = [ "bitflags", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -1072,7 +1136,7 @@ dependencies = [ "bitflags", "cfg-if", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -1181,6 +1245,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.5.9" @@ -1353,6 +1427,28 @@ dependencies = [ "raw-window-handle 0.5.0", ] +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" diff --git a/librashader-reflect/src/back/cross.rs b/librashader-reflect/src/back/cross.rs index e1a944b..9f6dbd8 100644 --- a/librashader-reflect/src/back/cross.rs +++ b/librashader-reflect/src/back/cross.rs @@ -30,7 +30,7 @@ impl FromCompilation for GLSL { compile: GlslangCompilation, ) -> Result, ShaderReflectError> { Ok(CompilerBackend { - backend: GlslReflect::try_from(compile)?, + backend: GlslReflect::try_from(&compile)?, }) } } @@ -52,7 +52,7 @@ impl FromCompilation for HLSL { compile: GlslangCompilation, ) -> Result, ShaderReflectError> { Ok(CompilerBackend { - backend: HlslReflect::try_from(compile)?, + backend: HlslReflect::try_from(&compile)?, }) } } diff --git a/librashader-reflect/src/back/dxil.rs b/librashader-reflect/src/back/dxil.rs index dd9ed5a..9ee523d 100644 --- a/librashader-reflect/src/back/dxil.rs +++ b/librashader-reflect/src/back/dxil.rs @@ -24,9 +24,9 @@ impl FromCompilation for DXIL { fn from_compilation( compile: GlslangCompilation, ) -> Result, ShaderReflectError> { - let vertex = compile.vertex.as_binary().to_vec(); - let fragment = compile.fragment.as_binary().to_vec(); - let reflect = GlslReflect::try_from(compile)?; + let reflect = GlslReflect::try_from(&compile)?; + let vertex = compile.vertex; + let fragment = compile.fragment; Ok(CompilerBackend { // we can just reuse WriteSpirV as the backend. backend: WriteSpirV { diff --git a/librashader-reflect/src/back/spirv.rs b/librashader-reflect/src/back/spirv.rs index 9f02f1a..e317499 100644 --- a/librashader-reflect/src/back/spirv.rs +++ b/librashader-reflect/src/back/spirv.rs @@ -23,9 +23,9 @@ impl FromCompilation for SPIRV { fn from_compilation( compile: GlslangCompilation, ) -> Result, ShaderReflectError> { - let vertex = compile.vertex.as_binary().to_vec(); - let fragment = compile.fragment.as_binary().to_vec(); - let reflect = GlslReflect::try_from(compile)?; + let reflect = GlslReflect::try_from(&compile)?; + let vertex = compile.vertex; + let fragment = compile.fragment; Ok(CompilerBackend { backend: WriteSpirV { reflect, diff --git a/librashader-reflect/src/front/shaderc.rs b/librashader-reflect/src/front/shaderc.rs index 01693c8..252c762 100644 --- a/librashader-reflect/src/front/shaderc.rs +++ b/librashader-reflect/src/front/shaderc.rs @@ -1,11 +1,11 @@ use crate::error::ShaderCompileError; use librashader_preprocess::ShaderSource; -use shaderc::{CompilationArtifact, CompileOptions, Limit, ShaderKind}; +use shaderc::{CompileOptions, Limit, ShaderKind}; /// A reflectable shader compilation via glslang (shaderc). pub struct GlslangCompilation { - pub(crate) vertex: CompilationArtifact, - pub(crate) fragment: CompilationArtifact, + pub(crate) vertex: Vec, + pub(crate) fragment: Vec, } impl GlslangCompilation { @@ -137,6 +137,11 @@ pub(crate) fn compile_spirv( "main", Some(&options), )?; + + // shaderc has a GIL so Send is unsafe. + let vertex = Vec::from(vertex.as_binary()); + let fragment = Vec::from(fragment.as_binary()); + Ok(GlslangCompilation { vertex, fragment }) } diff --git a/librashader-reflect/src/reflect/cross.rs b/librashader-reflect/src/reflect/cross.rs index 41afa17..cfd374b 100644 --- a/librashader-reflect/src/reflect/cross.rs +++ b/librashader-reflect/src/reflect/cross.rs @@ -7,7 +7,7 @@ use crate::reflect::semantics::{ MAX_BINDINGS_COUNT, MAX_PUSH_BUFFER_SIZE, }; use crate::reflect::{align_uniform_size, ReflectShader}; -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use spirv_cross::hlsl::ShaderModel; use spirv_cross::spirv::{Ast, Decoration, Module, Resource, ShaderResources, Type}; @@ -18,6 +18,9 @@ use crate::back::targets::{GLSL, HLSL}; use crate::back::{CompileShader, ShaderCompilerOutput}; use crate::reflect::helper::{SemanticErrorBlame, TextureData, UboData}; +// This is "probably" OK. +unsafe impl Send for CrossReflect {} + pub(crate) struct CrossReflect where T: spirv_cross::spirv::Target, @@ -110,7 +113,7 @@ impl ValidateTypeSemantics for TextureSemantics { } } -impl TryFrom for CrossReflect +impl TryFrom<&GlslangCompilation> for CrossReflect where T: spirv_cross::spirv::Target, Ast: spirv_cross::spirv::Compile, @@ -118,9 +121,9 @@ where { type Error = ShaderReflectError; - fn try_from(value: GlslangCompilation) -> Result { - let vertex_module = Module::from_words(value.vertex.as_binary()); - let fragment_module = Module::from_words(value.fragment.as_binary()); + fn try_from(value: &GlslangCompilation) -> Result { + let vertex_module = Module::from_words(&value.vertex); + let fragment_module = Module::from_words(&value.fragment); let vertex = Ast::parse(&vertex_module)?; let fragment = Ast::parse(&fragment_module)?; @@ -878,7 +881,7 @@ mod test { ); } let spirv = GlslangCompilation::compile(&result).unwrap(); - let mut reflect = CrossReflect::::try_from(spirv).unwrap(); + let mut reflect = CrossReflect::::try_from(&spirv).unwrap(); let _shader_reflection = reflect .reflect( 0, diff --git a/librashader-reflect/src/reflect/naga.rs b/librashader-reflect/src/reflect/naga.rs index 23562f8..0967e85 100644 --- a/librashader-reflect/src/reflect/naga.rs +++ b/librashader-reflect/src/reflect/naga.rs @@ -23,16 +23,16 @@ impl TryFrom for NagaReflect { } } -impl TryFrom for NagaReflect { +impl TryFrom<&GlslangCompilation> for NagaReflect { type Error = ShaderReflectError; - fn try_from(value: GlslangCompilation) -> Result { + fn try_from(value: &GlslangCompilation) -> Result { let ops = Options::default(); let vertex = - naga::front::spv::Parser::new(value.vertex.as_binary().to_vec().into_iter(), &ops) + naga::front::spv::Parser::new(value.vertex.clone().into_iter(), &ops) .parse()?; let fragment = - naga::front::spv::Parser::new(value.fragment.as_binary().to_vec().into_iter(), &ops) + naga::front::spv::Parser::new(value.fragment.clone().into_iter(), &ops) .parse()?; Ok(NagaReflect { vertex, fragment }) } diff --git a/librashader-runtime-d3d11/Cargo.toml b/librashader-runtime-d3d11/Cargo.toml index 48e58fb..9af2f6f 100644 --- a/librashader-runtime-d3d11/Cargo.toml +++ b/librashader-runtime-d3d11/Cargo.toml @@ -22,6 +22,7 @@ spirv_cross = { package = "librashader-spirv-cross", version = "0.23" } rustc-hash = "1.1.0" bytemuck = "1.12.3" +rayon = "1.6.1" [target.'cfg(windows)'.dependencies.windows] version = "0.44.0" diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 9eab31c..4558517 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -32,13 +32,14 @@ use windows::Win32::Graphics::Direct3D11::{ D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, }; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R8G8B8A8_UNORM; +use rayon::prelude::*; pub struct FilterMutable { pub(crate) passes_enabled: usize, pub(crate) parameters: FxHashMap, } -type ShaderPassMeta = ShaderPassArtifact>; +type ShaderPassMeta = ShaderPassArtifact + Send>; /// A Direct3D 11 filter chain. pub struct FilterChainD3D11 { @@ -220,81 +221,85 @@ impl FilterChainD3D11 { passes: Vec, semantics: &ShaderSemantics, ) -> error::Result> { - let mut filters = Vec::new(); + // access to ID3D11Device is thread safe. + let filters: Vec> = + passes.into_par_iter() + .enumerate() + .map(|(index, (config, source, mut reflect)) | { + let reflection = reflect.reflect(index, semantics)?; + let hlsl = reflect.compile(None)?; - for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() { - let reflection = reflect.reflect(index, semantics)?; - let hlsl = reflect.compile(None)?; + let vertex_dxbc = + util::d3d_compile_shader(hlsl.vertex.as_bytes(), b"main\0", b"vs_5_0\0")?; + let vs = d3d11_compile_bound_shader( + device, + &vertex_dxbc, + None, + ID3D11Device::CreateVertexShader, + )?; - let vertex_dxbc = - util::d3d_compile_shader(hlsl.vertex.as_bytes(), b"main\0", b"vs_5_0\0")?; - let vs = d3d11_compile_bound_shader( - device, - &vertex_dxbc, - None, - ID3D11Device::CreateVertexShader, - )?; + let ia_desc = DrawQuad::get_spirv_cross_vbo_desc(); + let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxbc)?; - let ia_desc = DrawQuad::get_spirv_cross_vbo_desc(); - let vao = util::d3d11_create_input_layout(device, &ia_desc, &vertex_dxbc)?; + let fragment_dxbc = + util::d3d_compile_shader(hlsl.fragment.as_bytes(), b"main\0", b"ps_5_0\0")?; + let ps = d3d11_compile_bound_shader( + device, + &fragment_dxbc, + None, + ID3D11Device::CreatePixelShader, + )?; - let fragment_dxbc = - util::d3d_compile_shader(hlsl.fragment.as_bytes(), b"main\0", b"ps_5_0\0")?; - let ps = d3d11_compile_bound_shader( - device, - &fragment_dxbc, - None, - ID3D11Device::CreatePixelShader, - )?; + let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 { + let buffer = FilterChainD3D11::create_constant_buffer(device, ubo.size)?; + Some(ConstantBufferBinding { + binding: ubo.binding, + size: ubo.size, + stage_mask: ubo.stage_mask, + buffer, + }) + } else { + None + }; - let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 { - let buffer = FilterChainD3D11::create_constant_buffer(device, ubo.size)?; - Some(ConstantBufferBinding { - binding: ubo.binding, - size: ubo.size, - stage_mask: ubo.stage_mask, - buffer, - }) - } else { - None - }; + let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 { + let buffer = FilterChainD3D11::create_constant_buffer(device, push.size)?; + Some(ConstantBufferBinding { + binding: if ubo_cbuffer.is_some() { 1 } else { 0 }, + size: push.size, + stage_mask: push.stage_mask, + buffer, + }) + } else { + None + }; - let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 { - let buffer = FilterChainD3D11::create_constant_buffer(device, push.size)?; - Some(ConstantBufferBinding { - binding: if ubo_cbuffer.is_some() { 1 } else { 0 }, - size: push.size, - stage_mask: push.stage_mask, - buffer, - }) - } else { - None - }; + let uniform_storage = UniformStorage::new( + reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize), + reflection + .push_constant + .as_ref() + .map_or(0, |push| push.size as usize), + ); - let uniform_storage = UniformStorage::new( - reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize), - reflection - .push_constant - .as_ref() - .map_or(0, |push| push.size as usize), - ); + let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); - let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); + Ok(FilterPass { + reflection, + vertex_shader: vs, + vertex_layout: vao, + pixel_shader: ps, + uniform_bindings, + uniform_storage, + uniform_buffer: ubo_cbuffer, + push_buffer: push_cbuffer, + source, + config: config.clone(), + }) + }).collect(); - filters.push(FilterPass { - reflection, - compiled: hlsl, - vertex_shader: vs, - vertex_layout: vao, - pixel_shader: ps, - uniform_bindings, - uniform_storage, - uniform_buffer: ubo_cbuffer, - push_buffer: push_cbuffer, - source, - config: config.clone(), - }) - } + let filters: error::Result> = filters.into_iter().collect(); + let filters = filters?; Ok(filters) } diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index 3c8e634..2a9d3bf 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -34,7 +34,6 @@ pub struct ConstantBufferBinding { // slang_process.cpp 141 pub struct FilterPass { pub reflection: ShaderReflection, - pub compiled: ShaderCompilerOutput, pub vertex_shader: ID3D11VertexShader, pub vertex_layout: ID3D11InputLayout, pub pixel_shader: ID3D11PixelShader, diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index c525f08..5f329df 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -38,7 +38,7 @@ mod tests { // "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", // "../test/null.slangp", - const FILTER_PATH: &str = "../test/slang-shaders/bezel/koko-aio/monitor-bloom.slangp"; + const FILTER_PATH: &str = "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp"; const IMAGE_PATH: &str = "../test/finalfightlong.png"; #[test] fn triangle_d3d11_args() { @@ -84,7 +84,8 @@ mod tests { force_no_mipmaps: false, }), // replace below with 'None' for the triangle - None, + // None, + Some(Image::load(IMAGE_PATH, UVDirection::TopLeft).unwrap()) ) .unwrap(); // let sample = hello_triangle_old::d3d11_hello_triangle::Sample::new( diff --git a/librashader-runtime-vk/Cargo.toml b/librashader-runtime-vk/Cargo.toml index 244118e..3a68eda 100644 --- a/librashader-runtime-vk/Cargo.toml +++ b/librashader-runtime-vk/Cargo.toml @@ -25,6 +25,8 @@ bytemuck = "1.12.3" thiserror = "1.0.37" ash = { version = "0.37.1+1.3.235", features = ["linked", "debug"] } +rayon = "1.6.1" + [dev-dependencies] num = "0.4.0" glfw = "0.49.0" diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index b348612..39c59ac 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -31,6 +31,7 @@ use std::collections::VecDeque; use std::path::Path; use std::sync::Arc; +use rayon::prelude::*; /// A Vulkan device and metadata that is required by the shader runtime. pub struct VulkanObjects { pub(crate) device: Arc, @@ -39,7 +40,7 @@ pub struct VulkanObjects { pipeline_cache: vk::PipelineCache, } -type ShaderPassMeta = ShaderPassArtifact>; +type ShaderPassMeta = ShaderPassArtifact + Send>; /// A collection of handles needed to access the Vulkan instance. #[derive(Clone)] @@ -308,69 +309,66 @@ impl FilterChainVulkan { frames_in_flight: u32, use_render_pass: bool, ) -> error::Result> { - let mut filters = Vec::new(); let frames_in_flight = std::cmp::max(1, frames_in_flight); - // initialize passes - for (index, (config, source, mut reflect)) in passes.into_iter().enumerate() { - let reflection = reflect.reflect(index, semantics)?; - let spirv_words = reflect.compile(None)?; + let filters: Vec> = passes.into_par_iter() + .enumerate() + .map(|(index, (config, source, mut reflect))| { + let reflection = reflect.reflect(index, semantics)?; + let spirv_words = reflect.compile(None)?; - let ubo_size = reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize); - let uniform_storage = UniformStorage::new_with_storage( - RawVulkanBuffer::new( + let ubo_size = reflection.ubo.as_ref().map_or(0, |ubo| ubo.size as usize); + let uniform_storage = UniformStorage::new_with_storage( + RawVulkanBuffer::new( + &vulkan.device, + &vulkan.memory_properties, + vk::BufferUsageFlags::UNIFORM_BUFFER, + ubo_size, + )?, + reflection + .push_constant + .as_ref() + .map_or(0, |push| push.size as usize), + ); + + let uniform_bindings = reflection.meta + .create_binding_map(|param| param.offset()); + + let render_pass_format = if !use_render_pass { + vk::Format::UNDEFINED + } else if let Some(format) = config.get_format_override() { + format.into() + } else if source.format != ImageFormat::Unknown { + source.format.into() + } else { + ImageFormat::R8G8B8A8Unorm.into() + }; + + let graphics_pipeline = VulkanGraphicsPipeline::new( &vulkan.device, - &vulkan.memory_properties, - vk::BufferUsageFlags::UNIFORM_BUFFER, - ubo_size, - )?, - reflection - .push_constant - .as_ref() - .map_or(0, |push| push.size as usize), - ); + &vulkan.pipeline_cache, + &spirv_words, + &reflection, + frames_in_flight, + render_pass_format, + )?; - let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); - - let render_pass_format = if !use_render_pass { - vk::Format::UNDEFINED - } else if let Some(format) = config.get_format_override() { - format.into() - } else if source.format != ImageFormat::Unknown { - source.format.into() - } else { - ImageFormat::R8G8B8A8Unorm.into() - }; - - let graphics_pipeline = VulkanGraphicsPipeline::new( - &vulkan.device, - &vulkan.pipeline_cache, - &spirv_words, - &reflection, - frames_in_flight, - render_pass_format, - )?; - - // let ubo_ring = VkUboRing::new( - // &vulkan.device, - // &vulkan.memory_properties, - // frames_in_flight as usize, - // ubo_size, - // )?; - filters.push(FilterPass { - device: vulkan.device.clone(), - reflection, - // compiled: spirv_words, - uniform_storage, - uniform_bindings, - source, - config, - graphics_pipeline, - // ubo_ring, - frames_in_flight, - }); - } + Ok(FilterPass { + device: vulkan.device.clone(), + reflection, + // compiled: spirv_words, + uniform_storage, + uniform_bindings, + source, + config, + graphics_pipeline, + // ubo_ring, + frames_in_flight, + }) + }).collect(); + let filters: error::Result> = filters.into_iter().collect(); + let filters = filters?; Ok(filters.into_boxed_slice()) } diff --git a/librashader-runtime-vk/src/vulkan_primitives.rs b/librashader-runtime-vk/src/vulkan_primitives.rs index 71e3fc9..35a9b10 100644 --- a/librashader-runtime-vk/src/vulkan_primitives.rs +++ b/librashader-runtime-vk/src/vulkan_primitives.rs @@ -134,6 +134,10 @@ impl<'a> Drop for VulkanBufferMapHandle<'a> { } } +/// SAFETY: Creating the pointer should be safe in multithreaded contexts. +/// +/// Mutation is guarded by DerefMut +unsafe impl Send for RawVulkanBuffer {} pub struct RawVulkanBuffer { buffer: ManuallyDrop, ptr: NonNull,