diff --git a/Cargo.lock b/Cargo.lock index 0f9e347..b17fd87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1654,17 +1654,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.43.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows-targets", ] [[package]] @@ -1687,19 +1681,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" @@ -1709,9 +1718,9 @@ checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" @@ -1721,9 +1730,9 @@ checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" @@ -1733,9 +1742,9 @@ checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" @@ -1745,15 +1754,15 @@ checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" @@ -1763,9 +1772,9 @@ checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winit" diff --git a/librashader-capi/Cargo.toml b/librashader-capi/Cargo.toml index 0713c78..d5497a3 100644 --- a/librashader-capi/Cargo.toml +++ b/librashader-capi/Cargo.toml @@ -32,7 +32,7 @@ rustc-hash = "1.1.0" ash = { version = "0.37.2+1.3.238", optional = true } [dependencies.windows] -version = "0.43.0" +version = "0.44.0" features = [ "Win32_Graphics_Direct3D11", ] diff --git a/librashader-common/Cargo.toml b/librashader-common/Cargo.toml index 3c59107..569d58f 100644 --- a/librashader-common/Cargo.toml +++ b/librashader-common/Cargo.toml @@ -26,7 +26,7 @@ num-traits = "0.2.15" [dependencies.windows] optional = true -version = "0.43.0" +version = "0.44.0" features = [ "Win32_Foundation", "Win32_Graphics_Dxgi_Common", diff --git a/librashader-runtime-d3d11/Cargo.toml b/librashader-runtime-d3d11/Cargo.toml index e2d87be..66e337d 100644 --- a/librashader-runtime-d3d11/Cargo.toml +++ b/librashader-runtime-d3d11/Cargo.toml @@ -24,7 +24,7 @@ rustc-hash = "1.1.0" bytemuck = "1.12.3" [dependencies.windows] -version = "0.43.0" +version = "0.44.0" features = [ "Win32_Foundation", "Win32_Graphics_Dxgi_Common", diff --git a/librashader-runtime-d3d11/src/error.rs b/librashader-runtime-d3d11/src/error.rs index fe42a82..2e4d1d1 100644 --- a/librashader-runtime-d3d11/src/error.rs +++ b/librashader-runtime-d3d11/src/error.rs @@ -9,8 +9,8 @@ use thiserror::Error; /// Cumulative error type for Direct3D11 filter chains. #[derive(Error, Debug)] pub enum FilterChainError { - #[error("unable to get direct3d context")] - Direct3DContextError, + #[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")] @@ -27,5 +27,21 @@ pub enum FilterChainError { LutLoadError(#[from] ImageError), } +macro_rules! assume_d3d11_init { + ($value:ident, $call:literal) => { + let $value = $value.ok_or($crate::error::FilterChainError::Direct3DOperationError( + $call, + ))?; + }; + (mut $value:ident, $call:literal) => { + let mut $value = $value.ok_or($crate::error::FilterChainError::Direct3DOperationError( + $call, + ))?; + }; +} + +/// Macro for unwrapping result of a D3D function. +pub(crate) use assume_d3d11_init; + /// Result type for Direct3D11 filter chains. pub type Result = std::result::Result; diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 133a7d7..1df00b5 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -16,7 +16,7 @@ use std::collections::VecDeque; use std::path::Path; -use crate::error::FilterChainError; +use crate::error::{assume_d3d11_init, FilterChainError}; use crate::filter_pass::{ConstantBufferBinding, FilterPass}; use crate::framebuffer::OwnedFramebuffer; use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11}; @@ -101,17 +101,18 @@ impl FilterChainD3D11 { // initialize passes let filters = FilterChainD3D11::init_passes(device, passes, &semantics)?; - let mut immediate_context = None; - unsafe { - device.GetImmediateContext(&mut immediate_context); - } - - let Some(immediate_context) = immediate_context else { - return Err(FilterChainError::Direct3DContextError) - }; + let immediate_context = unsafe { device.GetImmediateContext()? }; let current_context = if use_deferred_context { - unsafe { device.CreateDeferredContext(0)? } + // check if device supports deferred contexts + if let Err(_) = unsafe { device.CreateDeferredContext(0, None) } { + immediate_context.clone() + } else { + let mut context = None; + unsafe { device.CreateDeferredContext(0, Some(&mut context))? }; + assume_d3d11_init!(context, "CreateDeferredContext"); + context + } } else { immediate_context.clone() }; @@ -197,7 +198,8 @@ impl FilterChainD3D11 { impl FilterChainD3D11 { fn create_constant_buffer(device: &ID3D11Device, size: u32) -> error::Result { unsafe { - let buffer = device.CreateBuffer( + let mut buffer = None; + device.CreateBuffer( &D3D11_BUFFER_DESC { ByteWidth: size, Usage: D3D11_USAGE_DYNAMIC, @@ -207,8 +209,9 @@ impl FilterChainD3D11 { StructureByteStride: 0, }, None, + Some(&mut buffer), )?; - + assume_d3d11_init!(buffer, "CreateBuffer"); Ok(buffer) } } @@ -602,7 +605,12 @@ impl FilterChainD3D11 { if self.common.d3d11.context_is_deferred { unsafe { - let command_list = self.common.d3d11.current_context.FinishCommandList(false)?; + let mut command_list = None; + self.common + .d3d11 + .current_context + .FinishCommandList(false, Some(&mut command_list))?; + assume_d3d11_init!(command_list, "FinishCommandList"); self.common .d3d11 .immediate_context diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index c8c21a0..2c5061f 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -14,7 +14,8 @@ use rustc_hash::FxHashMap; use librashader_runtime::binding::{BindSemantics, TextureInput}; use windows::Win32::Graphics::Direct3D11::{ ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState, - ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, + ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAPPED_SUBRESOURCE, + D3D11_MAP_WRITE_DISCARD, }; use crate::render_target::RenderTarget; @@ -181,7 +182,8 @@ impl FilterPass { if let Some(ubo) = &self.uniform_buffer { // upload uniforms unsafe { - let map = context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; + let mut map = D3D11_MAPPED_SUBRESOURCE::default(); + context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut map))?; std::ptr::copy_nonoverlapping( self.uniform_storage.ubo_pointer(), map.pData.cast(), @@ -191,21 +193,18 @@ impl FilterPass { } if ubo.stage_mask.contains(BindingStage::VERTEX) { - unsafe { - context.VSSetConstantBuffers(ubo.binding, Some(&[Some(ubo.buffer.clone())])) - } + unsafe { context.VSSetConstantBuffers(ubo.binding, Some(&[ubo.buffer.clone()])) } } if ubo.stage_mask.contains(BindingStage::FRAGMENT) { - unsafe { - context.PSSetConstantBuffers(ubo.binding, Some(&[Some(ubo.buffer.clone())])) - } + unsafe { context.PSSetConstantBuffers(ubo.binding, Some(&[ubo.buffer.clone()])) } } } if let Some(push) = &self.push_buffer { // upload push constants unsafe { - let map = context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; + let mut map = D3D11_MAPPED_SUBRESOURCE::default(); + context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, Some(&mut map))?; std::ptr::copy_nonoverlapping( self.uniform_storage.push_pointer(), map.pData.cast(), @@ -215,14 +214,10 @@ impl FilterPass { } if push.stage_mask.contains(BindingStage::VERTEX) { - unsafe { - context.VSSetConstantBuffers(push.binding, Some(&[Some(push.buffer.clone())])) - } + unsafe { context.VSSetConstantBuffers(push.binding, Some(&[push.buffer.clone()])) } } if push.stage_mask.contains(BindingStage::FRAGMENT) { - unsafe { - context.PSSetConstantBuffers(push.binding, Some(&[Some(push.buffer.clone())])) - } + unsafe { context.PSSetConstantBuffers(push.binding, Some(&[push.buffer.clone()])) } } } @@ -232,10 +227,16 @@ impl FilterPass { } unsafe { - context.PSSetShaderResources(0, Some(&textures)); - context.PSSetSamplers(0, Some(&samplers)); + // SAFETY: Niche optimization for Option> + // Assumes that IUnknown is defined as IUnknown(std::ptr::NonNull) + const _: () = assert!( + std::mem::size_of::>() + == std::mem::size_of::() + ); + context.PSSetShaderResources(0, Some(std::mem::transmute(textures.as_ref()))); + context.PSSetSamplers(0, Some(std::mem::transmute(samplers.as_ref()))); - context.OMSetRenderTargets(Some(&[Some(output.output.rtv.clone())]), None); + context.OMSetRenderTargets(Some(&[output.output.rtv.clone()]), None); context.RSSetViewports(Some(&[output.output.viewport])) } @@ -246,7 +247,7 @@ impl FilterPass { unsafe { // unbind resources. - context.PSSetShaderResources(0, Some(NULL_TEXTURES)); + context.PSSetShaderResources(0, Some(std::mem::transmute(NULL_TEXTURES.as_ref()))); context.OMSetRenderTargets(None, None); } Ok(()) diff --git a/librashader-runtime-d3d11/src/framebuffer.rs b/librashader-runtime-d3d11/src/framebuffer.rs index a756e0e..d3c7b11 100644 --- a/librashader-runtime-d3d11/src/framebuffer.rs +++ b/librashader-runtime-d3d11/src/framebuffer.rs @@ -1,4 +1,5 @@ use crate::error; +use crate::error::assume_d3d11_init; use crate::texture::{D3D11InputView, InputTexture}; use crate::util::d3d11_get_closest_format; use librashader_common::{ImageFormat, Size}; @@ -43,7 +44,9 @@ impl OwnedFramebuffer { | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0, ); let desc = default_desc(size, format, 1); - let texture = device.CreateTexture2D(&desc, None)?; + let mut texture = None; + device.CreateTexture2D(&desc, None, Some(&mut texture))?; + assume_d3d11_init!(texture, "CreateTexture2D"); Ok(OwnedFramebuffer { texture, @@ -101,7 +104,10 @@ impl OwnedFramebuffer { // todo: fix mipmap handling let desc = default_desc(size, format, 1); unsafe { - let mut texture = self.device.CreateTexture2D(&desc, None)?; + let mut texture = None; + self.device + .CreateTexture2D(&desc, None, Some(&mut texture))?; + assume_d3d11_init!(mut texture, "CreateTexture2D"); std::mem::swap(&mut self.texture, &mut texture); drop(texture) } @@ -112,8 +118,9 @@ impl OwnedFramebuffer { } pub fn create_shader_resource_view(&self) -> error::Result { + let mut srv = None; unsafe { - Ok(self.device.CreateShaderResourceView( + self.device.CreateShaderResourceView( &self.texture, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Format: self.format, @@ -125,13 +132,17 @@ impl OwnedFramebuffer { }, }, }), - )?) + Some(&mut srv), + )?; } + assume_d3d11_init!(srv, "CreateShaderResourceView"); + Ok(srv) } pub fn create_render_target_view(&self) -> error::Result { + let mut rtv = None; unsafe { - Ok(self.device.CreateRenderTargetView( + self.device.CreateRenderTargetView( &self.texture, Some(&D3D11_RENDER_TARGET_VIEW_DESC { Format: self.format, @@ -140,8 +151,12 @@ impl OwnedFramebuffer { Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 }, }, }), - )?) + Some(&mut rtv), + )? } + + assume_d3d11_init!(rtv, "CreateRenderTargetView"); + Ok(rtv) } pub fn as_output_framebuffer(&self) -> error::Result { @@ -154,11 +169,7 @@ impl OwnedFramebuffer { pub fn copy_from(&mut self, image: &D3D11InputView) -> error::Result<()> { let original_resource: ID3D11Texture2D = unsafe { - let mut resource = None; - image.handle.GetResource(&mut resource); - let Some(resource) = resource else { - return Ok(()) - }; + let resource = image.handle.GetResource()?; resource.cast()? }; diff --git a/librashader-runtime-d3d11/src/hello_triangle.rs b/librashader-runtime-d3d11/src/hello_triangle.rs index 8d7f09c..7df94bd 100644 --- a/librashader-runtime-d3d11/src/hello_triangle.rs +++ b/librashader-runtime-d3d11/src/hello_triangle.rs @@ -298,15 +298,22 @@ pub mod d3d11_hello_triangle { ) }; - let vs = unsafe { self.device.CreateVertexShader(vs_compiled, None) }?; + let vs = unsafe { + let mut vso = None; + self.device + .CreateVertexShader(vs_compiled, None, Some(&mut vso))?; + vso.unwrap() + }; let ps = unsafe { let ps = slice::from_raw_parts( ps_blob.GetBufferPointer().cast::(), ps_blob.GetBufferSize(), ); - self.device.CreatePixelShader(ps, None) - }?; + let mut pso = None; + self.device.CreatePixelShader(ps, None, Some(&mut pso))?; + pso.unwrap() + }; let (input_layout, stencil_state, raster_state) = create_pipeline_state(&self.device, vs_compiled)?; @@ -370,11 +377,13 @@ pub mod d3d11_hello_triangle { let buffer_number = 0; unsafe { - let mapped_resource = self.context.Map( + let mut mapped_resource = Default::default(); + self.context.Map( &resources.triangle_uniforms, 0, D3D11_MAP_WRITE_DISCARD, 0, + Some(&mut mapped_resource), )?; std::ptr::copy_nonoverlapping( &resources.triangle_uniform_values, @@ -387,10 +396,10 @@ pub mod d3d11_hello_triangle { unsafe { self.context.VSSetConstantBuffers( buffer_number, - Some(&[Some(resources.triangle_uniforms.clone())]), + Some(&[resources.triangle_uniforms.clone()]), ); self.context.OMSetRenderTargets( - Some(&[Some(resources.rtv.clone())]), + Some(&[resources.rtv.clone()]), &resources.depth_stencil_view, ); self.context.RSSetViewports(Some(&[resources.viewport])) @@ -435,18 +444,23 @@ pub mod d3d11_hello_triangle { unsafe { let mut tex2d_desc = Default::default(); resources.backbuffer.GetDesc(&mut tex2d_desc); - let backup = self.device.CreateTexture2D( + let mut backup = None; + + self.device.CreateTexture2D( &D3D11_TEXTURE2D_DESC { BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, ..tex2d_desc }, None, + Some(&mut backup), )?; + let backup = backup.unwrap(); self.context.CopyResource(&backup, &resources.backbuffer); - let srv = self.device.CreateShaderResourceView( + let mut srv = None; + self.device.CreateShaderResourceView( &backup, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Format: tex2d_desc.Format, @@ -458,11 +472,17 @@ pub mod d3d11_hello_triangle { }, }, }), + Some(&mut srv), )?; + let srv = srv.unwrap(); - let shader_out = self.device.CreateTexture2D(&tex2d_desc, None)?; + let mut shader_out = None; + self.device + .CreateTexture2D(&tex2d_desc, None, Some(&mut shader_out))?; + let shader_out = shader_out.unwrap(); - let _rtv = self.device.CreateRenderTargetView( + let mut rtv = None; + self.device.CreateRenderTargetView( &shader_out, Some(&D3D11_RENDER_TARGET_VIEW_DESC { Format: tex2d_desc.Format, @@ -471,6 +491,7 @@ pub mod d3d11_hello_triangle { Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 }, }, }), + Some(&mut rtv), )?; // OutputFramebuffer { @@ -533,9 +554,10 @@ pub mod d3d11_hello_triangle { ) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)> { unsafe { let backbuffer: ID3D11Texture2D = swapchain.GetBuffer(0)?; - let rtv = device.CreateRenderTargetView(&backbuffer, None)?; + let mut rtv = None; + device.CreateRenderTargetView(&backbuffer, None, Some(&mut rtv))?; - Ok((rtv, backbuffer)) + Ok((rtv.unwrap(), backbuffer)) } } fn create_pipeline_state( @@ -547,7 +569,8 @@ pub mod d3d11_hello_triangle { ID3D11RasterizerState, )> { unsafe { - let input_layout = device.CreateInputLayout( + let mut input_layout = None; + device.CreateInputLayout( &[ D3D11_INPUT_ELEMENT_DESC { SemanticName: s!("POSITION"), @@ -569,42 +592,55 @@ pub mod d3d11_hello_triangle { }, ], vs_blob, + Some(&mut input_layout), )?; - let stencil_state = device.CreateDepthStencilState(&D3D11_DEPTH_STENCIL_DESC { - DepthEnable: BOOL::from(true), - DepthWriteMask: D3D11_DEPTH_WRITE_MASK_ALL, - DepthFunc: D3D11_COMPARISON_LESS, - StencilEnable: BOOL::from(true), - StencilReadMask: 0xff, - StencilWriteMask: 0xff, - FrontFace: D3D11_DEPTH_STENCILOP_DESC { - StencilFailOp: D3D11_STENCIL_OP_KEEP, - StencilDepthFailOp: D3D11_STENCIL_OP_INCR, - StencilPassOp: D3D11_STENCIL_OP_KEEP, - StencilFunc: D3D11_COMPARISON_ALWAYS, - }, - BackFace: D3D11_DEPTH_STENCILOP_DESC { - StencilFailOp: D3D11_STENCIL_OP_KEEP, - StencilDepthFailOp: D3D11_STENCIL_OP_DECR, - StencilPassOp: D3D11_STENCIL_OP_KEEP, - StencilFunc: D3D11_COMPARISON_ALWAYS, - }, - })?; + let input_layout = input_layout.unwrap(); - let rasterizer_state = device.CreateRasterizerState(&D3D11_RASTERIZER_DESC { - AntialiasedLineEnable: BOOL::from(false), - CullMode: D3D11_CULL_NONE, - DepthBias: 0, - DepthBiasClamp: 0.0f32, - DepthClipEnable: BOOL::from(true), - FillMode: D3D11_FILL_SOLID, - FrontCounterClockwise: BOOL::from(false), - MultisampleEnable: BOOL::from(false), - ScissorEnable: BOOL::from(false), - SlopeScaledDepthBias: 0.0f32, - })?; + let mut stencil_state = None; + device.CreateDepthStencilState( + &D3D11_DEPTH_STENCIL_DESC { + DepthEnable: BOOL::from(true), + DepthWriteMask: D3D11_DEPTH_WRITE_MASK_ALL, + DepthFunc: D3D11_COMPARISON_LESS, + StencilEnable: BOOL::from(true), + StencilReadMask: 0xff, + StencilWriteMask: 0xff, + FrontFace: D3D11_DEPTH_STENCILOP_DESC { + StencilFailOp: D3D11_STENCIL_OP_KEEP, + StencilDepthFailOp: D3D11_STENCIL_OP_INCR, + StencilPassOp: D3D11_STENCIL_OP_KEEP, + StencilFunc: D3D11_COMPARISON_ALWAYS, + }, + BackFace: D3D11_DEPTH_STENCILOP_DESC { + StencilFailOp: D3D11_STENCIL_OP_KEEP, + StencilDepthFailOp: D3D11_STENCIL_OP_DECR, + StencilPassOp: D3D11_STENCIL_OP_KEEP, + StencilFunc: D3D11_COMPARISON_ALWAYS, + }, + }, + Some(&mut stencil_state), + )?; + let stencil_state = stencil_state.unwrap(); + let mut rasterizer_state = None; + device.CreateRasterizerState( + &D3D11_RASTERIZER_DESC { + AntialiasedLineEnable: BOOL::from(false), + CullMode: D3D11_CULL_NONE, + DepthBias: 0, + DepthBiasClamp: 0.0f32, + DepthClipEnable: BOOL::from(true), + FillMode: D3D11_FILL_SOLID, + FrontCounterClockwise: BOOL::from(false), + MultisampleEnable: BOOL::from(false), + ScissorEnable: BOOL::from(false), + SlopeScaledDepthBias: 0.0f32, + }, + Some(&mut rasterizer_state), + )?; + + let rasterizer_state = rasterizer_state.unwrap(); Ok((input_layout, stencil_state, rasterizer_state)) } } @@ -613,7 +649,8 @@ pub mod d3d11_hello_triangle { device: &ID3D11Device, ) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)> { unsafe { - let buffer = device.CreateTexture2D( + let mut buffer = None; + device.CreateTexture2D( &D3D11_TEXTURE2D_DESC { Width: WIDTH as u32, Height: HEIGHT as u32, @@ -630,9 +667,13 @@ pub mod d3d11_hello_triangle { MiscFlags: Default::default(), }, None, + Some(&mut buffer), )?; - let view = device.CreateDepthStencilView( + let buffer = buffer.unwrap(); + + let mut view = None; + device.CreateDepthStencilView( &buffer, Some(&D3D11_DEPTH_STENCIL_VIEW_DESC { Format: DXGI_FORMAT_D24_UNORM_S8_UINT, @@ -642,13 +683,17 @@ pub mod d3d11_hello_triangle { }, ..Default::default() }), + Some(&mut view), )?; + let view = view.unwrap(); + Ok((buffer, view)) } } fn create_triangle_uniforms(device: &ID3D11Device) -> Result { + let mut buffer = None; unsafe { device.CreateBuffer( &D3D11_BUFFER_DESC { @@ -660,8 +705,10 @@ pub mod d3d11_hello_triangle { StructureByteStride: 0, }, None, - ) + Some(&mut buffer), + )?; } + Ok(buffer.unwrap()) } fn create_triangle_buffers(device: &ID3D11Device) -> Result<(ID3D11Buffer, ID3D11Buffer)> { @@ -682,7 +729,8 @@ pub mod d3d11_hello_triangle { let indices = [0, 1, 2]; unsafe { - let vertex_buffer = device.CreateBuffer( + let mut vertex_buffer = None; + device.CreateBuffer( &D3D11_BUFFER_DESC { ByteWidth: (std::mem::size_of::() * vertices.len()) as u32, Usage: D3D11_USAGE_DEFAULT, @@ -696,9 +744,11 @@ pub mod d3d11_hello_triangle { SysMemPitch: 0, SysMemSlicePitch: 0, }), + Some(&mut vertex_buffer), )?; - let index_buffer = device.CreateBuffer( + let mut index_buffer = None; + device.CreateBuffer( &D3D11_BUFFER_DESC { ByteWidth: (std::mem::size_of::() * indices.len()) as u32, Usage: D3D11_USAGE_DEFAULT, @@ -712,9 +762,10 @@ pub mod d3d11_hello_triangle { SysMemPitch: 0, SysMemSlicePitch: 0, }), + Some(&mut index_buffer), )?; - Ok((vertex_buffer, index_buffer)) + Ok((vertex_buffer.unwrap(), index_buffer.unwrap())) } } fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> { diff --git a/librashader-runtime-d3d11/src/quad_render.rs b/librashader-runtime-d3d11/src/quad_render.rs index 096604e..f4b5670 100644 --- a/librashader-runtime-d3d11/src/quad_render.rs +++ b/librashader-runtime-d3d11/src/quad_render.rs @@ -1,4 +1,5 @@ use crate::error; +use crate::error::assume_d3d11_init; use bytemuck::offset_of; use windows::core::PCSTR; use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; @@ -52,7 +53,8 @@ pub(crate) struct DrawQuad { impl DrawQuad { pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> error::Result { unsafe { - let buffer = device.CreateBuffer( + let mut buffer = None; + device.CreateBuffer( &D3D11_BUFFER_DESC { ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32, Usage: D3D11_USAGE_IMMUTABLE, @@ -66,7 +68,9 @@ impl DrawQuad { SysMemPitch: 0, SysMemSlicePitch: 0, }), + Some(&mut buffer), )?; + assume_d3d11_init!(buffer, "CreateBuffer"); Ok(DrawQuad { buffer, diff --git a/librashader-runtime-d3d11/src/samplers.rs b/librashader-runtime-d3d11/src/samplers.rs index 1c9c1b2..6a479ed 100644 --- a/librashader-runtime-d3d11/src/samplers.rs +++ b/librashader-runtime-d3d11/src/samplers.rs @@ -1,4 +1,4 @@ -use crate::error::Result; +use crate::error::{assume_d3d11_init, Result}; use librashader_common::{FilterMode, WrapMode}; use rustc_hash::FxHashMap; use windows::Win32::Graphics::Direct3D11::{ @@ -23,31 +23,42 @@ impl SamplerSet { ]; for wrap_mode in wrap_modes { unsafe { - let linear = device.CreateSamplerState(&D3D11_SAMPLER_DESC { - Filter: FilterMode::Linear.into(), - AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - MipLODBias: 0.0, - MaxAnisotropy: 1, - ComparisonFunc: D3D11_COMPARISON_NEVER, - BorderColor: [0.0, 0.0, 0.0, 0.0], - MinLOD: -D3D11_FLOAT32_MAX, - MaxLOD: D3D11_FLOAT32_MAX, - })?; + let mut linear = None; + device.CreateSamplerState( + &D3D11_SAMPLER_DESC { + Filter: FilterMode::Linear.into(), + AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + MipLODBias: 0.0, + MaxAnisotropy: 1, + ComparisonFunc: D3D11_COMPARISON_NEVER, + BorderColor: [0.0, 0.0, 0.0, 0.0], + MinLOD: -D3D11_FLOAT32_MAX, + MaxLOD: D3D11_FLOAT32_MAX, + }, + Some(&mut linear), + )?; - let nearest = device.CreateSamplerState(&D3D11_SAMPLER_DESC { - Filter: FilterMode::Nearest.into(), - AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), - MipLODBias: 0.0, - MaxAnisotropy: 1, - ComparisonFunc: D3D11_COMPARISON_NEVER, - BorderColor: [0.0, 0.0, 0.0, 0.0], - MinLOD: -D3D11_FLOAT32_MAX, - MaxLOD: D3D11_FLOAT32_MAX, - })?; + assume_d3d11_init!(linear, "CreateSamplerState"); + + let mut nearest = None; + device.CreateSamplerState( + &D3D11_SAMPLER_DESC { + Filter: FilterMode::Nearest.into(), + AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), + MipLODBias: 0.0, + MaxAnisotropy: 1, + ComparisonFunc: D3D11_COMPARISON_NEVER, + BorderColor: [0.0, 0.0, 0.0, 0.0], + MinLOD: -D3D11_FLOAT32_MAX, + MaxLOD: D3D11_FLOAT32_MAX, + }, + Some(&mut nearest), + )?; + assume_d3d11_init!(nearest, "CreateSamplerState"); samplers.insert((*wrap_mode, FilterMode::Linear), linear); samplers.insert((*wrap_mode, FilterMode::Nearest), nearest); diff --git a/librashader-runtime-d3d11/src/texture.rs b/librashader-runtime-d3d11/src/texture.rs index 82f6b37..8fb8a32 100644 --- a/librashader-runtime-d3d11/src/texture.rs +++ b/librashader-runtime-d3d11/src/texture.rs @@ -11,7 +11,7 @@ use windows::Win32::Graphics::Direct3D11::{ }; use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; -use crate::error::Result; +use crate::error::{assume_d3d11_init, Result}; use crate::framebuffer::OwnedFramebuffer; /// An image view for use as a shader resource. @@ -131,10 +131,13 @@ impl LutTexture { // since we load them with the Image module. unsafe { - let handle = device.CreateTexture2D(&desc, None).unwrap(); + let mut handle = None; + device.CreateTexture2D(&desc, None, Some(&mut handle))?; + assume_d3d11_init!(handle, "CreateTexture2D"); // need a staging texture to defer mipmap generation - let staging = device.CreateTexture2D( + let mut staging = None; + device.CreateTexture2D( &D3D11_TEXTURE2D_DESC { MipLevels: 1, BindFlags: D3D11_BIND_FLAG(0), @@ -148,7 +151,9 @@ impl LutTexture { SysMemPitch: source.pitch as u32, SysMemSlicePitch: 0, }), + Some(&mut staging), )?; + assume_d3d11_init!(staging, "CreateTexture2D"); // todo: do format conversion (leverage image crate..? // is this necessary with CopySubresourceRegion)... @@ -171,7 +176,8 @@ impl LutTexture { }), ); - let srv = device.CreateShaderResourceView( + let mut srv = None; + device.CreateShaderResourceView( &handle, Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Format: desc.Format, @@ -183,7 +189,9 @@ impl LutTexture { }, }, }), + Some(&mut srv), )?; + assume_d3d11_init!(srv, "CreateShaderResourceView"); if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 { context.GenerateMips(&srv) diff --git a/librashader-runtime-d3d11/src/util.rs b/librashader-runtime-d3d11/src/util.rs index e767fa4..9deb561 100644 --- a/librashader-runtime-d3d11/src/util.rs +++ b/librashader-runtime-d3d11/src/util.rs @@ -1,4 +1,5 @@ use crate::error; +use crate::error::assume_d3d11_init; use std::slice; use windows::core::PCSTR; use windows::Win32::Graphics::Direct3D::Fxc::{ @@ -129,8 +130,12 @@ pub fn d3d_compile_shader(source: &[u8], entry: &[u8], version: &[u8]) -> error: } } -pub type ShaderFactory<'a, L, T> = - unsafe fn(&'a ID3D11Device, &[u8], linkage: L) -> windows::core::Result; +pub type ShaderFactory<'a, L, T> = unsafe fn( + &'a ID3D11Device, + &[u8], + linkage: L, + Option<*mut Option>, +) -> windows::core::Result<()>; pub fn d3d11_compile_bound_shader<'a, T, L>( device: &'a ID3D11Device, @@ -139,14 +144,16 @@ pub fn d3d11_compile_bound_shader<'a, T, L>( factory: ShaderFactory<'a, L, T>, ) -> error::Result where - L: Into>, + L: Into>, { unsafe { // SAFETY: slice as valid for as long as vs_blob is alive. let dxil = slice::from_raw_parts(blob.GetBufferPointer().cast::(), blob.GetBufferSize()); - let compiled = factory(device, dxil, linkage)?; + let mut compiled = None; + factory(device, dxil, linkage, Some(&mut compiled))?; + assume_d3d11_init!(compiled, "CreateXXShader"); Ok(compiled) } } @@ -160,8 +167,9 @@ pub fn d3d11_create_input_layout( // SAFETY: slice as valid for as long as vs_blob is alive. let dxil = slice::from_raw_parts(blob.GetBufferPointer().cast::(), blob.GetBufferSize()); - - let compiled = device.CreateInputLayout(desc, dxil)?; - Ok(compiled) + let mut input_layout = None; + device.CreateInputLayout(desc, dxil, Some(&mut input_layout))?; + assume_d3d11_init!(input_layout, "CreateInputLayout"); + Ok(input_layout) } } diff --git a/librashader/Cargo.toml b/librashader/Cargo.toml index 4276bec..9211469 100644 --- a/librashader/Cargo.toml +++ b/librashader/Cargo.toml @@ -25,7 +25,7 @@ librashader-runtime-vk = { path = "../librashader-runtime-vk", version = "0.1.0- ash = { version = "0.37.1+1.3.235", optional = true } [dependencies.windows] -version = "0.43.0" +version = "0.44.0" features = [ "Win32_Graphics_Direct3D11", ]