diff --git a/librashader-runtime-d3d12/Cargo.toml b/librashader-runtime-d3d12/Cargo.toml index fdfaf37..d66fd88 100644 --- a/librashader-runtime-d3d12/Cargo.toml +++ b/librashader-runtime-d3d12/Cargo.toml @@ -25,6 +25,8 @@ bytemuck = { version = "1.12.3", features = ["derive"] } array-init = "2.1.0" bit-set = "0.5.3" +rayon = "1.6.1" + [target.'cfg(windows)'.dependencies.windows] version = "0.44.0" features = [ diff --git a/librashader-runtime-d3d12/src/descriptor_heap.rs b/librashader-runtime-d3d12/src/descriptor_heap.rs index 68817e7..3eca04e 100644 --- a/librashader-runtime-d3d12/src/descriptor_heap.rs +++ b/librashader-runtime-d3d12/src/descriptor_heap.rs @@ -11,6 +11,7 @@ use windows::Win32::Graphics::Direct3D12::{ D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, }; +use crate::error::FilterChainError; #[const_trait] pub trait D3D12HeapType { @@ -132,6 +133,7 @@ impl AsRef for D3D12DescriptorHeapSlotInner { fn as_ref(&self) -> &D3D12_GPU_DESCRIPTOR_HANDLE { + /// SAFETY: D3D12ShaderVisibleHeapType must have a GPU handle. self.gpu_handle.as_ref().unwrap() } } @@ -298,7 +300,7 @@ impl D3D12DescriptorHeap { } } - todo!("error need to fail"); + Err(FilterChainError::DescriptorHeapOverflow) } pub fn alloc_range( diff --git a/librashader-runtime-d3d12/src/error.rs b/librashader-runtime-d3d12/src/error.rs index b0bf0ec..a8379d9 100644 --- a/librashader-runtime-d3d12/src/error.rs +++ b/librashader-runtime-d3d12/src/error.rs @@ -1,16 +1,48 @@ use std::error::Error; +use thiserror::Error; -pub type Result = std::result::Result>; +/// Cumulative error type for Direct3D12 filter chains. +#[derive(Error, Debug)] +pub enum FilterChainError { + #[error("invariant assumption about d3d11 did not hold. report this as an issue.")] + Direct3DOperationError(&'static str), + #[error("direct3d driver error")] + Direct3DError(#[from] windows::core::Error), + #[error("SPIRV reflection error")] + SpirvCrossReflectError(#[from] spirv_cross::ErrorCode), + #[error("shader preset parse error")] + ShaderPresetError(#[from] ParsePresetError), + #[error("shader preprocess error")] + ShaderPreprocessError(#[from] PreprocessError), + #[error("shader compile error")] + ShaderCompileError(#[from] ShaderCompileError), + #[error("shader reflect error")] + ShaderReflectError(#[from] ShaderReflectError), + #[error("lut loading error")] + LutLoadError(#[from] ImageError), + #[error("heap overflow")] + DescriptorHeapOverflow, +} + +pub type Result = std::result::Result; // todo: make this return error macro_rules! assume_d3d12_init { ($value:ident, $call:literal) => { - let $value = $value.expect($call); + let $value = $value.ok_or($crate::error::FilterChainError::Direct3DOperationError( + $call, + ))?; }; (mut $value:ident, $call:literal) => { - let mut $value = $value.expect($call); + let mut $value = $value.ok_or($crate::error::FilterChainError::Direct3DOperationError( + $call, + ))?; }; } /// Macro for unwrapping result of a D3D function. pub(crate) use assume_d3d12_init; +use librashader_preprocess::PreprocessError; +use librashader_presets::ParsePresetError; +use librashader_reflect::error::{ShaderCompileError, ShaderReflectError}; +use librashader_runtime::image::ImageError; diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index dc835ff..8daff9c 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -47,6 +47,7 @@ use windows::Win32::Graphics::Direct3D12::{ use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_UNKNOWN; use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject}; use windows::Win32::System::WindowsProgramming::INFINITE; +use crate::error::FilterChainError; type DxilShaderPassMeta = ShaderPassArtifact>; type HlslShaderPassMeta = ShaderPassArtifact>; @@ -112,20 +113,18 @@ impl FilterChainD3D12 { let shader_copy = preset.shaders.clone(); let (passes, semantics) = - DXIL::compile_preset_passes::>( + DXIL::compile_preset_passes::( preset.shaders, &preset.textures, - ) - .unwrap(); + )?; - let (hlsl_passes, _) = HLSL::compile_preset_passes::>( + let (hlsl_passes, _) = HLSL::compile_preset_passes::( shader_copy, &preset.textures, - ) - .unwrap(); + )?; let samplers = SamplerSet::new(device)?; - let mipmap_gen = D3D12MipmapGen::new(device).unwrap(); + let mipmap_gen = D3D12MipmapGen::new(device)?; let draw_quad = DrawQuad::new(device)?; let mut staging_heap = D3D12DescriptorHeap::new( @@ -138,8 +137,7 @@ impl FilterChainD3D12 { )?; let luts = - FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen) - .unwrap(); + FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen)?; let root_signature = D3D12RootSignature::new(device)?; @@ -150,8 +148,7 @@ impl FilterChainD3D12 { hlsl_passes, &semantics, options.map_or(false, |o| o.force_hlsl_pipeline), - ) - .unwrap(); + )?; // initialize output framebuffers let mut output_framebuffers = Vec::new(); @@ -305,22 +302,20 @@ impl FilterChainD3D12 { // Wait until finished if unsafe { fence.GetCompletedValue() } < 1 { - unsafe { fence.SetEventOnCompletion(1, fence_event) } - .ok() - .unwrap(); + unsafe { fence.SetEventOnCompletion(1, fence_event)? }; unsafe { WaitForSingleObject(fence_event, INFINITE) }; unsafe { ResetEvent(fence_event) }; } - cmd.Reset(&command_pool, None).unwrap(); + cmd.Reset(&command_pool, None)?; let residuals = mipmap_gen.mipmapping_context(&cmd, &mut work_heap, |context| { for lut in luts.values() { lut.generate_mipmaps(context)?; } - Ok::<(), Box>(()) + Ok::<(), FilterChainError>(()) })?; // @@ -329,9 +324,7 @@ impl FilterChainD3D12 { queue.Signal(&fence, 2)?; // if unsafe { fence.GetCompletedValue() } < 2 { - unsafe { fence.SetEventOnCompletion(2, fence_event) } - .ok() - .unwrap(); + unsafe { fence.SetEventOnCompletion(2, fence_event)? } unsafe { WaitForSingleObject(fence_event, INFINITE) }; unsafe { CloseHandle(fence_event) }; @@ -600,24 +593,24 @@ impl FilterChainD3D12 { source.filter = pass.config.filter; source.wrap_mode = pass.config.wrap_mode; - if pass.config.mipmap_input && !self.disable_mipmaps { - unsafe { - // this is so bad. - self.common.mipmap_gen.mipmapping_context( - cmd, - &mut self.mipmap_heap, - |ctx| { - ctx.generate_mipmaps( - &source.resource, - source.size().calculate_miplevels() as u16, - source.size, - source.format, - )?; - Ok::<(), Box>(()) - }, - )?; - } - } + // if pass.config.mipmap_input && !self.disable_mipmaps { + // unsafe { + // // this is so bad. + // self.common.mipmap_gen.mipmapping_context( + // cmd, + // &mut self.mipmap_heap, + // |ctx| { + // ctx.generate_mipmaps( + // &source.resource, + // source.size().calculate_miplevels() as u16, + // source.size, + // source.format, + // )?; + // Ok::<(), FilterChainError>(()) + // }, + // )?; + // } + // } let target = &self.output_framebuffers[index]; util::d3d12_resource_transition( diff --git a/librashader-runtime-d3d12/src/graphics_pipeline.rs b/librashader-runtime-d3d12/src/graphics_pipeline.rs index f29a64c..65223d0 100644 --- a/librashader-runtime-d3d12/src/graphics_pipeline.rs +++ b/librashader-runtime-d3d12/src/graphics_pipeline.rs @@ -20,6 +20,8 @@ use windows::Win32::Graphics::Direct3D12::{ D3D12_SHADER_VISIBILITY_ALL, D3D12_SHADER_VISIBILITY_PIXEL, D3D_ROOT_SIGNATURE_VERSION_1, }; use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT, DXGI_FORMAT_UNKNOWN, DXGI_SAMPLE_DESC}; +use crate::error::assume_d3d12_init; +use crate::error::FilterChainError::Direct3DOperationError; pub struct D3D12GraphicsPipeline { pub(crate) handle: ID3D12PipelineState, @@ -108,8 +110,7 @@ impl D3D12RootSignature { None, )?; - // SAFETY: if D3D12SerializeRootSignature succeeds then blob is Some - let rs_blob = rs_blob.unwrap(); + assume_d3d12_init!(rs_blob, "D3D12SerializeRootSignature"); let blob = std::slice::from_raw_parts( rs_blob.GetBufferPointer().cast(), rs_blob.GetBufferSize(), @@ -215,10 +216,10 @@ impl D3D12GraphicsPipeline { render_format: DXGI_FORMAT, ) -> error::Result { if shader_assembly.vertex.requires_runtime_data() { - panic!("vertex needs rt data??") + return Err(Direct3DOperationError("Compiled DXIL Vertex shader needs unexpected runtime data")) } if shader_assembly.fragment.requires_runtime_data() { - panic!("fragment needs rt data??") + return Err(Direct3DOperationError("Compiled DXIL fragment shader needs unexpected runtime data")) } let vertex_dxil = util::dxc_validate_shader(library, validator, &shader_assembly.vertex)?; let fragment_dxil = diff --git a/librashader-runtime-d3d12/src/lib.rs b/librashader-runtime-d3d12/src/lib.rs index d18d86d..e4dcb01 100644 --- a/librashader-runtime-d3d12/src/lib.rs +++ b/librashader-runtime-d3d12/src/lib.rs @@ -27,9 +27,9 @@ mod tests { fn triangle_d3d12() { let sample = hello_triangle::d3d12_hello_triangle::Sample::new( // "../test/slang-shaders/crt/crt-lottes.slangp", - // "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", + "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", // "../test/slang-shaders/crt/crt-royale.slangp", - "../test/slang-shaders/vhs/VHSPro.slangp", + // "../test/slang-shaders/vhs/VHSPro.slangp", &SampleCommandLine { use_warp_device: false, }, diff --git a/librashader-runtime-d3d12/src/mipmap.rs b/librashader-runtime-d3d12/src/mipmap.rs index c5effa6..b9f449c 100644 --- a/librashader-runtime-d3d12/src/mipmap.rs +++ b/librashader-runtime-d3d12/src/mipmap.rs @@ -123,10 +123,10 @@ impl<'a> MipmapGenContext<'a> { impl D3D12MipmapGen { pub fn new(device: &ID3D12Device) -> error::Result { unsafe { - let blob = fxc_compile_shader(GENERATE_MIPS_SRC, b"main\0", b"cs_5_1\0").unwrap(); + let blob = fxc_compile_shader(GENERATE_MIPS_SRC, b"main\0", b"cs_5_1\0")?; let blob = std::slice::from_raw_parts(blob.GetBufferPointer().cast(), blob.GetBufferSize()); - let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob).unwrap(); + let root_signature: ID3D12RootSignature = device.CreateRootSignature(0, blob)?; let desc = D3D12_COMPUTE_PIPELINE_STATE_DESC { pRootSignature: windows::core::ManuallyDrop::new(&root_signature), diff --git a/librashader-runtime-d3d12/src/util.rs b/librashader-runtime-d3d12/src/util.rs index a94d063..8746f3d 100644 --- a/librashader-runtime-d3d12/src/util.rs +++ b/librashader-runtime-d3d12/src/util.rs @@ -197,7 +197,7 @@ pub fn dxc_compile_shader( if let Ok(buf) = result.GetErrorBuffer() { unsafe { - let buf: IDxcBlobUtf8 = buf.cast().unwrap(); + let buf: IDxcBlobUtf8 = buf.cast()?; let buf = std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize()); let str = std::str::from_utf8_unchecked(buf); @@ -225,12 +225,11 @@ pub fn dxc_validate_shader( unsafe { let result = validator - .Validate(&blob, DxcValidatorFlags_InPlaceEdit) - .unwrap(); + .Validate(&blob, DxcValidatorFlags_InPlaceEdit)?; if let Ok(buf) = result.GetErrorBuffer() { unsafe { - let buf: IDxcBlobUtf8 = buf.cast().unwrap(); + let buf: IDxcBlobUtf8 = buf.cast()?; let buf = std::slice::from_raw_parts(buf.GetBufferPointer().cast(), buf.GetBufferSize()); let str = std::str::from_utf8_unchecked(buf);