From eb565a59f70bc117063a9a72f5762637dc87dc48 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Mon, 5 Jul 2021 12:42:11 -0400 Subject: [PATCH] hal/dx12: move device and encoder into modules --- wgpu-hal/src/dx12/adapter.rs | 66 +++++++- wgpu-hal/src/dx12/command.rs | 168 +++++++++++++++++++ wgpu-hal/src/dx12/device.rs | 121 ++++++++++++++ wgpu-hal/src/dx12/mod.rs | 304 ++--------------------------------- 4 files changed, 363 insertions(+), 296 deletions(-) create mode 100644 wgpu-hal/src/dx12/command.rs create mode 100644 wgpu-hal/src/dx12/device.rs diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index ff01aee89c..6527f58830 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -1,8 +1,8 @@ -use super::{conv, HResultPair as _}; +use super::{conv, HResult as _, HResultPair as _}; use std::{mem, sync::Arc}; use winapi::{ - shared::{dxgi, dxgi1_2, winerror}, - um::d3d12, + shared::{dxgi, dxgi1_2, dxgi1_5, minwindef, windef, winerror}, + um::{d3d12, winuser}, }; impl Drop for super::Adapter { @@ -314,6 +314,64 @@ impl crate::Adapter for super::Adapter { &self, surface: &super::Surface, ) -> Option { - None + let current_extent = { + let mut rect: windef::RECT = mem::zeroed(); + if winuser::GetClientRect(surface.wnd_handle, &mut rect) != 0 { + Some(wgt::Extent3d { + width: (rect.right - rect.left) as u32, + height: (rect.bottom - rect.top) as u32, + depth_or_array_layers: 1, + }) + } else { + log::warn!("Unable to get the window client rect"); + None + } + }; + + let mut present_modes = vec![wgt::PresentMode::Fifo]; + #[allow(trivial_casts)] + if let Ok(factory5) = surface.factory.cast::().check() { + let mut allow_tearing: minwindef::BOOL = minwindef::FALSE; + let hr = factory5.CheckFeatureSupport( + dxgi1_5::DXGI_FEATURE_PRESENT_ALLOW_TEARING, + &mut allow_tearing as *mut _ as *mut _, + mem::size_of::() as _, + ); + + factory5.destroy(); + match hr.to_error() { + Some(err) => log::warn!("Unable to check for tearing support: {}", err), + None => present_modes.push(wgt::PresentMode::Immediate), + } + } + + Some(crate::SurfaceCapabilities { + formats: vec![ + wgt::TextureFormat::Bgra8UnormSrgb, + wgt::TextureFormat::Bgra8Unorm, + wgt::TextureFormat::Rgba8UnormSrgb, + wgt::TextureFormat::Rgba8Unorm, + wgt::TextureFormat::Rgb10a2Unorm, + wgt::TextureFormat::Rgba16Float, + ], + // we currently use a flip effect which supports 2..=16 buffers + swap_chain_sizes: 2..=16, + current_extent, + // TODO: figure out the exact bounds + extents: wgt::Extent3d { + width: 16, + height: 16, + depth_or_array_layers: 1, + }..=wgt::Extent3d { + width: 4096, + height: 4096, + depth_or_array_layers: 1, + }, + usage: crate::TextureUses::COLOR_TARGET + | crate::TextureUses::COPY_SRC + | crate::TextureUses::COPY_DST, + present_modes, + composite_alpha_modes: vec![crate::CompositeAlphaMode::Opaque], + }) } } diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs new file mode 100644 index 0000000000..3ed82d4385 --- /dev/null +++ b/wgpu-hal/src/dx12/command.rs @@ -0,0 +1,168 @@ +use super::Resource; +use std::ops::Range; + +impl crate::CommandEncoder for super::Encoder { + unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> { + Ok(()) + } + unsafe fn discard_encoding(&mut self) {} + unsafe fn end_encoding(&mut self) -> Result { + Ok(Resource) + } + unsafe fn reset_all(&mut self, command_buffers: I) {} + + unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) + where + T: Iterator>, + { + } + + unsafe fn transition_textures<'a, T>(&mut self, barriers: T) + where + T: Iterator>, + { + } + + unsafe fn fill_buffer(&mut self, buffer: &Resource, range: crate::MemoryRange, value: u8) {} + + unsafe fn copy_buffer_to_buffer(&mut self, src: &Resource, dst: &Resource, regions: T) {} + + unsafe fn copy_texture_to_texture( + &mut self, + src: &Resource, + src_usage: crate::TextureUses, + dst: &Resource, + regions: T, + ) { + } + + unsafe fn copy_buffer_to_texture(&mut self, src: &Resource, dst: &Resource, regions: T) {} + + unsafe fn copy_texture_to_buffer( + &mut self, + src: &Resource, + src_usage: crate::TextureUses, + dst: &Resource, + regions: T, + ) { + } + + 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 copy_query_results( + &mut self, + set: &Resource, + range: Range, + buffer: &Resource, + offset: wgt::BufferAddress, + stride: wgt::BufferSize, + ) { + } + + // render + + unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) {} + unsafe fn end_render_pass(&mut self) {} + + unsafe fn set_bind_group( + &mut self, + layout: &Resource, + index: u32, + group: &Resource, + dynamic_offsets: &[wgt::DynamicOffset], + ) { + } + unsafe fn set_push_constants( + &mut self, + layout: &Resource, + stages: wgt::ShaderStages, + offset: u32, + data: &[u32], + ) { + } + + unsafe fn insert_debug_marker(&mut self, label: &str) {} + unsafe fn begin_debug_marker(&mut self, group_label: &str) {} + unsafe fn end_debug_marker(&mut self) {} + + unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {} + + unsafe fn set_index_buffer<'a>( + &mut self, + binding: crate::BufferBinding<'a, super::Api>, + format: wgt::IndexFormat, + ) { + } + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: crate::BufferBinding<'a, super::Api>, + ) { + } + unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: Range) {} + unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) {} + unsafe fn set_stencil_reference(&mut self, value: u32) {} + unsafe fn set_blend_constants(&mut self, color: &wgt::Color) {} + + unsafe fn draw( + &mut self, + start_vertex: u32, + vertex_count: u32, + start_instance: u32, + instance_count: u32, + ) { + } + unsafe fn draw_indexed( + &mut self, + start_index: u32, + index_count: u32, + base_vertex: i32, + start_instance: u32, + instance_count: u32, + ) { + } + unsafe fn draw_indirect( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + } + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + } + unsafe fn draw_indirect_count( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + count_buffer: &Resource, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + } + unsafe fn draw_indexed_indirect_count( + &mut self, + buffer: &Resource, + offset: wgt::BufferAddress, + count_buffer: &Resource, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + } + + // compute + + unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {} + unsafe fn end_compute_pass(&mut self) {} + + unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {} + + unsafe fn dispatch(&mut self, count: [u32; 3]) {} + unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} +} diff --git a/wgpu-hal/src/dx12/device.rs b/wgpu-hal/src/dx12/device.rs new file mode 100644 index 0000000000..73fbb885c5 --- /dev/null +++ b/wgpu-hal/src/dx12/device.rs @@ -0,0 +1,121 @@ +//TODO: remove this +use super::{Encoder, Resource}; +type DeviceResult = Result; + +impl crate::Device for super::Device { + unsafe fn exit(self) {} + unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_buffer(&self, buffer: Resource) {} + unsafe fn map_buffer( + &self, + buffer: &Resource, + range: crate::MemoryRange, + ) -> DeviceResult { + Err(crate::DeviceError::Lost) + } + unsafe fn unmap_buffer(&self, buffer: &Resource) -> DeviceResult<()> { + Ok(()) + } + unsafe fn flush_mapped_ranges(&self, buffer: &Resource, ranges: I) {} + unsafe fn invalidate_mapped_ranges(&self, buffer: &Resource, ranges: I) {} + + unsafe fn create_texture(&self, desc: &crate::TextureDescriptor) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_texture(&self, texture: Resource) {} + unsafe fn create_texture_view( + &self, + texture: &Resource, + desc: &crate::TextureViewDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_texture_view(&self, view: Resource) {} + unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_sampler(&self, sampler: Resource) {} + + unsafe fn create_command_encoder( + &self, + desc: &crate::CommandEncoderDescriptor, + ) -> DeviceResult { + Ok(Encoder) + } + unsafe fn destroy_command_encoder(&self, encoder: Encoder) {} + + unsafe fn create_bind_group_layout( + &self, + desc: &crate::BindGroupLayoutDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} + unsafe fn create_pipeline_layout( + &self, + desc: &crate::PipelineLayoutDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} + unsafe fn create_bind_group( + &self, + desc: &crate::BindGroupDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_bind_group(&self, group: Resource) {} + + unsafe fn create_shader_module( + &self, + desc: &crate::ShaderModuleDescriptor, + shader: crate::ShaderInput, + ) -> Result { + Ok(Resource) + } + unsafe fn destroy_shader_module(&self, module: Resource) {} + unsafe fn create_render_pipeline( + &self, + desc: &crate::RenderPipelineDescriptor, + ) -> Result { + Ok(Resource) + } + unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {} + unsafe fn create_compute_pipeline( + &self, + desc: &crate::ComputePipelineDescriptor, + ) -> Result { + Ok(Resource) + } + unsafe fn destroy_compute_pipeline(&self, pipeline: Resource) {} + + unsafe fn create_query_set( + &self, + desc: &wgt::QuerySetDescriptor, + ) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_query_set(&self, set: Resource) {} + unsafe fn create_fence(&self) -> DeviceResult { + Ok(Resource) + } + unsafe fn destroy_fence(&self, fence: Resource) {} + unsafe fn get_fence_value(&self, fence: &Resource) -> DeviceResult { + Ok(0) + } + unsafe fn wait( + &self, + fence: &Resource, + value: crate::FenceValue, + timeout_ms: u32, + ) -> DeviceResult { + Ok(true) + } + + unsafe fn start_capture(&self) -> bool { + false + } + unsafe fn stop_capture(&self) {} +} diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 1ca55e8d68..669d5e2392 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -8,9 +8,11 @@ #![allow(unused_variables)] mod adapter; +mod command; mod conv; +mod device; -use std::{borrow::Cow, ops::Range, sync::Arc}; +use std::{borrow::Cow, sync::Arc}; use winapi::{ shared::{dxgi, dxgi1_2, dxgi1_4, dxgi1_6, windef, winerror}, Interface as _, @@ -23,8 +25,6 @@ pub struct Encoder; #[derive(Debug)] pub struct Resource; -type DeviceResult = Result; - impl crate::Api for Api { type Instance = Instance; type Surface = Surface; @@ -101,10 +101,12 @@ impl Drop for Instance { unsafe impl Send for Instance {} unsafe impl Sync for Instance {} +struct SwapChain {} + pub struct Surface { factory: native::WeakPtr, wnd_handle: windef::HWND, - //presentation: Option, + swap_chain: Option, } unsafe impl Send for Surface {} @@ -224,13 +226,11 @@ impl crate::Instance for Instance { has_handle: &impl raw_window_handle::HasRawWindowHandle, ) -> Result { match has_handle.raw_window_handle() { - raw_window_handle::RawWindowHandle::Windows(handle) => { - Ok(Surface { - factory: self.factory, - wnd_handle: handle.hwnd as *mut _, - //presentation: None, - }) - } + raw_window_handle::RawWindowHandle::Windows(handle) => Ok(Surface { + factory: self.factory, + wnd_handle: handle.hwnd as *mut _, + swap_chain: None, + }), _ => Err(crate::InstanceError), } } @@ -334,7 +334,7 @@ impl crate::Queue for Queue { &mut self, command_buffers: &[&Resource], signal_fence: Option<(&mut Resource, crate::FenceValue)>, - ) -> DeviceResult<()> { + ) -> Result<(), crate::DeviceError> { Ok(()) } unsafe fn present( @@ -345,283 +345,3 @@ impl crate::Queue for Queue { Ok(()) } } - -impl crate::Device for Device { - unsafe fn exit(self) {} - unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_buffer(&self, buffer: Resource) {} - unsafe fn map_buffer( - &self, - buffer: &Resource, - range: crate::MemoryRange, - ) -> DeviceResult { - Err(crate::DeviceError::Lost) - } - unsafe fn unmap_buffer(&self, buffer: &Resource) -> DeviceResult<()> { - Ok(()) - } - unsafe fn flush_mapped_ranges(&self, buffer: &Resource, ranges: I) {} - unsafe fn invalidate_mapped_ranges(&self, buffer: &Resource, ranges: I) {} - - unsafe fn create_texture(&self, desc: &crate::TextureDescriptor) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_texture(&self, texture: Resource) {} - unsafe fn create_texture_view( - &self, - texture: &Resource, - desc: &crate::TextureViewDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_texture_view(&self, view: Resource) {} - unsafe fn create_sampler(&self, desc: &crate::SamplerDescriptor) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_sampler(&self, sampler: Resource) {} - - unsafe fn create_command_encoder( - &self, - desc: &crate::CommandEncoderDescriptor, - ) -> DeviceResult { - Ok(Encoder) - } - unsafe fn destroy_command_encoder(&self, encoder: Encoder) {} - - unsafe fn create_bind_group_layout( - &self, - desc: &crate::BindGroupLayoutDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_bind_group_layout(&self, bg_layout: Resource) {} - unsafe fn create_pipeline_layout( - &self, - desc: &crate::PipelineLayoutDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_pipeline_layout(&self, pipeline_layout: Resource) {} - unsafe fn create_bind_group( - &self, - desc: &crate::BindGroupDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_bind_group(&self, group: Resource) {} - - unsafe fn create_shader_module( - &self, - desc: &crate::ShaderModuleDescriptor, - shader: crate::ShaderInput, - ) -> Result { - Ok(Resource) - } - unsafe fn destroy_shader_module(&self, module: Resource) {} - unsafe fn create_render_pipeline( - &self, - desc: &crate::RenderPipelineDescriptor, - ) -> Result { - Ok(Resource) - } - unsafe fn destroy_render_pipeline(&self, pipeline: Resource) {} - unsafe fn create_compute_pipeline( - &self, - desc: &crate::ComputePipelineDescriptor, - ) -> Result { - Ok(Resource) - } - unsafe fn destroy_compute_pipeline(&self, pipeline: Resource) {} - - unsafe fn create_query_set( - &self, - desc: &wgt::QuerySetDescriptor, - ) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_query_set(&self, set: Resource) {} - unsafe fn create_fence(&self) -> DeviceResult { - Ok(Resource) - } - unsafe fn destroy_fence(&self, fence: Resource) {} - unsafe fn get_fence_value(&self, fence: &Resource) -> DeviceResult { - Ok(0) - } - unsafe fn wait( - &self, - fence: &Resource, - value: crate::FenceValue, - timeout_ms: u32, - ) -> DeviceResult { - Ok(true) - } - - unsafe fn start_capture(&self) -> bool { - false - } - unsafe fn stop_capture(&self) {} -} - -impl crate::CommandEncoder for Encoder { - unsafe fn begin_encoding(&mut self, label: crate::Label) -> DeviceResult<()> { - Ok(()) - } - unsafe fn discard_encoding(&mut self) {} - unsafe fn end_encoding(&mut self) -> DeviceResult { - Ok(Resource) - } - unsafe fn reset_all(&mut self, command_buffers: I) {} - - unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) - where - T: Iterator>, - { - } - - unsafe fn transition_textures<'a, T>(&mut self, barriers: T) - where - T: Iterator>, - { - } - - unsafe fn fill_buffer(&mut self, buffer: &Resource, range: crate::MemoryRange, value: u8) {} - - unsafe fn copy_buffer_to_buffer(&mut self, src: &Resource, dst: &Resource, regions: T) {} - - unsafe fn copy_texture_to_texture( - &mut self, - src: &Resource, - src_usage: crate::TextureUses, - dst: &Resource, - regions: T, - ) { - } - - unsafe fn copy_buffer_to_texture(&mut self, src: &Resource, dst: &Resource, regions: T) {} - - unsafe fn copy_texture_to_buffer( - &mut self, - src: &Resource, - src_usage: crate::TextureUses, - dst: &Resource, - regions: T, - ) { - } - - 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 copy_query_results( - &mut self, - set: &Resource, - range: Range, - buffer: &Resource, - offset: wgt::BufferAddress, - stride: wgt::BufferSize, - ) { - } - - // render - - unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor) {} - unsafe fn end_render_pass(&mut self) {} - - unsafe fn set_bind_group( - &mut self, - layout: &Resource, - index: u32, - group: &Resource, - dynamic_offsets: &[wgt::DynamicOffset], - ) { - } - unsafe fn set_push_constants( - &mut self, - layout: &Resource, - stages: wgt::ShaderStages, - offset: u32, - data: &[u32], - ) { - } - - unsafe fn insert_debug_marker(&mut self, label: &str) {} - unsafe fn begin_debug_marker(&mut self, group_label: &str) {} - unsafe fn end_debug_marker(&mut self) {} - - unsafe fn set_render_pipeline(&mut self, pipeline: &Resource) {} - - unsafe fn set_index_buffer<'a>( - &mut self, - binding: crate::BufferBinding<'a, Api>, - format: wgt::IndexFormat, - ) { - } - unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: crate::BufferBinding<'a, Api>) { - } - unsafe fn set_viewport(&mut self, rect: &crate::Rect, depth_range: Range) {} - unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect) {} - unsafe fn set_stencil_reference(&mut self, value: u32) {} - unsafe fn set_blend_constants(&mut self, color: &wgt::Color) {} - - unsafe fn draw( - &mut self, - start_vertex: u32, - vertex_count: u32, - start_instance: u32, - instance_count: u32, - ) { - } - unsafe fn draw_indexed( - &mut self, - start_index: u32, - index_count: u32, - base_vertex: i32, - start_instance: u32, - instance_count: u32, - ) { - } - unsafe fn draw_indirect( - &mut self, - buffer: &Resource, - offset: wgt::BufferAddress, - draw_count: u32, - ) { - } - unsafe fn draw_indexed_indirect( - &mut self, - buffer: &Resource, - offset: wgt::BufferAddress, - draw_count: u32, - ) { - } - unsafe fn draw_indirect_count( - &mut self, - buffer: &Resource, - offset: wgt::BufferAddress, - count_buffer: &Resource, - count_offset: wgt::BufferAddress, - max_count: u32, - ) { - } - unsafe fn draw_indexed_indirect_count( - &mut self, - buffer: &Resource, - offset: wgt::BufferAddress, - count_buffer: &Resource, - count_offset: wgt::BufferAddress, - max_count: u32, - ) { - } - - // compute - - unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) {} - unsafe fn end_compute_pass(&mut self) {} - - unsafe fn set_compute_pipeline(&mut self, pipeline: &Resource) {} - - unsafe fn dispatch(&mut self, count: [u32; 3]) {} - unsafe fn dispatch_indirect(&mut self, buffer: &Resource, offset: wgt::BufferAddress) {} -}