From 855689462c2c8c686102e51b1e7a96605e4b02f2 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Tue, 6 Jul 2021 22:32:57 -0400 Subject: [PATCH] hal/dx12: fences --- wgpu-hal/src/dx12/command.rs | 10 +++--- wgpu-hal/src/dx12/device.rs | 69 +++++++++++++++++++++++++----------- wgpu-hal/src/dx12/mod.rs | 25 ++++++++++--- 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index 76b2145c3..ef4e175cd 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -60,13 +60,13 @@ impl crate::CommandEncoder for super::CommandEncoder { ) { } - unsafe fn begin_query(&mut self, set: &Resource, index: u32) {} - unsafe fn end_query(&mut self, set: &Resource, index: u32) {} - unsafe fn write_timestamp(&mut self, set: &Resource, index: u32) {} - unsafe fn reset_queries(&mut self, set: &Resource, range: Range) {} + unsafe fn begin_query(&mut self, set: &super::QuerySet, index: u32) {} + unsafe fn end_query(&mut self, set: &super::QuerySet, index: u32) {} + unsafe fn write_timestamp(&mut self, set: &super::QuerySet, index: u32) {} + unsafe fn reset_queries(&mut self, set: &super::QuerySet, range: Range) {} unsafe fn copy_query_results( &mut self, - set: &Resource, + set: &super::QuerySet, range: Range, buffer: &super::Buffer, offset: wgt::BufferAddress, diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs index 3b9e497ed..7c5aeccb3 100644 --- a/wgpu-hal/src/dx12/device.rs +++ b/wgpu-hal/src/dx12/device.rs @@ -2,7 +2,7 @@ use super::{conv, descriptor, HResult as _}; use parking_lot::Mutex; use std::{iter, mem, ptr}; use winapi::{ - shared::{dxgiformat, dxgitype}, + shared::{dxgiformat, dxgitype, winerror}, um::{d3d12, d3d12sdklayers, synchapi, winbase}, Interface, }; @@ -10,8 +10,6 @@ use winapi::{ //TODO: remove this use super::Resource; -type DeviceResult = Result; - const D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING: u32 = 0x1688; fn wide_cstr(name: &str) -> Vec { @@ -649,10 +647,13 @@ impl crate::Device for super::Device { } } - unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult { - Ok(Resource) + unsafe fn create_sampler( + &self, + desc: &crate::SamplerDescriptor, + ) -> Result { + Ok(super::Sampler {}) } - unsafe fn destroy_sampler(&self, sampler: Resource) {} + unsafe fn destroy_sampler(&self, sampler: super::Sampler) {} unsafe fn create_command_encoder( &self, @@ -665,21 +666,21 @@ impl crate::Device for super::Device { unsafe fn create_bind_group_layout( &self, desc: &crate::BindGroupLayoutDescriptor, - ) -> DeviceResult { + ) -> Result { Ok(Resource) } unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} unsafe fn create_pipeline_layout( &self, desc: &crate::PipelineLayoutDescriptor, - ) -> DeviceResult { + ) -> Result { Ok(Resource) } unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} unsafe fn create_bind_group( &self, desc: &crate::BindGroupDescriptor, - ) -> DeviceResult { + ) -> Result { Ok(Resource) } unsafe fn destroy_bind_group(&self, group: Resource) {} @@ -710,24 +711,52 @@ impl crate::Device for super::Device { unsafe fn create_query_set( &self, desc: &wgt::QuerySetDescriptor, - ) -> DeviceResult { - Ok(Resource) + ) -> Result { + Ok(super::QuerySet {}) } - unsafe fn destroy_query_set(&self, set: Resource) {} - unsafe fn create_fence(&self) -> DeviceResult { - Ok(Resource) + unsafe fn destroy_query_set(&self, set: super::QuerySet) {} + + unsafe fn create_fence(&self) -> Result { + let mut raw = native::Fence::null(); + let hr = self.raw.CreateFence( + 0, + d3d12::D3D12_FENCE_FLAG_NONE, + &d3d12::ID3D12Fence::uuidof(), + raw.mut_void(), + ); + hr.to_device_result("Fence creation")?; + Ok(super::Fence { raw }) } - unsafe fn destroy_fence(&self, fence: Resource) {} - unsafe fn get_fence_value(&self, fence: &Resource) -> DeviceResult { - Ok(0) + unsafe fn destroy_fence(&self, fence: super::Fence) { + fence.raw.destroy(); + } + unsafe fn get_fence_value( + &self, + fence: &super::Fence, + ) -> Result { + Ok(fence.raw.GetCompletedValue()) } unsafe fn wait( &self, - fence: &Resource, + fence: &super::Fence, value: crate::FenceValue, timeout_ms: u32, - ) -> DeviceResult { - Ok(true) + ) -> Result { + if fence.raw.GetCompletedValue() >= value { + return Ok(true); + } + let hr = fence.raw.set_event_on_completion(self.idler.event, value); + hr.to_device_result("Set event")?; + + match synchapi::WaitForSingleObject(self.idler.event.0, timeout_ms) { + winbase::WAIT_ABANDONED | winbase::WAIT_FAILED => Err(crate::DeviceError::Lost), + winbase::WAIT_OBJECT_0 => Ok(true), + winerror::WAIT_TIMEOUT => Ok(false), + other => { + log::error!("Unexpected wait status: 0x{:x}", other); + Err(crate::DeviceError::Lost) + } + } } unsafe fn start_capture(&self) -> bool { diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index dc978a6a1..8b4fa8157 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -41,9 +41,9 @@ impl crate::Api for Api { type Texture = Texture; type SurfaceTexture = Texture; type TextureView = TextureView; - type Sampler = Resource; - type QuerySet = Resource; - type Fence = Resource; + type Sampler = Sampler; + type QuerySet = QuerySet; + type Fence = Fence; type BindGroupLayout = Resource; type BindGroup = Resource; @@ -216,6 +216,23 @@ pub struct TextureView { unsafe impl Send for TextureView {} unsafe impl Sync for TextureView {} +#[derive(Debug)] +pub struct Sampler {} + +unsafe impl Send for Sampler {} +unsafe impl Sync for Sampler {} + +#[derive(Debug)] +pub struct QuerySet {} + +#[derive(Debug)] +pub struct Fence { + raw: native::Fence, +} + +unsafe impl Send for Fence {} +unsafe impl Sync for Fence {} + impl crate::Instance for Instance { unsafe fn init(desc: &crate::InstanceDescriptor) -> Result { let lib_main = native::D3D12Lib::new().map_err(|_| crate::InstanceError)?; @@ -525,7 +542,7 @@ impl crate::Queue for Queue { unsafe fn submit( &mut self, command_buffers: &[&Resource], - signal_fence: Option<(&mut Resource, crate::FenceValue)>, + signal_fence: Option<(&mut Fence, crate::FenceValue)>, ) -> Result<(), crate::DeviceError> { Ok(()) }