d3d11: update to windows-rs 0.44

This commit is contained in:
chyyran 2023-01-16 18:45:02 -05:00
parent a2363c30a7
commit acca9ce6f6
14 changed files with 292 additions and 165 deletions

65
Cargo.lock generated
View file

@ -1654,17 +1654,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "windows" name = "windows"
version = "0.43.0" version = "0.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows-targets",
"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",
] ]
[[package]] [[package]]
@ -1687,19 +1681,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.42.0", "windows_aarch64_msvc 0.42.1",
"windows_i686_gnu 0.42.0", "windows_i686_gnu 0.42.1",
"windows_i686_msvc 0.42.0", "windows_i686_msvc 0.42.1",
"windows_x86_64_gnu 0.42.0", "windows_x86_64_gnu 0.42.1",
"windows_x86_64_gnullvm", "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]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@ -1709,9 +1718,9 @@ checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@ -1721,9 +1730,9 @@ checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@ -1733,9 +1742,9 @@ checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@ -1745,15 +1754,15 @@ checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
@ -1763,9 +1772,9 @@ checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.42.0" version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]] [[package]]
name = "winit" name = "winit"

View file

@ -32,7 +32,7 @@ rustc-hash = "1.1.0"
ash = { version = "0.37.2+1.3.238", optional = true } ash = { version = "0.37.2+1.3.238", optional = true }
[dependencies.windows] [dependencies.windows]
version = "0.43.0" version = "0.44.0"
features = [ features = [
"Win32_Graphics_Direct3D11", "Win32_Graphics_Direct3D11",
] ]

View file

