diff --git a/src/backend/dx12/Cargo.toml b/src/backend/dx12/Cargo.toml index 5b91c9ba253..3b1a508f63d 100644 --- a/src/backend/dx12/Cargo.toml +++ b/src/backend/dx12/Cargo.toml @@ -23,7 +23,7 @@ auxil = { path = "../../auxil/auxil", version = "0.2", package = "gfx-auxil", fe hal = { path = "../../hal", version = "0.4", package = "gfx-hal" } range-alloc = { path = "../../auxil/range-alloc", version = "0.1" } bitflags = "1" -native = { version = "0.2.2", package = "d3d12" } +native = { package = "d3d12", version = "0.3", features = ["libloading"] } log = { version = "0.4" } smallvec = "0.6" spirv_cross = { version = "0.16", features = ["hlsl"] } diff --git a/src/backend/dx12/src/command.rs b/src/backend/dx12/src/command.rs index 287c715da28..ee0ddd31ff2 100644 --- a/src/backend/dx12/src/command.rs +++ b/src/backend/dx12/src/command.rs @@ -32,8 +32,6 @@ use winapi::{ Interface, }; -use device::{ViewInfo, IDENTITY_MAPPING}; -use native::descriptor; use smallvec::SmallVec; use crate::{ @@ -676,12 +674,12 @@ impl CommandBuffer { stencil: Option, rects: &[d3d12::D3D12_RECT], ) { - let mut flags = native::command_list::ClearFlags::empty(); + let mut flags = native::ClearFlags::empty(); if depth.is_some() { - flags |= native::command_list::ClearFlags::DEPTH; + flags |= native::ClearFlags::DEPTH; } if stencil.is_some() { - flags |= native::command_list::ClearFlags::STENCIL; + flags |= native::ClearFlags::STENCIL; } self.raw.clear_depth_stencil_view( @@ -1482,7 +1480,7 @@ impl com::CommandBuffer for CommandBuffer { let mut rtv_pool = descriptors_cpu::HeapLinear::new( device, - descriptor::HeapType::Rtv, + native::DescriptorHeapType::Rtv, clear_rects.len(), ); @@ -1496,7 +1494,7 @@ impl com::CommandBuffer for CommandBuffer { caps: image::ViewCapabilities::empty(), view_kind: image::ViewKind::D2Array, format: attachment.dxgi_format, - component_mapping: IDENTITY_MAPPING, + component_mapping: device::IDENTITY_MAPPING, range: image::SubresourceRange { aspects: Aspects::COLOR, levels: attachment.mip_levels.0 .. attachment.mip_levels.1, @@ -1519,7 +1517,7 @@ impl com::CommandBuffer for CommandBuffer { let mut dsv_pool = descriptors_cpu::HeapLinear::new( device, - descriptor::HeapType::Dsv, + native::DescriptorHeapType::Dsv, clear_rects.len(), ); @@ -1533,7 +1531,7 @@ impl com::CommandBuffer for CommandBuffer { caps: image::ViewCapabilities::empty(), view_kind: image::ViewKind::D2Array, format: attachment.dxgi_format, - component_mapping: IDENTITY_MAPPING, + component_mapping: device::IDENTITY_MAPPING, range: image::SubresourceRange { aspects: if depth.is_some() { Aspects::DEPTH @@ -1650,17 +1648,17 @@ impl com::CommandBuffer for CommandBuffer { // Descriptor heap for the current blit, only storing the src image let (srv_heap, _) = device.create_descriptor_heap( 1, - descriptor::HeapType::CbvSrvUav, - descriptor::HeapFlags::SHADER_VISIBLE, + native::DescriptorHeapType::CbvSrvUav, + native::DescriptorHeapFlags::SHADER_VISIBLE, 0, ); - let srv_desc = Device::build_image_as_shader_resource_desc(&ViewInfo { + let srv_desc = Device::build_image_as_shader_resource_desc(&device::ViewInfo { resource: src.resource, kind: src.kind, caps: src.view_caps, view_kind: image::ViewKind::D2Array, // TODO format: src.default_view_format.unwrap(), - component_mapping: IDENTITY_MAPPING, + component_mapping: device::IDENTITY_MAPPING, range: image::SubresourceRange { aspects: format::Aspects::COLOR, // TODO levels: 0 .. src.descriptor.MipLevels as _, @@ -1698,7 +1696,7 @@ impl com::CommandBuffer for CommandBuffer { // WORKAROUND: renderdoc crashes if we destroy the pool too early let rtv_pool = Device::create_descriptor_heap_impl( device, - descriptor::HeapType::Rtv, + native::DescriptorHeapType::Rtv, false, num_layers as _, ); @@ -2526,7 +2524,7 @@ impl com::CommandBuffer for CommandBuffer { unsafe fn begin_query(&mut self, query: query::Query, flags: query::ControlFlags) { let query_ty = match query.pool.ty { - native::query::HeapType::Occlusion => { + native::QueryHeapType::Occlusion => { if flags.contains(query::ControlFlags::PRECISE) { self.occlusion_query = Some(OcclusionQuery::Precise(query.id)); d3d12::D3D12_QUERY_TYPE_OCCLUSION @@ -2537,8 +2535,8 @@ impl com::CommandBuffer for CommandBuffer { d3d12::D3D12_QUERY_TYPE_BINARY_OCCLUSION } } - native::query::HeapType::Timestamp => panic!("Timestap queries are issued via "), - native::query::HeapType::PipelineStatistics => { + native::QueryHeapType::Timestamp => panic!("Timestap queries are issued via "), + native::QueryHeapType::PipelineStatistics => { self.pipeline_stats_query = Some(query.id); d3d12::D3D12_QUERY_TYPE_PIPELINE_STATISTICS } @@ -2552,19 +2550,19 @@ impl com::CommandBuffer for CommandBuffer { unsafe fn end_query(&mut self, query: query::Query) { let id = query.id; let query_ty = match query.pool.ty { - native::query::HeapType::Occlusion + native::QueryHeapType::Occlusion if self.occlusion_query == Some(OcclusionQuery::Precise(id)) => { self.occlusion_query = None; d3d12::D3D12_QUERY_TYPE_OCCLUSION } - native::query::HeapType::Occlusion + native::QueryHeapType::Occlusion if self.occlusion_query == Some(OcclusionQuery::Binary(id)) => { self.occlusion_query = None; d3d12::D3D12_QUERY_TYPE_BINARY_OCCLUSION } - native::query::HeapType::PipelineStatistics + native::QueryHeapType::PipelineStatistics if self.pipeline_stats_query == Some(id) => { self.pipeline_stats_query = None; diff --git a/src/backend/dx12/src/conv.rs b/src/backend/dx12/src/conv.rs index b4e621f05a0..879d6633b7a 100644 --- a/src/backend/dx12/src/conv.rs +++ b/src/backend/dx12/src/conv.rs @@ -19,7 +19,7 @@ use hal::{ pso, }; -use native::descriptor::ShaderVisibility; +use native::ShaderVisibility; pub fn map_format(format: Format) -> Option { use hal::format::Format::*; diff --git a/src/backend/dx12/src/descriptors_cpu.rs b/src/backend/dx12/src/descriptors_cpu.rs index 3c691514266..93cdf6f346d 100644 --- a/src/backend/dx12/src/descriptors_cpu.rs +++ b/src/backend/dx12/src/descriptors_cpu.rs @@ -1,4 +1,4 @@ -use native::descriptor::{CpuDescriptor, HeapFlags, HeapType}; +use native::{CpuDescriptor, DescriptorHeapFlags, DescriptorHeapType}; use std::{collections::HashSet, fmt}; // Linear stack allocator for CPU descriptor heaps. @@ -17,8 +17,8 @@ impl fmt::Debug for HeapLinear { } impl HeapLinear { - pub fn new(device: native::Device, ty: HeapType, size: usize) -> Self { - let (heap, _hr) = device.create_descriptor_heap(size as _, ty, HeapFlags::empty(), 0); + pub fn new(device: native::Device, ty: DescriptorHeapType, size: usize) -> Self { + let (heap, _hr) = device.create_descriptor_heap(size as _, ty, DescriptorHeapFlags::empty(), 0); HeapLinear { handle_size: device.get_descriptor_increment_size(ty) as _, @@ -74,9 +74,9 @@ impl fmt::Debug for Heap { } impl Heap { - pub fn new(device: native::Device, ty: HeapType) -> Self { + pub fn new(device: native::Device, ty: DescriptorHeapType) -> Self { let (heap, _hr) = - device.create_descriptor_heap(HEAP_SIZE_FIXED as _, ty, HeapFlags::empty(), 0); + device.create_descriptor_heap(HEAP_SIZE_FIXED as _, ty, DescriptorHeapFlags::empty(), 0); Heap { handle_size: device.get_descriptor_increment_size(ty) as _, @@ -109,7 +109,7 @@ impl Heap { pub struct DescriptorCpuPool { device: native::Device, - ty: HeapType, + ty: DescriptorHeapType, heaps: Vec, free_list: HashSet, } @@ -121,7 +121,7 @@ impl fmt::Debug for DescriptorCpuPool { } impl DescriptorCpuPool { - pub fn new(device: native::Device, ty: HeapType) -> Self { + pub fn new(device: native::Device, ty: DescriptorHeapType) -> Self { DescriptorCpuPool { device, ty, diff --git a/src/backend/dx12/src/device.rs b/src/backend/dx12/src/device.rs index b78cce5df66..48c00bfe56e 100644 --- a/src/backend/dx12/src/device.rs +++ b/src/backend/dx12/src/device.rs @@ -50,7 +50,6 @@ use hal::{ use crate::{ command as cmd, conv, - descriptor, descriptors_cpu, pool::{CommandPool, CommandPoolAllocator}, resource as r, @@ -65,8 +64,8 @@ use crate::{ QUEUE_FAMILIES, }; use native::{ - command_list::IndirectArgument, - pso::{CachedPSO, PipelineStateFlags, PipelineStateSubobject, Subobject}, + PipelineStateSubobject, + Subobject, }; // Register space used for root constants. @@ -490,9 +489,9 @@ impl Device { ty: CommandSignature, ) -> native::CommandSignature { let (arg, stride) = match ty { - CommandSignature::Draw => (IndirectArgument::draw(), 16), - CommandSignature::DrawIndexed => (IndirectArgument::draw_indexed(), 20), - CommandSignature::Dispatch => (IndirectArgument::dispatch(), 12), + CommandSignature::Draw => (native::IndirectArgument::draw(), 16), + CommandSignature::DrawIndexed => (native::IndirectArgument::draw_indexed(), 20), + CommandSignature::Dispatch => (native::IndirectArgument::dispatch(), 12), }; let (signature, hr) = @@ -506,7 +505,7 @@ impl Device { pub(crate) fn create_descriptor_heap_impl( device: native::Device, - heap_type: descriptor::HeapType, + heap_type: native::DescriptorHeapType, shader_visible: bool, capacity: usize, ) -> r::DescriptorHeap { @@ -516,9 +515,9 @@ impl Device { capacity as _, heap_type, if shader_visible { - descriptor::HeapFlags::SHADER_VISIBLE + native::DescriptorHeapFlags::SHADER_VISIBLE } else { - descriptor::HeapFlags::empty() + native::DescriptorHeapFlags::empty() }, 0, ); @@ -1050,7 +1049,7 @@ impl Device { }; let rtv_heap = Device::create_descriptor_heap_impl( self.raw, - descriptor::HeapType::Rtv, + native::DescriptorHeapType::Rtv, false, config.image_count as _, ); @@ -1531,9 +1530,9 @@ impl d::Device for Device { "\tRoot constant set={} range {:?}", ROOT_CONSTANT_SPACE, root_constant.range ); - parameters.push(descriptor::RootParameter::constants( + parameters.push(native::RootParameter::constants( conv::map_shader_visibility(root_constant.stages), - descriptor::Binding { + native::Binding { register: root_constant.range.start as _, space: ROOT_CONSTANT_SPACE, }, @@ -1587,10 +1586,10 @@ impl d::Device for Device { } let describe = |bind: &pso::DescriptorSetLayoutBinding, ty| { - descriptor::DescriptorRange::new( + native::DescriptorRange::new( ty, bind.count as _, - descriptor::Binding { + native::Binding { register: bind.binding as _, space, }, @@ -1605,7 +1604,7 @@ impl d::Device for Device { if content.is_dynamic() { // Root Descriptor - let binding = descriptor::Binding { + let binding = native::Binding { register: bind.binding as _, space, }; @@ -1614,7 +1613,7 @@ impl d::Device for Device { descriptors.push(r::RootDescriptor { offset: root_offset, }); - parameters.push(descriptor::RootParameter::cbv_descriptor( + parameters.push(native::RootParameter::cbv_descriptor( visibility, binding, )); root_offset += 2; @@ -1625,18 +1624,18 @@ impl d::Device for Device { } else { // Descriptor table ranges if content.contains(r::DescriptorContent::CBV) { - ranges.push(describe(bind, descriptor::DescriptorRangeType::CBV)); + ranges.push(describe(bind, native::DescriptorRangeType::CBV)); } if content.contains(r::DescriptorContent::SRV) { - ranges.push(describe(bind, descriptor::DescriptorRangeType::SRV)); + ranges.push(describe(bind, native::DescriptorRangeType::SRV)); } if content.contains(r::DescriptorContent::UAV) { - ranges.push(describe(bind, descriptor::DescriptorRangeType::UAV)); + ranges.push(describe(bind, native::DescriptorRangeType::UAV)); } } } if ranges.len() > range_base { - parameters.push(descriptor::RootParameter::descriptor_table( + parameters.push(native::RootParameter::descriptor_table( visibility, &ranges[range_base ..], )); @@ -1648,11 +1647,11 @@ impl d::Device for Device { for bind in set.bindings.iter() { let content = r::DescriptorContent::from(bind.ty); if content.contains(r::DescriptorContent::SAMPLER) { - ranges.push(describe(bind, descriptor::DescriptorRangeType::Sampler)); + ranges.push(describe(bind, native::DescriptorRangeType::Sampler)); } } if ranges.len() > range_base { - parameters.push(descriptor::RootParameter::descriptor_table( + parameters.push(native::RootParameter::descriptor_table( visibility, &ranges[range_base ..], )); @@ -1674,12 +1673,16 @@ impl d::Device for Device { debug_assert_eq!(ranges.len(), total); // TODO: error handling - let ((signature_raw, error), _hr) = native::RootSignature::serialize( - descriptor::RootSignatureVersion::V1_0, + let (signature_raw, error) = match self.library.serialize_root_signature( + native::RootSignatureVersion::V1_0, ¶meters, &[], - descriptor::RootSignatureFlags::ALLOW_IA_INPUT_LAYOUT, - ); + native::RootSignatureFlags::ALLOW_IA_INPUT_LAYOUT, + ) { + Ok((pair, hr)) if winerror::SUCCEEDED(hr) => pair, + Ok((_, hr)) => panic!("Can't serialize root signature: {:?}", hr), + Err(e) => panic!("Can't find serialization function: {:?}", e), + }; if !error.is_null() { error!( @@ -2017,8 +2020,8 @@ impl d::Device for Device { desc.layout.raw, native::Shader::from_blob(cs), 0, - CachedPSO::null(), - PipelineStateFlags::empty(), + native::CachedPSO::null(), + native::PipelineStateFlags::empty(), ); if cs_destroy { @@ -2835,7 +2838,7 @@ impl d::Device for Device { let max_size = 1u64 << 12; //arbitrary descriptor_update_pools.push(descriptors_cpu::HeapLinear::new( self.raw, - descriptor::HeapType::CbvSrvUav, + native::DescriptorHeapType::CbvSrvUav, max_size as _, )); } @@ -2901,7 +2904,7 @@ impl d::Device for Device { let max_size = 1u64 << 12; //arbitrary descriptor_update_pools.push(descriptors_cpu::HeapLinear::new( self.raw, - descriptor::HeapType::CbvSrvUav, + native::DescriptorHeapType::CbvSrvUav, max_size as _, )); heap = descriptor_update_pools.last_mut().unwrap(); @@ -3309,9 +3312,9 @@ impl d::Device for Device { count: query::Id, ) -> Result { let heap_ty = match query_ty { - query::Type::Occlusion => native::query::HeapType::Occlusion, - query::Type::PipelineStatistics(_) => native::query::HeapType::PipelineStatistics, - query::Type::Timestamp => native::query::HeapType::Timestamp, + query::Type::Occlusion => native::QueryHeapType::Occlusion, + query::Type::PipelineStatistics(_) => native::QueryHeapType::PipelineStatistics, + query::Type::Timestamp => native::QueryHeapType::Timestamp, }; let (query_heap, hr) = self.raw.create_query_heap(heap_ty, count, 0); diff --git a/src/backend/dx12/src/internal.rs b/src/backend/dx12/src/internal.rs index d1e3ee4fe20..976b00934be 100644 --- a/src/backend/dx12/src/internal.rs +++ b/src/backend/dx12/src/internal.rs @@ -1,5 +1,5 @@ use auxil::FastHashMap; -use std::{ffi::CStr, mem, ptr, sync::Mutex}; +use std::{ffi::CStr, mem, ptr, sync::{Arc, Mutex}}; use winapi::{ shared::{ @@ -12,7 +12,7 @@ use winapi::{ Interface, }; -use native::{descriptor, pso}; +use native; #[derive(Clone, Debug)] pub struct BlitPipe { @@ -43,13 +43,15 @@ type BlitMap = FastHashMap; #[derive(Debug)] pub(crate) struct ServicePipes { pub(crate) device: native::Device, + library: Arc, blits_2d_color: Mutex, } impl ServicePipes { - pub fn new(device: native::Device) -> Self { + pub fn new(device: native::Device, library: Arc) -> Self { ServicePipes { device, + library, blits_2d_color: Mutex::new(FastHashMap::default()), } } @@ -70,10 +72,10 @@ impl ServicePipes { } fn create_blit_2d_color(&self, (dst_format, filter): BlitKey) -> BlitPipe { - let descriptor_range = [descriptor::DescriptorRange::new( - descriptor::DescriptorRangeType::SRV, + let descriptor_range = [native::DescriptorRange::new( + native::DescriptorRangeType::SRV, 1, - native::descriptor::Binding { + native::Binding { register: 0, space: 0, }, @@ -81,13 +83,13 @@ impl ServicePipes { )]; let root_parameters = [ - descriptor::RootParameter::descriptor_table( - descriptor::ShaderVisibility::All, + native::RootParameter::descriptor_table( + native::ShaderVisibility::All, &descriptor_range, ), - descriptor::RootParameter::constants( - descriptor::ShaderVisibility::All, - native::descriptor::Binding { + native::RootParameter::constants( + native::ShaderVisibility::All, + native::Binding { register: 0, space: 0, }, @@ -95,9 +97,9 @@ impl ServicePipes { ), ]; - let static_samplers = [descriptor::StaticSampler::new( - descriptor::ShaderVisibility::PS, - native::descriptor::Binding { + let static_samplers = [native::StaticSampler::new( + native::ShaderVisibility::PS, + native::Binding { register: 0, space: 0, }, @@ -110,16 +112,20 @@ impl ServicePipes { 0.0, 0, d3d12::D3D12_COMPARISON_FUNC_ALWAYS, - descriptor::StaticBorderColor::TransparentBlack, + native::StaticBorderColor::TransparentBlack, 0.0 .. d3d12::D3D12_FLOAT32_MAX, )]; - let ((signature_raw, error), _hr) = native::RootSignature::serialize( - descriptor::RootSignatureVersion::V1_0, + let (signature_raw, error) = match self.library.serialize_root_signature( + native::RootSignatureVersion::V1_0, &root_parameters, &static_samplers, - descriptor::RootSignatureFlags::empty(), - ); + native::RootSignatureFlags::empty(), + ) { + Ok((pair, hr)) if winerror::SUCCEEDED(hr) => pair, + Ok((_, hr)) => panic!("Can't serialize internal root signature: {:?}", hr), + Err(e) => panic!("Can't find serialization function: {:?}", e), + }; if !error.is_null() { error!("D3D12SerializeRootSignature error: {:?}", unsafe { @@ -129,21 +135,21 @@ impl ServicePipes { } let (signature, _hr) = self.device.create_root_signature(signature_raw, 0); - unsafe { signature_raw.destroy() }; + unsafe { signature_raw.destroy(); } let shader_src = include_bytes!("../shaders/blit.hlsl"); // TODO: check results - let ((vs, _), _hr_vs) = pso::Shader::compile( + let ((vs, _), _hr_vs) = native::Shader::compile( shader_src, unsafe { CStr::from_bytes_with_nul_unchecked(b"vs_5_0\0") }, unsafe { CStr::from_bytes_with_nul_unchecked(b"vs_blit_2d\0") }, - pso::ShaderCompileFlags::empty(), + native::ShaderCompileFlags::empty(), ); - let ((ps, _), _hr_ps) = pso::Shader::compile( + let ((ps, _), _hr_ps) = native::Shader::compile( shader_src, unsafe { CStr::from_bytes_with_nul_unchecked(b"ps_5_0\0") }, unsafe { CStr::from_bytes_with_nul_unchecked(b"ps_blit_2d\0") }, - pso::ShaderCompileFlags::empty(), + native::ShaderCompileFlags::empty(), ); let mut rtvs = [dxgiformat::DXGI_FORMAT_UNKNOWN; 8]; @@ -165,11 +171,11 @@ impl ServicePipes { let pso_desc = d3d12::D3D12_GRAPHICS_PIPELINE_STATE_DESC { pRootSignature: signature.as_mut_ptr(), - VS: *pso::Shader::from_blob(vs), - PS: *pso::Shader::from_blob(ps), - GS: *pso::Shader::null(), - DS: *pso::Shader::null(), - HS: *pso::Shader::null(), + VS: *native::Shader::from_blob(vs), + PS: *native::Shader::from_blob(ps), + GS: *native::Shader::null(), + DS: *native::Shader::null(), + HS: *native::Shader::null(), StreamOutput: d3d12::D3D12_STREAM_OUTPUT_DESC { pSODeclaration: ptr::null(), NumEntries: 0, diff --git a/src/backend/dx12/src/lib.rs b/src/backend/dx12/src/lib.rs index 3d20f4ee353..83ac7325d64 100644 --- a/src/backend/dx12/src/lib.rs +++ b/src/backend/dx12/src/lib.rs @@ -16,8 +16,8 @@ mod window; use hal::{adapter, format as f, image, memory, pso::PipelineStage, queue as q, Features, Limits}; use winapi::{ - shared::{dxgi, dxgi1_2, dxgi1_3, dxgi1_4, dxgi1_6, minwindef::TRUE, winerror}, - um::{d3d12, d3d12sdklayers, dxgidebug, handleapi, synchapi, winbase}, + shared::{dxgi, dxgi1_2, dxgi1_4, dxgi1_6, minwindef::TRUE, winerror}, + um::{d3d12, d3d12sdklayers, handleapi, synchapi, winbase}, Interface, }; @@ -27,12 +27,10 @@ use std::{ fmt, mem, os::windows::ffi::OsStringExt, - ptr, sync::{Arc, Mutex}, }; use self::descriptors_cpu::DescriptorCpuPool; -use native::descriptor; #[derive(Debug)] pub(crate) struct HeapProperties { @@ -151,15 +149,15 @@ impl q::QueueFamily for QueueFamily { } impl QueueFamily { - fn native_type(&self) -> native::command_list::CmdListType { + fn native_type(&self) -> native::CmdListType { use hal::queue::QueueFamily as _; - use native::command_list::CmdListType; + use native::CmdListType as Clt; let queue_type = self.queue_type(); match queue_type { - q::QueueType::General | q::QueueType::Graphics => CmdListType::Direct, - q::QueueType::Compute => CmdListType::Compute, - q::QueueType::Transfer => CmdListType::Copy, + q::QueueType::General | q::QueueType::Graphics => Clt::Direct, + q::QueueType::Compute => Clt::Compute, + q::QueueType::Transfer => Clt::Copy, } } } @@ -172,6 +170,7 @@ static QUEUE_FAMILIES: [QueueFamily; 4] = [ ]; pub struct PhysicalDevice { + library: Arc, adapter: native::WeakPtr, features: Features, limits: Limits, @@ -209,17 +208,23 @@ impl adapter::PhysicalDevice for PhysicalDevice { return Err(hal::device::CreationError::MissingFeature); } - let (device_raw, hr_device) = - native::Device::create(self.adapter, native::FeatureLevel::L11_0); - if !winerror::SUCCEEDED(hr_device) { - error!("error on device creation: {:x}", hr_device); - } + let device_raw = match self.library.create_device( + self.adapter, + native::FeatureLevel::L11_0, + ) { + Ok((device, hr)) if winerror::SUCCEEDED(hr) => device, + Ok((_, hr)) => { + error!("error on device creation: {:x}", hr); + return Err(hal::device::CreationError::InitializationFailed); + } + Err(e) => panic!("device creation failed with {:?}", e), + }; // Always create the presentation queue in case we want to build a swapchain. let (present_queue, hr_queue) = device_raw.create_command_queue( QueueFamily::Present.native_type(), - native::queue::Priority::Normal, - native::queue::CommandQueueFlags::empty(), + native::Priority::Normal, + native::CommandQueueFlags::empty(), 0, ); if !winerror::SUCCEEDED(hr_queue) { @@ -254,8 +259,8 @@ impl adapter::PhysicalDevice for PhysicalDevice { for _ in 0 .. priorities.len() { let (queue, hr_queue) = device_raw.create_command_queue( list_type, - native::queue::Priority::Normal, - native::queue::CommandQueueFlags::empty(), + native::Priority::Normal, + native::CommandQueueFlags::empty(), 0, ); @@ -405,7 +410,7 @@ impl adapter::PhysicalDevice for PhysicalDevice { pub struct CommandQueue { pub(crate) raw: native::CommandQueue, idle_fence: native::Fence, - idle_event: native::sync::Event, + idle_event: native::Event, } impl fmt::Debug for CommandQueue { @@ -544,6 +549,7 @@ impl Shared { pub struct Device { raw: native::Device, + library: Arc, private_caps: Capabilities, format_properties: Arc, heap_properties: &'static [HeapProperties], @@ -584,20 +590,20 @@ impl Device { present_queue: native::CommandQueue, ) -> Self { // Allocate descriptor heaps - let rtv_pool = DescriptorCpuPool::new(device, descriptor::HeapType::Rtv); - let dsv_pool = DescriptorCpuPool::new(device, descriptor::HeapType::Dsv); - let srv_uav_pool = DescriptorCpuPool::new(device, descriptor::HeapType::CbvSrvUav); - let sampler_pool = DescriptorCpuPool::new(device, descriptor::HeapType::Sampler); + let rtv_pool = DescriptorCpuPool::new(device, native::DescriptorHeapType::Rtv); + let dsv_pool = DescriptorCpuPool::new(device, native::DescriptorHeapType::Dsv); + let srv_uav_pool = DescriptorCpuPool::new(device, native::DescriptorHeapType::CbvSrvUav); + let sampler_pool = DescriptorCpuPool::new(device, native::DescriptorHeapType::Sampler); let heap_srv_cbv_uav = Self::create_descriptor_heap_impl( device, - descriptor::HeapType::CbvSrvUav, + native::DescriptorHeapType::CbvSrvUav, true, 1_000_000, // maximum number of CBV/SRV/UAV descriptors in heap for Tier 1 ); let heap_sampler = - Self::create_descriptor_heap_impl(device, descriptor::HeapType::Sampler, true, 2_048); + Self::create_descriptor_heap_impl(device, native::DescriptorHeapType::Sampler, true, 2_048); let draw_signature = Self::create_command_signature(device, device::CommandSignature::Draw); let draw_indexed_signature = @@ -610,7 +616,10 @@ impl Device { draw_indexed: draw_indexed_signature, dispatch: dispatch_signature, }; - let service_pipes = internal::ServicePipes::new(device); + let service_pipes = internal::ServicePipes::new( + device, + Arc::clone(&physical_device.library), + ); let shared = Shared { signatures, service_pipes, @@ -618,6 +627,7 @@ impl Device { Device { raw: device, + library: Arc::clone(&physical_device.library), private_caps: physical_device.private_caps, format_properties: physical_device.format_properties.clone(), heap_properties: physical_device.heap_properties, @@ -683,7 +693,8 @@ impl Drop for Device { #[derive(Debug)] pub struct Instance { - pub(crate) factory: native::WeakPtr, + pub(crate) factory: native::Factory4, + library: Arc, } impl Drop for Instance { @@ -699,65 +710,52 @@ unsafe impl Sync for Instance {} impl hal::Instance for Instance { fn create(_: &str, _: u32) -> Result { + let lib_main = match native::D3D12Lib::new() { + Ok(lib) => lib, + Err(_) => return Err(hal::UnsupportedBackend), + }; + #[cfg(debug_assertions)] { // Enable debug layer - let mut debug_controller: *mut d3d12sdklayers::ID3D12Debug = ptr::null_mut(); - let hr = unsafe { - d3d12::D3D12GetDebugInterface( - &d3d12sdklayers::ID3D12Debug::uuidof(), - &mut debug_controller as *mut *mut _ as *mut *mut _, - ) - }; - - if winerror::SUCCEEDED(hr) { - unsafe { - (*debug_controller).EnableDebugLayer(); - (*debug_controller).Release(); + match lib_main.get_debug_interface() { + Ok((debug_controller, hr)) if winerror::SUCCEEDED(hr) => { + debug_controller.enable_layer(); + unsafe { debug_controller.Release(); } + } + _ => { + warn!("Unable to get D3D12 debug interface"); } } } + let lib_dxgi = native::DxgiLib::new().unwrap(); + // The `DXGI_CREATE_FACTORY_DEBUG` flag is only allowed to be passed to // `CreateDXGIFactory2` if the debug interface is actually available. So // we check for whether it exists first. - let mut queue = native::WeakPtr::::null(); - let hr = unsafe { - dxgi1_3::DXGIGetDebugInterface1( - 0, - &dxgidebug::IDXGIInfoQueue::uuidof(), - queue.mut_void(), - ) - }; - - let factory_flags = if winerror::SUCCEEDED(hr) { - unsafe { - queue.destroy(); + let factory_flags = match lib_dxgi.get_debug_interface1() { + Ok((queue, hr)) if winerror::SUCCEEDED(hr) => { + unsafe { queue.destroy() }; + native::FactoryCreationFlags::DEBUG } - dxgi1_3::DXGI_CREATE_FACTORY_DEBUG - } else { - 0 + _ => native::FactoryCreationFlags::empty(), }; // Create DXGI factory - let mut dxgi_factory = native::WeakPtr::::null(); - - let hr = unsafe { - dxgi1_3::CreateDXGIFactory2( - factory_flags, - &dxgi1_4::IDXGIFactory4::uuidof(), - dxgi_factory.mut_void(), - ) + let factory = match lib_dxgi.create_factory2(factory_flags) { + Ok((factory, hr)) if winerror::SUCCEEDED(hr) => factory, + Ok((_, hr)) => { + info!("Failed on dxgi factory creation: {:?}", hr); + return Err(hal::UnsupportedBackend) + } + Err(_) => return Err(hal::UnsupportedBackend), }; - if winerror::SUCCEEDED(hr) { - Ok(Instance { - factory: dxgi_factory, - }) - } else { - info!("Failed on dxgi factory creation: {:?}", hr); - Err(hal::UnsupportedBackend) - } + Ok(Instance { + factory, + library: Arc::new(lib_main), + }) } fn enumerate_adapters(&self) -> Vec> { @@ -823,12 +821,9 @@ impl hal::Instance for Instance { // Check for D3D12 support // Create temporary device to get physical device information - let device = { - let (device, hr) = native::Device::create(adapter, native::FeatureLevel::L11_0); - if !winerror::SUCCEEDED(hr) { - continue; - } - device + let device = match self.library.create_device(adapter, native::FeatureLevel::L11_0) { + Ok((device, hr)) if winerror::SUCCEEDED(hr) => device, + _ => continue, }; // We have found a possible adapter @@ -1046,6 +1041,7 @@ impl hal::Instance for Instance { let sample_count_mask = 0x3F; let physical_device = PhysicalDevice { + library: Arc::clone(&self.library), adapter, features: // TODO: add more features, based on diff --git a/src/backend/dx12/src/pool.rs b/src/backend/dx12/src/pool.rs index 26e86db992b..dd2beec7683 100644 --- a/src/backend/dx12/src/pool.rs +++ b/src/backend/dx12/src/pool.rs @@ -4,7 +4,6 @@ use winapi::shared::winerror::SUCCEEDED; use crate::{command::CommandBuffer, Backend, Shared}; use hal::{command, pool}; -use native::command_list::CmdListType; #[derive(Debug)] pub enum CommandPoolAllocator { @@ -15,7 +14,7 @@ pub enum CommandPoolAllocator { pub struct CommandPool { pub(crate) allocator: CommandPoolAllocator, pub(crate) device: native::Device, - pub(crate) list_type: CmdListType, + pub(crate) list_type: native::CmdListType, pub(crate) shared: Arc, pub(crate) create_flags: pool::CommandPoolCreateFlags, } diff --git a/src/backend/dx12/src/resource.rs b/src/backend/dx12/src/resource.rs index 6fea4368b85..f2b94bb384e 100644 --- a/src/backend/dx12/src/resource.rs +++ b/src/backend/dx12/src/resource.rs @@ -4,7 +4,6 @@ use winapi::{ }; use hal::{buffer, format, image, memory, pass, pso}; -use native::{self, query}; use range_alloc::RangeAllocator; use crate::{root_constants::RootConstant, Backend, MAX_VERTEX_BUFFERS}; @@ -752,7 +751,7 @@ impl pso::DescriptorPool for DescriptorPool { #[derive(Debug)] pub struct QueryPool { pub(crate) raw: native::QueryHeap, - pub(crate) ty: query::HeapType, + pub(crate) ty: native::QueryHeapType, } unsafe impl Send for QueryPool {}