Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dx11 Backend #2443

Merged
merged 9 commits into from
Mar 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ default-members = ["wgpu", "wgpu-hal", "wgpu-info"]
[patch.crates-io]
#naga = { path = "../naga" }
#glow = { path = "../glow" }
#d3d12 = { path = "../d3d12-rs" }
#metal = { path = "../metal-rs" }
#web-sys = { path = "../wasm-bindgen/crates/web-sys" }
#js-sys = { path = "../wasm-bindgen/crates/js-sys" }
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ hal = { path = "../wgpu-hal", package = "wgpu-hal", version = "0.12", features =
hal = { path = "../wgpu-hal", package = "wgpu-hal", version = "0.12", features = ["vulkan", "gles", "renderdoc"] }

[target.'cfg(all(not(target_arch = "wasm32"), windows))'.dependencies]
hal = { path = "../wgpu-hal", package = "wgpu-hal", version = "0.12", features = ["vulkan", "dx12", "renderdoc"] }
hal = { path = "../wgpu-hal", package = "wgpu-hal", version = "0.12", features = ["vulkan", "dx12", "dx11", "renderdoc"] }

[target.'cfg(target_os = "emscripten")'.dependencies]
hal = { path = "../wgpu-hal", package = "wgpu-hal", version = "0.12", features = ["emscripten"] }
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
vulkan: { all(not(wasm), any(windows, unix_wo_apple, feature = "vulkan-portability")) },
metal: { all(not(wasm), apple) },
dx12: { all(not(wasm), windows) },
dx11: { all(false, not(wasm), windows) },
dx11: { all(not(wasm), windows) },
gl: {
any(
unix_wo_apple,
Expand Down
9 changes: 7 additions & 2 deletions wgpu-core/src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,10 +1042,16 @@ impl HalApi for hal::api::Dx12 {
}
}

/*
#[cfg(dx11)]
impl HalApi for hal::api::Dx11 {
const VARIANT: Backend = Backend::Dx11;
fn create_instance_from_hal(name: &str, hal_instance: Self::Instance) -> Instance {
Instance {
name: name.to_owned(),
dx11: Some(hal_instance),
..Default::default()
}
}
fn hub<G: GlobalIdentityHandlerFactory>(global: &Global<G>) -> &Hub<Self, G> {
&global.hubs.dx11
}
Expand All @@ -1056,7 +1062,6 @@ impl HalApi for hal::api::Dx11 {
surface.dx11.as_mut().unwrap()
}
}
*/

#[cfg(gl)]
impl HalApi for hal::api::Gles {
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
dx12: self.instance.dx12.as_ref().map(|inst| HalSurface {
raw: { inst.create_surface_from_visual(visual as _) },
}),
dx11: None,
#[cfg(gl)]
gl: None,
};
Expand Down
4 changes: 2 additions & 2 deletions wgpu-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ macro_rules! gfx_select {
wgt::Backend::Metal => $global.$method::<$crate::api::Metal>( $($param),* ),
#[cfg(all(not(target_arch = "wasm32"), windows))]
wgt::Backend::Dx12 => $global.$method::<$crate::api::Dx12>( $($param),* ),
//#[cfg(all(not(target_arch = "wasm32"), windows))]
//wgt::Backend::Dx11 => $global.$method::<$crate::api::Dx11>( $($param),* ),
#[cfg(all(not(target_arch = "wasm32"), windows))]
wgt::Backend::Dx11 => $global.$method::<$crate::api::Dx11>( $($param),* ),
#[cfg(any(
all(unix, not(target_os = "macos"), not(target_os = "ios")),
feature = "angle",
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ default = []
metal = ["naga/msl-out", "block", "foreign-types"]
vulkan = ["naga/spv-out", "ash", "gpu-alloc", "gpu-descriptor", "libloading", "inplace_it"]
gles = ["naga/glsl-out", "glow", "egl", "libloading"]
dx11 = ["naga/hlsl-out", "native", "libloading", "winapi/d3d11", "winapi/d3d11_1", "winapi/d3d11_2", "winapi/d3d11sdklayers", "winapi/dxgi1_6"]
dx12 = ["naga/hlsl-out", "native", "bit-set", "range-alloc", "winapi/d3d12", "winapi/d3d12shader", "winapi/d3d12sdklayers", "winapi/dxgi1_6"]
renderdoc = ["libloading", "renderdoc-sys"]
emscripten = ["gles"]
Expand Down Expand Up @@ -74,7 +75,8 @@ libloading = { version = "0.7", optional = true }

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["libloaderapi", "windef", "winuser", "dcomp"] }
native = { package = "d3d12", version = "0.4.1", features = ["libloading"], optional = true }
# native = { package = "d3d12", version = "0.4.1", features = ["libloading"], optional = true }
native = { package = "d3d12", git = "https://github.com/gfx-rs/d3d12-rs.git", rev = "ffe5e261da0a6cb85332b82ab310abd2a7e849f6", features = ["libloading"], optional = true }

[target.'cfg(any(target_os="macos", target_os="ios"))'.dependencies]
mtl = { package = "metal", git = "https://github.com/gfx-rs/metal-rs", rev = "44af5cc" }
Expand Down
175 changes: 175 additions & 0 deletions wgpu-hal/src/auxil/dxgi/conv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
use winapi::shared::dxgiformat;

pub fn map_texture_format(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
cwfitzgerald marked this conversation as resolved.
Show resolved Hide resolved
use wgt::TextureFormat as Tf;
use winapi::shared::dxgiformat::*;

match format {
Tf::R8Unorm => DXGI_FORMAT_R8_UNORM,
Tf::R8Snorm => DXGI_FORMAT_R8_SNORM,
Tf::R8Uint => DXGI_FORMAT_R8_UINT,
Tf::R8Sint => DXGI_FORMAT_R8_SINT,
Tf::R16Uint => DXGI_FORMAT_R16_UINT,
Tf::R16Sint => DXGI_FORMAT_R16_SINT,
Tf::R16Unorm => DXGI_FORMAT_R16_UNORM,
Tf::R16Snorm => DXGI_FORMAT_R16_SNORM,
Tf::R16Float => DXGI_FORMAT_R16_FLOAT,
Tf::Rg8Unorm => DXGI_FORMAT_R8G8_UNORM,
Tf::Rg8Snorm => DXGI_FORMAT_R8G8_SNORM,
Tf::Rg8Uint => DXGI_FORMAT_R8G8_UINT,
Tf::Rg8Sint => DXGI_FORMAT_R8G8_SINT,
Tf::Rg16Unorm => DXGI_FORMAT_R16G16_UNORM,
Tf::Rg16Snorm => DXGI_FORMAT_R16G16_SNORM,
Tf::R32Uint => DXGI_FORMAT_R32_UINT,
Tf::R32Sint => DXGI_FORMAT_R32_SINT,
Tf::R32Float => DXGI_FORMAT_R32_FLOAT,
Tf::Rg16Uint => DXGI_FORMAT_R16G16_UINT,
Tf::Rg16Sint => DXGI_FORMAT_R16G16_SINT,
Tf::Rg16Float => DXGI_FORMAT_R16G16_FLOAT,
Tf::Rgba8Unorm => DXGI_FORMAT_R8G8B8A8_UNORM,
Tf::Rgba8UnormSrgb => DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
Tf::Bgra8UnormSrgb => DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
Tf::Rgba8Snorm => DXGI_FORMAT_R8G8B8A8_SNORM,
Tf::Bgra8Unorm => DXGI_FORMAT_B8G8R8A8_UNORM,
Tf::Rgba8Uint => DXGI_FORMAT_R8G8B8A8_UINT,
Tf::Rgba8Sint => DXGI_FORMAT_R8G8B8A8_SINT,
Tf::Rgb10a2Unorm => DXGI_FORMAT_R10G10B10A2_UNORM,
Tf::Rg11b10Float => DXGI_FORMAT_R11G11B10_FLOAT,
Tf::Rg32Uint => DXGI_FORMAT_R32G32_UINT,
Tf::Rg32Sint => DXGI_FORMAT_R32G32_SINT,
Tf::Rg32Float => DXGI_FORMAT_R32G32_FLOAT,
Tf::Rgba16Uint => DXGI_FORMAT_R16G16B16A16_UINT,
Tf::Rgba16Sint => DXGI_FORMAT_R16G16B16A16_SINT,
Tf::Rgba16Unorm => DXGI_FORMAT_R16G16B16A16_UNORM,
Tf::Rgba16Snorm => DXGI_FORMAT_R16G16B16A16_SNORM,
Tf::Rgba16Float => DXGI_FORMAT_R16G16B16A16_FLOAT,
Tf::Rgba32Uint => DXGI_FORMAT_R32G32B32A32_UINT,
Tf::Rgba32Sint => DXGI_FORMAT_R32G32B32A32_SINT,
Tf::Rgba32Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
Tf::Depth32Float => DXGI_FORMAT_D32_FLOAT,
Tf::Depth24Plus => DXGI_FORMAT_D24_UNORM_S8_UINT,
Tf::Depth24PlusStencil8 => DXGI_FORMAT_D24_UNORM_S8_UINT,
Tf::Rgb9e5Ufloat => DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
Tf::Bc1RgbaUnorm => DXGI_FORMAT_BC1_UNORM,
Tf::Bc1RgbaUnormSrgb => DXGI_FORMAT_BC1_UNORM_SRGB,
Tf::Bc2RgbaUnorm => DXGI_FORMAT_BC2_UNORM,
Tf::Bc2RgbaUnormSrgb => DXGI_FORMAT_BC2_UNORM_SRGB,
Tf::Bc3RgbaUnorm => DXGI_FORMAT_BC3_UNORM,
Tf::Bc3RgbaUnormSrgb => DXGI_FORMAT_BC3_UNORM_SRGB,
Tf::Bc4RUnorm => DXGI_FORMAT_BC4_UNORM,
Tf::Bc4RSnorm => DXGI_FORMAT_BC4_SNORM,
Tf::Bc5RgUnorm => DXGI_FORMAT_BC5_UNORM,
Tf::Bc5RgSnorm => DXGI_FORMAT_BC5_SNORM,
Tf::Bc6hRgbUfloat => DXGI_FORMAT_BC6H_UF16,
Tf::Bc6hRgbSfloat => DXGI_FORMAT_BC6H_SF16,
Tf::Bc7RgbaUnorm => DXGI_FORMAT_BC7_UNORM,
Tf::Bc7RgbaUnormSrgb => DXGI_FORMAT_BC7_UNORM_SRGB,
Tf::Etc2Rgb8Unorm
| Tf::Etc2Rgb8UnormSrgb
| Tf::Etc2Rgb8A1Unorm
| Tf::Etc2Rgb8A1UnormSrgb
| Tf::Etc2Rgba8Unorm
| Tf::Etc2Rgba8UnormSrgb
| Tf::EacR11Unorm
| Tf::EacR11Snorm
| Tf::EacRg11Unorm
| Tf::EacRg11Snorm
| Tf::Astc {
block: _,
channel: _,
} => unreachable!(),
}
}

// Note: DXGI doesn't allow sRGB format on the swapchain,
// but creating RTV of swapchain buffers with sRGB works.
pub fn map_texture_format_nosrgb(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
match format {
wgt::TextureFormat::Bgra8UnormSrgb => dxgiformat::DXGI_FORMAT_B8G8R8A8_UNORM,
wgt::TextureFormat::Rgba8UnormSrgb => dxgiformat::DXGI_FORMAT_R8G8B8A8_UNORM,
_ => map_texture_format(format),
}
}

//Note: SRV and UAV can't use the depth formats directly
//TODO: stencil views?
pub fn map_texture_format_nodepth(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
match format {
wgt::TextureFormat::Depth32Float => dxgiformat::DXGI_FORMAT_R32_FLOAT,
wgt::TextureFormat::Depth24Plus | wgt::TextureFormat::Depth24PlusStencil8 => {
dxgiformat::DXGI_FORMAT_R24_UNORM_X8_TYPELESS
}
_ => {
assert_eq!(
crate::FormatAspects::from(format),
crate::FormatAspects::COLOR
);
map_texture_format(format)
}
}
}

pub fn map_texture_format_depth_typeless(format: wgt::TextureFormat) -> dxgiformat::DXGI_FORMAT {
match format {
wgt::TextureFormat::Depth32Float => dxgiformat::DXGI_FORMAT_R32_TYPELESS,
wgt::TextureFormat::Depth24Plus | wgt::TextureFormat::Depth24PlusStencil8 => {
dxgiformat::DXGI_FORMAT_R24G8_TYPELESS
}
_ => unreachable!(),
}
}

pub fn map_index_format(format: wgt::IndexFormat) -> dxgiformat::DXGI_FORMAT {
match format {
wgt::IndexFormat::Uint16 => dxgiformat::DXGI_FORMAT_R16_UINT,
wgt::IndexFormat::Uint32 => dxgiformat::DXGI_FORMAT_R32_UINT,
}
}

pub fn map_vertex_format(format: wgt::VertexFormat) -> dxgiformat::DXGI_FORMAT {
use wgt::VertexFormat as Vf;
use winapi::shared::dxgiformat::*;

match format {
Vf::Unorm8x2 => DXGI_FORMAT_R8G8_UNORM,
Vf::Snorm8x2 => DXGI_FORMAT_R8G8_SNORM,
Vf::Uint8x2 => DXGI_FORMAT_R8G8_UINT,
Vf::Sint8x2 => DXGI_FORMAT_R8G8_SINT,
Vf::Unorm8x4 => DXGI_FORMAT_R8G8B8A8_UNORM,
Vf::Snorm8x4 => DXGI_FORMAT_R8G8B8A8_SNORM,
Vf::Uint8x4 => DXGI_FORMAT_R8G8B8A8_UINT,
Vf::Sint8x4 => DXGI_FORMAT_R8G8B8A8_SINT,
Vf::Unorm16x2 => DXGI_FORMAT_R16G16_UNORM,
Vf::Snorm16x2 => DXGI_FORMAT_R16G16_SNORM,
Vf::Uint16x2 => DXGI_FORMAT_R16G16_UINT,
Vf::Sint16x2 => DXGI_FORMAT_R16G16_SINT,
Vf::Float16x2 => DXGI_FORMAT_R16G16_FLOAT,
Vf::Unorm16x4 => DXGI_FORMAT_R16G16B16A16_UNORM,
Vf::Snorm16x4 => DXGI_FORMAT_R16G16B16A16_SNORM,
Vf::Uint16x4 => DXGI_FORMAT_R16G16B16A16_UINT,
Vf::Sint16x4 => DXGI_FORMAT_R16G16B16A16_SINT,
Vf::Float16x4 => DXGI_FORMAT_R16G16B16A16_FLOAT,
Vf::Uint32 => DXGI_FORMAT_R32_UINT,
Vf::Sint32 => DXGI_FORMAT_R32_SINT,
Vf::Float32 => DXGI_FORMAT_R32_FLOAT,
Vf::Uint32x2 => DXGI_FORMAT_R32G32_UINT,
Vf::Sint32x2 => DXGI_FORMAT_R32G32_SINT,
Vf::Float32x2 => DXGI_FORMAT_R32G32_FLOAT,
Vf::Uint32x3 => DXGI_FORMAT_R32G32B32_UINT,
Vf::Sint32x3 => DXGI_FORMAT_R32G32B32_SINT,
Vf::Float32x3 => DXGI_FORMAT_R32G32B32_FLOAT,
Vf::Uint32x4 => DXGI_FORMAT_R32G32B32A32_UINT,
Vf::Sint32x4 => DXGI_FORMAT_R32G32B32A32_SINT,
Vf::Float32x4 => DXGI_FORMAT_R32G32B32A32_FLOAT,
Vf::Float64 | Vf::Float64x2 | Vf::Float64x3 | Vf::Float64x4 => unimplemented!(),
}
}

pub fn map_acomposite_alpha_mode(mode: crate::CompositeAlphaMode) -> native::AlphaMode {
use crate::CompositeAlphaMode as Cam;
match mode {
Cam::Opaque => native::AlphaMode::Ignore,
Cam::PreMultiplied => native::AlphaMode::Premultiplied,
Cam::PostMultiplied => native::AlphaMode::Straight,
}
}
98 changes: 98 additions & 0 deletions wgpu-hal/src/auxil/dxgi/exception.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use std::{borrow::Cow, slice};

use parking_lot::{lock_api::RawMutex, Mutex};
use winapi::{
um::{errhandlingapi, winnt},
vc::excpt,
};

// This is a mutex as opposed to an atomic as we need to completely
// lock everyone out until we have registered or unregistered the
// exception handler, otherwise really nasty races could happen.
//
// By routing all the registration through these functions we can guarentee
// there is either 1 or 0 exception handlers registered, not multiple.
static EXCEPTION_HANLDER_COUNT: Mutex<usize> = Mutex::const_new(parking_lot::RawMutex::INIT, 0);

pub fn register_exception_handler() {
let mut count_guard = EXCEPTION_HANLDER_COUNT.lock();
if *count_guard == 0 {
unsafe {
errhandlingapi::AddVectoredExceptionHandler(0, Some(output_debug_string_handler))
};
}
*count_guard += 1;
}

pub fn unregister_exception_handler() {
let mut count_guard = EXCEPTION_HANLDER_COUNT.lock();
if *count_guard == 1 {
unsafe {
errhandlingapi::RemoveVectoredExceptionHandler(output_debug_string_handler as *mut _)
};
}
*count_guard -= 1;
}

const MESSAGE_PREFIXES: &[(&str, log::Level)] = &[
("CORRUPTION", log::Level::Error),
("ERROR", log::Level::Error),
("WARNING", log::Level::Warn),
("INFO", log::Level::Info),
("MESSAGE", log::Level::Debug),
];

unsafe extern "system" fn output_debug_string_handler(
exception_info: *mut winnt::EXCEPTION_POINTERS,
) -> i32 {
// See https://stackoverflow.com/a/41480827
let record = &*(*exception_info).ExceptionRecord;
if record.NumberParameters != 2 {
return excpt::EXCEPTION_CONTINUE_SEARCH;
}
let message = match record.ExceptionCode {
winnt::DBG_PRINTEXCEPTION_C => String::from_utf8_lossy(slice::from_raw_parts(
record.ExceptionInformation[1] as *const u8,
record.ExceptionInformation[0],
)),
winnt::DBG_PRINTEXCEPTION_WIDE_C => {
Cow::Owned(String::from_utf16_lossy(slice::from_raw_parts(
record.ExceptionInformation[1] as *const u16,
record.ExceptionInformation[0],
)))
}
_ => return excpt::EXCEPTION_CONTINUE_SEARCH,
};

let message = match message.strip_prefix("D3D12 ") {
Some(msg) => msg
.trim_end_matches("\n\0")
.trim_end_matches("[ STATE_CREATION WARNING #0: UNKNOWN]"),
None => return excpt::EXCEPTION_CONTINUE_SEARCH,
};

let (message, level) = match MESSAGE_PREFIXES
.iter()
.find(|&&(prefix, _)| message.starts_with(prefix))
{
Some(&(prefix, level)) => (&message[prefix.len() + 2..], level),
None => (message, log::Level::Debug),
};

if level == log::Level::Warn && message.contains("#82") {
// This is are useless spammy warnings (#820, #821):
// "The application did not pass any clear value to resource creation"
return excpt::EXCEPTION_CONTINUE_SEARCH;
}

let _ = std::panic::catch_unwind(|| {
log::log!(level, "{}", message);
});

if cfg!(debug_assertions) && level == log::Level::Error {
// Set canary and continue
crate::VALIDATION_CANARY.set();
}

excpt::EXCEPTION_CONTINUE_EXECUTION
}
Loading