@ -26,7 +26,7 @@ num-traits = "0.2.15"
[dependencies.windows] [dependencies.windows]
optional = true optional = true
version = "0.43.0" version = "0.44.0"
features = [ features = [
"Win32_Foundation", "Win32_Foundation",
"Win32_Graphics_Dxgi_Common", "Win32_Graphics_Dxgi_Common",

View file

@ -24,7 +24,7 @@ rustc-hash = "1.1.0"
bytemuck = "1.12.3" bytemuck = "1.12.3"
[dependencies.windows] [dependencies.windows]
version = "0.43.0" version = "0.44.0"
features = [ features = [
"Win32_Foundation", "Win32_Foundation",
"Win32_Graphics_Dxgi_Common", "Win32_Graphics_Dxgi_Common",

View file

@ -9,8 +9,8 @@ use thiserror::Error;
/// Cumulative error type for Direct3D11 filter chains. /// Cumulative error type for Direct3D11 filter chains.
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum FilterChainError { pub enum FilterChainError {
#[error("unable to get direct3d context")] #[error("invariant assumption about d3d11 did not hold. report this as an issue.")]
Direct3DContextError, Direct3DOperationError(&'static str),
#[error("direct3d driver error")] #[error("direct3d driver error")]
Direct3DError(#[from] windows::core::Error), Direct3DError(#[from] windows::core::Error),
#[error("SPIRV reflection error")] #[error("SPIRV reflection error")]
@ -27,5 +27,21 @@ pub enum FilterChainError {
LutLoadError(#[from] ImageError), 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. /// Result type for Direct3D11 filter chains.
pub type Result<T> = std::result::Result<T, FilterChainError>; pub type Result<T> = std::result::Result<T, FilterChainError>;

View file

@ -16,7 +16,7 @@ use std::collections::VecDeque;
use std::path::Path; use std::path::Path;
use crate::error::FilterChainError; use crate::error::{assume_d3d11_init, FilterChainError};
use crate::filter_pass::{ConstantBufferBinding, FilterPass}; use crate::filter_pass::{ConstantBufferBinding, FilterPass};
use crate::framebuffer::OwnedFramebuffer; use crate::framebuffer::OwnedFramebuffer;
use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11}; use crate::options::{FilterChainOptionsD3D11, FrameOptionsD3D11};
@ -101,17 +101,18 @@ impl FilterChainD3D11 {
// initialize passes // initialize passes
let filters = FilterChainD3D11::init_passes(device, passes, &semantics)?; let filters = FilterChainD3D11::init_passes(device, passes, &semantics)?;
let mut immediate_context = None; let immediate_context = unsafe { device.GetImmediateContext()? };
unsafe {
device.GetImmediateContext(&mut immediate_context);
}
let Some(immediate_context) = immediate_context else {
return Err(FilterChainError::Direct3DContextError)
};
let current_context = if use_deferred_context { 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 { } else {
immediate_context.clone() immediate_context.clone()
}; };
@ -197,7 +198,8 @@ impl FilterChainD3D11 {
impl FilterChainD3D11 { impl FilterChainD3D11 {
fn create_constant_buffer(device: &ID3D11Device, size: u32) -> error::Result<ID3D11Buffer> { fn create_constant_buffer(device: &ID3D11Device, size: u32) -> error::Result<ID3D11Buffer> {
unsafe { unsafe {
let buffer = device.CreateBuffer( let mut buffer = None;
device.CreateBuffer(
&D3D11_BUFFER_DESC { &D3D11_BUFFER_DESC {
ByteWidth: size, ByteWidth: size,
Usage: D3D11_USAGE_DYNAMIC, Usage: D3D11_USAGE_DYNAMIC,
@ -207,8 +209,9 @@ impl FilterChainD3D11 {
StructureByteStride: 0, StructureByteStride: 0,
}, },
None, None,
Some(&mut buffer),
)?; )?;
assume_d3d11_init!(buffer, "CreateBuffer");
Ok(buffer) Ok(buffer)
} }
} }
@ -602,7 +605,12 @@ impl FilterChainD3D11 {
if self.common.d3d11.context_is_deferred { if self.common.d3d11.context_is_deferred {
unsafe { 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 self.common
.d3d11 .d3d11
.immediate_context .immediate_context

View file

@ -14,7 +14,8 @@ use rustc_hash::FxHashMap;
use librashader_runtime::binding::{BindSemantics, TextureInput}; use librashader_runtime::binding::{BindSemantics, TextureInput};
use windows::Win32::Graphics::Direct3D11::{ use windows::Win32::Graphics::Direct3D11::{
ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState, ID3D11Buffer, ID3D11InputLayout, ID3D11PixelShader, ID3D11SamplerState,
ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAPPED_SUBRESOURCE,
D3D11_MAP_WRITE_DISCARD,
}; };
use crate::render_target::RenderTarget; use crate::render_target::RenderTarget;
@ -181,7 +182,8 @@ impl FilterPass {
if let Some(ubo) = &self.uniform_buffer { if let Some(ubo) = &self.uniform_buffer {
// upload uniforms // upload uniforms
unsafe { 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( std::ptr::copy_nonoverlapping(
self.uniform_storage.ubo_pointer(), self.uniform_storage.ubo_pointer(),
map.pData.cast(), map.pData.cast(),
@ -191,21 +193,18 @@ impl FilterPass {
} }
if ubo.stage_mask.contains(BindingStage::VERTEX) { if ubo.stage_mask.contains(BindingStage::VERTEX) {
unsafe { unsafe { context.VSSetConstantBuffers(ubo.binding, Some(&[ubo.buffer.clone()])) }
context.VSSetConstantBuffers(ubo.binding, Some(&[Some(ubo.buffer.clone())]))
}
} }
if ubo.stage_mask.contains(BindingStage::FRAGMENT) { if ubo.stage_mask.contains(BindingStage::FRAGMENT) {
unsafe { unsafe { context.PSSetConstantBuffers(ubo.binding, Some(&[ubo.buffer.clone()])) }
context.PSSetConstantBuffers(ubo.binding, Some(&[Some(ubo.buffer.clone())]))
}
} }
} }
if let Some(push) = &self.push_buffer { if let Some(push) = &self.push_buffer {
// upload push constants // upload push constants
unsafe { 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( std::ptr::copy_nonoverlapping(
self.uniform_storage.push_pointer(), self.uniform_storage.push_pointer(),
map.pData.cast(), map.pData.cast(),
@ -215,14 +214,10 @@ impl FilterPass {
} }
if push.stage_mask.contains(BindingStage::VERTEX) { if push.stage_mask.contains(BindingStage::VERTEX) {
unsafe { unsafe { context.VSSetConstantBuffers(push.binding, Some(&[push.buffer.clone()])) }
context.VSSetConstantBuffers(push.binding, Some(&[Some(push.buffer.clone())]))
}
} }
if push.stage_mask.contains(BindingStage::FRAGMENT) { if push.stage_mask.contains(BindingStage::FRAGMENT) {
unsafe { unsafe { context.PSSetConstantBuffers(push.binding, Some(&[push.buffer.clone()])) }
context.PSSetConstantBuffers(push.binding, Some(&[Some(push.buffer.clone())]))
}
} }
} }
@ -232,10 +227,16 @@ impl FilterPass {
} }
unsafe { unsafe {
context.PSSetShaderResources(0, Some(&textures)); // SAFETY: Niche optimization for Option<NonNull<T>>
context.PSSetSamplers(0, Some(&samplers)); // Assumes that IUnknown is defined as IUnknown(std::ptr::NonNull<std::ffi::c_void>)
const _: () = assert!(
std::mem::size_of::<Option<windows::core::IUnknown>>()
== std::mem::size_of::<windows::core::IUnknown>()
);
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])) context.RSSetViewports(Some(&[output.output.viewport]))
} }
@ -246,7 +247,7 @@ impl FilterPass {
unsafe { unsafe {
// unbind resources. // unbind resources.
context.PSSetShaderResources(0, Some(NULL_TEXTURES)); context.PSSetShaderResources(0, Some(std::mem::transmute(NULL_TEXTURES.as_ref())));
context.OMSetRenderTargets(None, None); context.OMSetRenderTargets(None, None);
} }
Ok(()) Ok(())

View file

@ -1,4 +1,5 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init;
use crate::texture::{D3D11InputView, InputTexture}; use crate::texture::{D3D11InputView, InputTexture};
use crate::util::d3d11_get_closest_format; use crate::util::d3d11_get_closest_format;
use librashader_common::{ImageFormat, Size}; use librashader_common::{ImageFormat, Size};
@ -43,7 +44,9 @@ impl OwnedFramebuffer {
| D3D11_FORMAT_SUPPORT_RENDER_TARGET.0, | D3D11_FORMAT_SUPPORT_RENDER_TARGET.0,
); );
let desc = default_desc(size, format, 1); 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 { Ok(OwnedFramebuffer {
texture, texture,
@ -101,7 +104,10 @@ impl OwnedFramebuffer {
// todo: fix mipmap handling // todo: fix mipmap handling
let desc = default_desc(size, format, 1); let desc = default_desc(size, format, 1);
unsafe { 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); std::mem::swap(&mut self.texture, &mut texture);
drop(texture) drop(texture)
} }
@ -112,8 +118,9 @@ impl OwnedFramebuffer {
} }
pub fn create_shader_resource_view(&self) -> error::Result<ID3D11ShaderResourceView> { pub fn create_shader_resource_view(&self) -> error::Result<ID3D11ShaderResourceView> {
let mut srv = None;
unsafe { unsafe {
Ok(self.device.CreateShaderResourceView( self.device.CreateShaderResourceView(
&self.texture, &self.texture,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: self.format, 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<ID3D11RenderTargetView> { pub fn create_render_target_view(&self) -> error::Result<ID3D11RenderTargetView> {
let mut rtv = None;
unsafe { unsafe {
Ok(self.device.CreateRenderTargetView( self.device.CreateRenderTargetView(
&self.texture, &self.texture,
Some(&D3D11_RENDER_TARGET_VIEW_DESC { Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: self.format, Format: self.format,
@ -140,8 +151,12 @@ impl OwnedFramebuffer {
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 }, Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
}, },
}), }),
)?) Some(&mut rtv),
)?
} }
assume_d3d11_init!(rtv, "CreateRenderTargetView");
Ok(rtv)
} }
pub fn as_output_framebuffer(&self) -> error::Result<OutputFramebuffer> { pub fn as_output_framebuffer(&self) -> error::Result<OutputFramebuffer> {
@ -154,11 +169,7 @@ impl OwnedFramebuffer {
pub fn copy_from(&mut self, image: &D3D11InputView) -> error::Result<()> { pub fn copy_from(&mut self, image: &D3D11InputView) -> error::Result<()> {
let original_resource: ID3D11Texture2D = unsafe { let original_resource: ID3D11Texture2D = unsafe {
let mut resource = None; let resource = image.handle.GetResource()?;
image.handle.GetResource(&mut resource);
let Some(resource) = resource else {
return Ok(())
};
resource.cast()? resource.cast()?
}; };

View file

@ -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 = unsafe {
let ps = slice::from_raw_parts( let ps = slice::from_raw_parts(
ps_blob.GetBufferPointer().cast::<u8>(), ps_blob.GetBufferPointer().cast::<u8>(),
ps_blob.GetBufferSize(), 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) = let (input_layout, stencil_state, raster_state) =
create_pipeline_state(&self.device, vs_compiled)?; create_pipeline_state(&self.device, vs_compiled)?;
@ -370,11 +377,13 @@ pub mod d3d11_hello_triangle {
let buffer_number = 0; let buffer_number = 0;
unsafe { unsafe {
let mapped_resource = self.context.Map( let mut mapped_resource = Default::default();
self.context.Map(
&resources.triangle_uniforms, &resources.triangle_uniforms,
0, 0,
D3D11_MAP_WRITE_DISCARD, D3D11_MAP_WRITE_DISCARD,
0, 0,
Some(&mut mapped_resource),
)?; )?;
std::ptr::copy_nonoverlapping( std::ptr::copy_nonoverlapping(
&resources.triangle_uniform_values, &resources.triangle_uniform_values,
@ -387,10 +396,10 @@ pub mod d3d11_hello_triangle {
unsafe { unsafe {
self.context.VSSetConstantBuffers( self.context.VSSetConstantBuffers(
buffer_number, buffer_number,
Some(&[Some(resources.triangle_uniforms.clone())]), Some(&[resources.triangle_uniforms.clone()]),
); );
self.context.OMSetRenderTargets( self.context.OMSetRenderTargets(
Some(&[Some(resources.rtv.clone())]), Some(&[resources.rtv.clone()]),
&resources.depth_stencil_view, &resources.depth_stencil_view,
); );
self.context.RSSetViewports(Some(&[resources.viewport])) self.context.RSSetViewports(Some(&[resources.viewport]))
@ -435,18 +444,23 @@ pub mod d3d11_hello_triangle {
unsafe { unsafe {
let mut tex2d_desc = Default::default(); let mut tex2d_desc = Default::default();
resources.backbuffer.GetDesc(&mut tex2d_desc); resources.backbuffer.GetDesc(&mut tex2d_desc);
let backup = self.device.CreateTexture2D( let mut backup = None;
self.device.CreateTexture2D(
&D3D11_TEXTURE2D_DESC { &D3D11_TEXTURE2D_DESC {
BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, BindFlags: D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, CPUAccessFlags: D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE,
..tex2d_desc ..tex2d_desc
}, },
None, None,
Some(&mut backup),
)?; )?;
let backup = backup.unwrap();
self.context.CopyResource(&backup, &resources.backbuffer); self.context.CopyResource(&backup, &resources.backbuffer);
let srv = self.device.CreateShaderResourceView( let mut srv = None;
self.device.CreateShaderResourceView(
&backup, &backup,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: tex2d_desc.Format, 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, &shader_out,
Some(&D3D11_RENDER_TARGET_VIEW_DESC { Some(&D3D11_RENDER_TARGET_VIEW_DESC {
Format: tex2d_desc.Format, Format: tex2d_desc.Format,
@ -471,6 +491,7 @@ pub mod d3d11_hello_triangle {
Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 }, Texture2D: D3D11_TEX2D_RTV { MipSlice: 0 },
}, },
}), }),
Some(&mut rtv),
)?; )?;
// OutputFramebuffer { // OutputFramebuffer {
@ -533,9 +554,10 @@ pub mod d3d11_hello_triangle {
) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)> { ) -> Result<(ID3D11RenderTargetView, ID3D11Texture2D)> {
unsafe { unsafe {
let backbuffer: ID3D11Texture2D = swapchain.GetBuffer(0)?; 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( fn create_pipeline_state(
@ -547,7 +569,8 @@ pub mod d3d11_hello_triangle {
ID3D11RasterizerState, ID3D11RasterizerState,
)> { )> {
unsafe { unsafe {
let input_layout = device.CreateInputLayout( let mut input_layout = None;
device.CreateInputLayout(
&[ &[
D3D11_INPUT_ELEMENT_DESC { D3D11_INPUT_ELEMENT_DESC {
SemanticName: s!("POSITION"), SemanticName: s!("POSITION"),
@ -569,42 +592,55 @@ pub mod d3d11_hello_triangle {
}, },
], ],
vs_blob, vs_blob,
Some(&mut input_layout),
)?; )?;
let stencil_state = device.CreateDepthStencilState(&D3D11_DEPTH_STENCIL_DESC { let input_layout = input_layout.unwrap();
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 rasterizer_state = device.CreateRasterizerState(&D3D11_RASTERIZER_DESC { let mut stencil_state = None;
AntialiasedLineEnable: BOOL::from(false), device.CreateDepthStencilState(
CullMode: D3D11_CULL_NONE, &D3D11_DEPTH_STENCIL_DESC {
DepthBias: 0, DepthEnable: BOOL::from(true),
DepthBiasClamp: 0.0f32, DepthWriteMask: D3D11_DEPTH_WRITE_MASK_ALL,
DepthClipEnable: BOOL::from(true), DepthFunc: D3D11_COMPARISON_LESS,
FillMode: D3D11_FILL_SOLID, StencilEnable: BOOL::from(true),
FrontCounterClockwise: BOOL::from(false), StencilReadMask: 0xff,
MultisampleEnable: BOOL::from(false), StencilWriteMask: 0xff,
ScissorEnable: BOOL::from(false), FrontFace: D3D11_DEPTH_STENCILOP_DESC {
SlopeScaledDepthBias: 0.0f32, 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)) Ok((input_layout, stencil_state, rasterizer_state))
} }
} }
@ -613,7 +649,8 @@ pub mod d3d11_hello_triangle {
device: &ID3D11Device, device: &ID3D11Device,
) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)> { ) -> Result<(ID3D11Texture2D, ID3D11DepthStencilView)> {
unsafe { unsafe {
let buffer = device.CreateTexture2D( let mut buffer = None;
device.CreateTexture2D(
&D3D11_TEXTURE2D_DESC { &D3D11_TEXTURE2D_DESC {
Width: WIDTH as u32, Width: WIDTH as u32,
Height: HEIGHT as u32, Height: HEIGHT as u32,
@ -630,9 +667,13 @@ pub mod d3d11_hello_triangle {
MiscFlags: Default::default(), MiscFlags: Default::default(),
}, },
None, None,
Some(&mut buffer),
)?; )?;
let view = device.CreateDepthStencilView( let buffer = buffer.unwrap();
let mut view = None;
device.CreateDepthStencilView(
&buffer, &buffer,
Some(&D3D11_DEPTH_STENCIL_VIEW_DESC { Some(&D3D11_DEPTH_STENCIL_VIEW_DESC {
Format: DXGI_FORMAT_D24_UNORM_S8_UINT, Format: DXGI_FORMAT_D24_UNORM_S8_UINT,
@ -642,13 +683,17 @@ pub mod d3d11_hello_triangle {
}, },
..Default::default() ..Default::default()
}), }),
Some(&mut view),
)?; )?;
let view = view.unwrap();
Ok((buffer, view)) Ok((buffer, view))
} }
} }
fn create_triangle_uniforms(device: &ID3D11Device) -> Result<ID3D11Buffer> { fn create_triangle_uniforms(device: &ID3D11Device) -> Result<ID3D11Buffer> {
let mut buffer = None;
unsafe { unsafe {
device.CreateBuffer( device.CreateBuffer(
&D3D11_BUFFER_DESC { &D3D11_BUFFER_DESC {
@ -660,8 +705,10 @@ pub mod d3d11_hello_triangle {
StructureByteStride: 0, StructureByteStride: 0,
}, },
None, None,
) Some(&mut buffer),
)?;
} }
Ok(buffer.unwrap())
} }
fn create_triangle_buffers(device: &ID3D11Device) -> Result<(ID3D11Buffer, ID3D11Buffer)> { fn create_triangle_buffers(device: &ID3D11Device) -> Result<(ID3D11Buffer, ID3D11Buffer)> {
@ -682,7 +729,8 @@ pub mod d3d11_hello_triangle {
let indices = [0, 1, 2]; let indices = [0, 1, 2];
unsafe { unsafe {
let vertex_buffer = device.CreateBuffer( let mut vertex_buffer = None;
device.CreateBuffer(
&D3D11_BUFFER_DESC { &D3D11_BUFFER_DESC {
ByteWidth: (std::mem::size_of::<Vertex>() * vertices.len()) as u32, ByteWidth: (std::mem::size_of::<Vertex>() * vertices.len()) as u32,
Usage: D3D11_USAGE_DEFAULT, Usage: D3D11_USAGE_DEFAULT,
@ -696,9 +744,11 @@ pub mod d3d11_hello_triangle {
SysMemPitch: 0, SysMemPitch: 0,
SysMemSlicePitch: 0, SysMemSlicePitch: 0,
}), }),
Some(&mut vertex_buffer),
)?; )?;
let index_buffer = device.CreateBuffer( let mut index_buffer = None;
device.CreateBuffer(
&D3D11_BUFFER_DESC { &D3D11_BUFFER_DESC {
ByteWidth: (std::mem::size_of::<u32>() * indices.len()) as u32, ByteWidth: (std::mem::size_of::<u32>() * indices.len()) as u32,
Usage: D3D11_USAGE_DEFAULT, Usage: D3D11_USAGE_DEFAULT,
@ -712,9 +762,10 @@ pub mod d3d11_hello_triangle {
SysMemPitch: 0, SysMemPitch: 0,
SysMemSlicePitch: 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)> { fn create_device() -> Result<(IDXGIFactory4, ID3D11Device, ID3D11DeviceContext)> {

View file

@ -1,4 +1,5 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init;
use bytemuck::offset_of; use bytemuck::offset_of;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; use windows::Win32::Graphics::Direct3D::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
@ -52,7 +53,8 @@ pub(crate) struct DrawQuad {
impl DrawQuad { impl DrawQuad {
pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> error::Result<DrawQuad> { pub fn new(device: &ID3D11Device, context: &ID3D11DeviceContext) -> error::Result<DrawQuad> {
unsafe { unsafe {
let buffer = device.CreateBuffer( let mut buffer = None;
device.CreateBuffer(
&D3D11_BUFFER_DESC { &D3D11_BUFFER_DESC {
ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32, ByteWidth: std::mem::size_of::<[D3D11Vertex; 4]>() as u32,
Usage: D3D11_USAGE_IMMUTABLE, Usage: D3D11_USAGE_IMMUTABLE,
@ -66,7 +68,9 @@ impl DrawQuad {
SysMemPitch: 0, SysMemPitch: 0,
SysMemSlicePitch: 0, SysMemSlicePitch: 0,
}), }),
Some(&mut buffer),
)?; )?;
assume_d3d11_init!(buffer, "CreateBuffer");
Ok(DrawQuad { Ok(DrawQuad {
buffer, buffer,

View file

@ -1,4 +1,4 @@
use crate::error::Result; use crate::error::{assume_d3d11_init, Result};
use librashader_common::{FilterMode, WrapMode}; use librashader_common::{FilterMode, WrapMode};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use windows::Win32::Graphics::Direct3D11::{ use windows::Win32::Graphics::Direct3D11::{
@ -23,31 +23,42 @@ impl SamplerSet {
]; ];
for wrap_mode in wrap_modes { for wrap_mode in wrap_modes {
unsafe { unsafe {
let linear = device.CreateSamplerState(&D3D11_SAMPLER_DESC { let mut linear = None;
Filter: FilterMode::Linear.into(), device.CreateSamplerState(
AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), &D3D11_SAMPLER_DESC {
AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), Filter: FilterMode::Linear.into(),
AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
MipLODBias: 0.0, AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
MaxAnisotropy: 1, AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
ComparisonFunc: D3D11_COMPARISON_NEVER, MipLODBias: 0.0,
BorderColor: [0.0, 0.0, 0.0, 0.0], MaxAnisotropy: 1,
MinLOD: -D3D11_FLOAT32_MAX, ComparisonFunc: D3D11_COMPARISON_NEVER,
MaxLOD: D3D11_FLOAT32_MAX, 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 { assume_d3d11_init!(linear, "CreateSamplerState");
Filter: FilterMode::Nearest.into(),
AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), let mut nearest = None;
AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), device.CreateSamplerState(
AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode), &D3D11_SAMPLER_DESC {
MipLODBias: 0.0, Filter: FilterMode::Nearest.into(),
MaxAnisotropy: 1, AddressU: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
ComparisonFunc: D3D11_COMPARISON_NEVER, AddressV: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
BorderColor: [0.0, 0.0, 0.0, 0.0], AddressW: D3D11_TEXTURE_ADDRESS_MODE::from(*wrap_mode),
MinLOD: -D3D11_FLOAT32_MAX, MipLODBias: 0.0,
MaxLOD: D3D11_FLOAT32_MAX, 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::Linear), linear);
samplers.insert((*wrap_mode, FilterMode::Nearest), nearest); samplers.insert((*wrap_mode, FilterMode::Nearest), nearest);

View file

@ -11,7 +11,7 @@ use windows::Win32::Graphics::Direct3D11::{
}; };
use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use crate::error::Result; use crate::error::{assume_d3d11_init, Result};
use crate::framebuffer::OwnedFramebuffer; use crate::framebuffer::OwnedFramebuffer;
/// An image view for use as a shader resource. /// An image view for use as a shader resource.
@ -131,10 +131,13 @@ impl LutTexture {
// since we load them with the Image module. // since we load them with the Image module.
unsafe { 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 // need a staging texture to defer mipmap generation
let staging = device.CreateTexture2D( let mut staging = None;
device.CreateTexture2D(
&D3D11_TEXTURE2D_DESC { &D3D11_TEXTURE2D_DESC {
MipLevels: 1, MipLevels: 1,
BindFlags: D3D11_BIND_FLAG(0), BindFlags: D3D11_BIND_FLAG(0),
@ -148,7 +151,9 @@ impl LutTexture {
SysMemPitch: source.pitch as u32, SysMemPitch: source.pitch as u32,
SysMemSlicePitch: 0, SysMemSlicePitch: 0,
}), }),
Some(&mut staging),
)?; )?;
assume_d3d11_init!(staging, "CreateTexture2D");
// todo: do format conversion (leverage image crate..? // todo: do format conversion (leverage image crate..?
// is this necessary with CopySubresourceRegion)... // is this necessary with CopySubresourceRegion)...
@ -171,7 +176,8 @@ impl LutTexture {
}), }),
); );
let srv = device.CreateShaderResourceView( let mut srv = None;
device.CreateShaderResourceView(
&handle, &handle,
Some(&D3D11_SHADER_RESOURCE_VIEW_DESC { Some(&D3D11_SHADER_RESOURCE_VIEW_DESC {
Format: desc.Format, 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 { if (desc.MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS).0 != 0 {
context.GenerateMips(&srv) context.GenerateMips(&srv)

View file

@ -1,4 +1,5 @@
use crate::error; use crate::error;
use crate::error::assume_d3d11_init;
use std::slice; use std::slice;
use windows::core::PCSTR; use windows::core::PCSTR;
use windows::Win32::Graphics::Direct3D::Fxc::{ 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> = pub type ShaderFactory<'a, L, T> = unsafe fn(
unsafe fn(&'a ID3D11Device, &[u8], linkage: L) -> windows::core::Result<T>; &'a ID3D11Device,
&[u8],
linkage: L,
Option<*mut Option<T>>,
) -> windows::core::Result<()>;
pub fn d3d11_compile_bound_shader<'a, T, L>( pub fn d3d11_compile_bound_shader<'a, T, L>(
device: &'a ID3D11Device, device: &'a ID3D11Device,
@ -139,14 +144,16 @@ pub fn d3d11_compile_bound_shader<'a, T, L>(
factory: ShaderFactory<'a, L, T>, factory: ShaderFactory<'a, L, T>,
) -> error::Result<T> ) -> error::Result<T>
where where
L: Into<windows::core::InParam<'a, ID3D11ClassLinkage>>, L: Into<windows::core::InParam<ID3D11ClassLinkage>>,
{ {
unsafe { unsafe {
// SAFETY: slice as valid for as long as vs_blob is alive. // SAFETY: slice as valid for as long as vs_blob is alive.
let dxil = let dxil =
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize()); slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), 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) Ok(compiled)
} }
} }
@ -160,8 +167,9 @@ pub fn d3d11_create_input_layout(
// SAFETY: slice as valid for as long as vs_blob is alive. // SAFETY: slice as valid for as long as vs_blob is alive.
let dxil = let dxil =
slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize()); slice::from_raw_parts(blob.GetBufferPointer().cast::<u8>(), blob.GetBufferSize());
let mut input_layout = None;
let compiled = device.CreateInputLayout(desc, dxil)?; device.CreateInputLayout(desc, dxil, Some(&mut input_layout))?;
Ok(compiled) assume_d3d11_init!(input_layout, "CreateInputLayout");
Ok(input_layout)
} }
} }

View file

@ -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 } ash = { version = "0.37.1+1.3.235", optional = true }
[dependencies.windows] [dependencies.windows]
version = "0.43.0" version = "0.44.0"
features = [ features = [
"Win32_Graphics_Direct3D11", "Win32_Graphics_Direct3D11",
] ]