diff options
Diffstat (limited to 'third_party/rust/wgpu-hal/src/dx11')
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/adapter.rs | 289 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/command.rs | 268 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/device.rs | 242 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/instance.rs | 48 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/library.rs | 144 | ||||
-rw-r--r-- | third_party/rust/wgpu-hal/src/dx11/mod.rs | 137 |
6 files changed, 1128 insertions, 0 deletions
diff --git a/third_party/rust/wgpu-hal/src/dx11/adapter.rs b/third_party/rust/wgpu-hal/src/dx11/adapter.rs new file mode 100644 index 0000000000..6e14b42f5a --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/adapter.rs @@ -0,0 +1,289 @@ +use std::num::NonZeroU64; + +use winapi::um::{d3d11, d3dcommon}; + +impl crate::Adapter<super::Api> for super::Adapter { + unsafe fn open( + &self, + features: wgt::Features, + limits: &wgt::Limits, + ) -> Result<crate::OpenDevice<super::Api>, crate::DeviceError> { + todo!() + } + + unsafe fn texture_format_capabilities( + &self, + format: wgt::TextureFormat, + ) -> crate::TextureFormatCapabilities { + todo!() + } + + unsafe fn surface_capabilities( + &self, + surface: &super::Surface, + ) -> Option<crate::SurfaceCapabilities> { + todo!() + } + + unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp { + todo!() + } +} + +impl super::Adapter { + pub(super) fn expose( + instance: &super::library::D3D11Lib, + adapter: native::DxgiAdapter, + ) -> Option<crate::ExposedAdapter<super::Api>> { + use d3dcommon::{ + D3D_FEATURE_LEVEL_10_0 as FL10_0, D3D_FEATURE_LEVEL_10_1 as FL10_1, + D3D_FEATURE_LEVEL_11_0 as FL11_0, D3D_FEATURE_LEVEL_11_1 as FL11_1, + D3D_FEATURE_LEVEL_9_1 as FL9_1, D3D_FEATURE_LEVEL_9_2 as FL9_2, + D3D_FEATURE_LEVEL_9_3 as FL9_3, + }; + + let (device, feature_level) = instance.create_device(adapter)?; + + // + // Query Features from d3d11 + // + + let d3d9_features = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D9_OPTIONS1>( + d3d11::D3D11_FEATURE_D3D9_OPTIONS1, + ) + }; + + let d3d10_features = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS>( + d3d11::D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, + ) + }; + + let d3d11_features = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D11_OPTIONS>( + d3d11::D3D11_FEATURE_D3D11_OPTIONS, + ) + }; + + let d3d11_features1 = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D11_OPTIONS1>( + d3d11::D3D11_FEATURE_D3D11_OPTIONS1, + ) + }; + + let d3d11_features2 = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D11_OPTIONS2>( + d3d11::D3D11_FEATURE_D3D11_OPTIONS2, + ) + }; + + let d3d11_features3 = unsafe { + device.check_feature_support::<d3d11::D3D11_FEATURE_DATA_D3D11_OPTIONS3>( + d3d11::D3D11_FEATURE_D3D11_OPTIONS3, + ) + }; + + // + // Fill out features and downlevel features + // + // TODO(cwfitzgerald): Needed downlevel features: 3D dispatch + + let mut features = wgt::Features::DEPTH_CLIP_CONTROL + | wgt::Features::PUSH_CONSTANTS + | wgt::Features::POLYGON_MODE_LINE + | wgt::Features::CLEAR_TEXTURE + | wgt::Features::TEXTURE_FORMAT_16BIT_NORM + | wgt::Features::ADDRESS_MODE_CLAMP_TO_ZERO; + let mut downlevel = wgt::DownlevelFlags::BASE_VERTEX + | wgt::DownlevelFlags::READ_ONLY_DEPTH_STENCIL + | wgt::DownlevelFlags::UNRESTRICTED_INDEX_BUFFER; + + // Features from queries + downlevel.set( + wgt::DownlevelFlags::NON_POWER_OF_TWO_MIPMAPPED_TEXTURES, + d3d9_features.FullNonPow2TextureSupported == 1, + ); + downlevel.set( + wgt::DownlevelFlags::COMPUTE_SHADERS, + d3d10_features.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x == 1, + ); + + // Features from feature level + if feature_level >= FL9_2 { + downlevel |= wgt::DownlevelFlags::INDEPENDENT_BLEND; + // formally FL9_1 supports aniso 2, but we don't support that level of distinction + downlevel |= wgt::DownlevelFlags::ANISOTROPIC_FILTERING; + // this is actually the first FL that supports u32 at all + downlevel |= wgt::DownlevelFlags::FULL_DRAW_INDEX_UINT32; + } + + if feature_level >= FL9_3 { + downlevel |= wgt::DownlevelFlags::COMPARISON_SAMPLERS; + } + + if feature_level >= FL10_0 { + downlevel |= wgt::DownlevelFlags::INDEPENDENT_BLEND; + downlevel |= wgt::DownlevelFlags::FRAGMENT_STORAGE; + downlevel |= wgt::DownlevelFlags::FRAGMENT_WRITABLE_STORAGE; + downlevel |= wgt::DownlevelFlags::DEPTH_BIAS_CLAMP; + features |= wgt::Features::DEPTH_CLIP_CONTROL; + features |= wgt::Features::TIMESTAMP_QUERY; + features |= wgt::Features::PIPELINE_STATISTICS_QUERY; + features |= wgt::Features::SHADER_PRIMITIVE_INDEX; + } + + if feature_level >= FL10_1 { + downlevel |= wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES; + } + + if feature_level >= FL11_0 { + downlevel |= wgt::DownlevelFlags::INDIRECT_EXECUTION; + downlevel |= wgt::DownlevelFlags::WEBGPU_TEXTURE_FORMAT_SUPPORT; + features |= wgt::Features::TEXTURE_COMPRESSION_BC; + } + + if feature_level >= FL11_1 { + downlevel |= wgt::DownlevelFlags::VERTEX_STORAGE; + } + + // + // Fill out limits and alignments + // + + let max_texture_dimension_2d = match feature_level { + FL9_1 | FL9_2 => 2048, + FL9_3 => 4096, + FL10_0 | FL10_1 => 8192, + _ => d3d11::D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION, + }; + + let max_texture_dimension_3d = match feature_level { + FL9_1..=FL9_3 => 256, + _ => d3d11::D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION, + }; + let max_vertex_buffers = match feature_level { + FL9_1..=FL9_3 => 16, + _ => 32, + }; + let max_compute_workgroup_storage_size = match feature_level { + FL9_1..=FL9_3 => 0, + FL10_0 | FL10_1 => 4096 * 4, // This doesn't have an equiv SM4 constant :\ + _ => d3d11::D3D11_CS_TGSM_REGISTER_COUNT * 4, + }; + let max_workgroup_size_xy = match feature_level { + FL9_1..=FL9_3 => 0, + FL10_0 | FL10_1 => d3d11::D3D11_CS_4_X_THREAD_GROUP_MAX_X, + _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_X, + }; + let max_workgroup_size_z = match feature_level { + FL9_1..=FL9_3 => 0, + FL10_0 | FL10_1 => 1, + _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_Z, + }; + // let max_workgroup_count_z = match feature_level { + // FL9_1..=FL9_3 => 0, + // FL10_0 | FL10_1 => 1, + // _ => d3d11::D3D11_CS_THREAD_GROUP_MAX_Z, + // }; + + let max_sampled_textures = d3d11::D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT; + let max_samplers = d3d11::D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + let max_constant_buffers = d3d11::D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1; + let max_uavs = if device.as_device1().is_some() { + d3d11::D3D11_1_UAV_SLOT_COUNT + } else { + d3d11::D3D11_PS_CS_UAV_REGISTER_COUNT + }; + let max_output_registers = d3d11::D3D11_VS_OUTPUT_REGISTER_COMPONENTS; + let max_compute_invocations_per_workgroup = + d3d11::D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; + let max_compute_workgroups_per_dimension = + d3d11::D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION; + + let limits = wgt::Limits { + max_texture_dimension_1d: max_texture_dimension_2d, + max_texture_dimension_2d, + max_texture_dimension_3d, + max_texture_array_layers: max_texture_dimension_3d, + max_bind_groups: u32::MAX, + max_bindings_per_bind_group: 65535, + max_dynamic_uniform_buffers_per_pipeline_layout: max_constant_buffers, + max_dynamic_storage_buffers_per_pipeline_layout: 0, + max_sampled_textures_per_shader_stage: max_sampled_textures, + max_samplers_per_shader_stage: max_samplers, + max_storage_buffers_per_shader_stage: max_uavs, + max_storage_textures_per_shader_stage: max_uavs, + max_uniform_buffers_per_shader_stage: max_constant_buffers, + max_uniform_buffer_binding_size: 1 << 16, + max_storage_buffer_binding_size: u32::MAX, + max_vertex_buffers, + max_vertex_attributes: max_vertex_buffers, + max_vertex_buffer_array_stride: u32::MAX, + max_push_constant_size: 1 << 16, + min_uniform_buffer_offset_alignment: 256, + min_storage_buffer_offset_alignment: 1, + max_inter_stage_shader_components: max_output_registers, + max_compute_workgroup_storage_size, + max_compute_invocations_per_workgroup, + max_compute_workgroup_size_x: max_workgroup_size_xy, + max_compute_workgroup_size_y: max_workgroup_size_xy, + max_compute_workgroup_size_z: max_workgroup_size_z, + max_compute_workgroups_per_dimension, + // D3D11_BUFFER_DESC represents the buffer size as a 32 bit int. + max_buffer_size: u32::MAX as u64, + }; + + // + // Other capabilities + // + + let shader_model = match feature_level { + FL9_1..=FL9_3 => wgt::ShaderModel::Sm2, + FL10_0 | FL10_1 => wgt::ShaderModel::Sm4, + _ => wgt::ShaderModel::Sm5, + }; + + let device_info = wgt::AdapterInfo { + name: String::new(), + vendor: 0, + device: 0, + device_type: match d3d11_features2.UnifiedMemoryArchitecture { + 0 => wgt::DeviceType::DiscreteGpu, + 1 => wgt::DeviceType::IntegratedGpu, + _ => unreachable!(), + }, + driver: String::new(), + driver_info: String::new(), + backend: wgt::Backend::Dx11, + }; + + // + // Build up the structs + // + + let api_adapter = super::Adapter { device }; + + let alignments = crate::Alignments { + buffer_copy_offset: NonZeroU64::new(1).unwrap(), // todo + buffer_copy_pitch: NonZeroU64::new(1).unwrap(), // todo + }; + + let capabilities = crate::Capabilities { + limits, + alignments, + downlevel: wgt::DownlevelCapabilities { + flags: downlevel, + limits: wgt::DownlevelLimits {}, + shader_model, + }, + }; + + Some(crate::ExposedAdapter { + adapter: api_adapter, + info: device_info, + features, + capabilities, + }) + } +} diff --git a/third_party/rust/wgpu-hal/src/dx11/command.rs b/third_party/rust/wgpu-hal/src/dx11/command.rs new file mode 100644 index 0000000000..1c73f3c325 --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/command.rs @@ -0,0 +1,268 @@ +impl crate::CommandEncoder<super::Api> for super::CommandEncoder { + unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> { + todo!() + } + + unsafe fn discard_encoding(&mut self) { + todo!() + } + + unsafe fn end_encoding(&mut self) -> Result<super::CommandBuffer, crate::DeviceError> { + todo!() + } + + unsafe fn reset_all<I>(&mut self, command_buffers: I) + where + I: Iterator<Item = super::CommandBuffer>, + { + todo!() + } + + unsafe fn transition_buffers<'a, T>(&mut self, barriers: T) + where + T: Iterator<Item = crate::BufferBarrier<'a, super::Api>>, + { + todo!() + } + + unsafe fn transition_textures<'a, T>(&mut self, barriers: T) + where + T: Iterator<Item = crate::TextureBarrier<'a, super::Api>>, + { + todo!() + } + + unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) { + todo!() + } + + unsafe fn copy_buffer_to_buffer<T>( + &mut self, + src: &super::Buffer, + dst: &super::Buffer, + regions: T, + ) where + T: Iterator<Item = crate::BufferCopy>, + { + todo!() + } + + unsafe fn copy_texture_to_texture<T>( + &mut self, + src: &super::Texture, + src_usage: crate::TextureUses, + dst: &super::Texture, + regions: T, + ) where + T: Iterator<Item = crate::TextureCopy>, + { + todo!() + } + + unsafe fn copy_buffer_to_texture<T>( + &mut self, + src: &super::Buffer, + dst: &super::Texture, + regions: T, + ) where + T: Iterator<Item = crate::BufferTextureCopy>, + { + todo!() + } + + unsafe fn copy_texture_to_buffer<T>( + &mut self, + src: &super::Texture, + src_usage: crate::TextureUses, + dst: &super::Buffer, + regions: T, + ) where + T: Iterator<Item = crate::BufferTextureCopy>, + { + todo!() + } + + unsafe fn set_bind_group( + &mut self, + layout: &super::PipelineLayout, + index: u32, + group: &super::BindGroup, + dynamic_offsets: &[wgt::DynamicOffset], + ) { + todo!() + } + + unsafe fn set_push_constants( + &mut self, + layout: &super::PipelineLayout, + stages: wgt::ShaderStages, + offset: u32, + data: &[u32], + ) { + todo!() + } + + unsafe fn insert_debug_marker(&mut self, label: &str) { + todo!() + } + + unsafe fn begin_debug_marker(&mut self, group_label: &str) { + todo!() + } + + unsafe fn end_debug_marker(&mut self) { + todo!() + } + + unsafe fn begin_query(&mut self, set: &super::QuerySet, index: u32) { + todo!() + } + + unsafe fn end_query(&mut self, set: &super::QuerySet, index: u32) { + todo!() + } + + unsafe fn write_timestamp(&mut self, set: &super::QuerySet, index: u32) { + todo!() + } + + unsafe fn reset_queries(&mut self, set: &super::QuerySet, range: std::ops::Range<u32>) { + todo!() + } + + unsafe fn copy_query_results( + &mut self, + set: &super::QuerySet, + range: std::ops::Range<u32>, + buffer: &super::Buffer, + offset: wgt::BufferAddress, + stride: wgt::BufferSize, + ) { + todo!() + } + + unsafe fn begin_render_pass(&mut self, desc: &crate::RenderPassDescriptor<super::Api>) { + todo!() + } + + unsafe fn end_render_pass(&mut self) { + todo!() + } + + unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) { + todo!() + } + + unsafe fn set_index_buffer<'a>( + &mut self, + binding: crate::BufferBinding<'a, super::Api>, + format: wgt::IndexFormat, + ) { + todo!() + } + + unsafe fn set_vertex_buffer<'a>( + &mut self, + index: u32, + binding: crate::BufferBinding<'a, super::Api>, + ) { + todo!() + } + + unsafe fn set_viewport(&mut self, rect: &crate::Rect<f32>, depth_range: std::ops::Range<f32>) { + todo!() + } + + unsafe fn set_scissor_rect(&mut self, rect: &crate::Rect<u32>) { + todo!() + } + + unsafe fn set_stencil_reference(&mut self, value: u32) { + todo!() + } + + unsafe fn set_blend_constants(&mut self, color: &[f32; 4]) { + todo!() + } + + unsafe fn draw( + &mut self, + start_vertex: u32, + vertex_count: u32, + start_instance: u32, + instance_count: u32, + ) { + todo!() + } + + unsafe fn draw_indexed( + &mut self, + start_index: u32, + index_count: u32, + base_vertex: i32, + start_instance: u32, + instance_count: u32, + ) { + todo!() + } + + unsafe fn draw_indirect( + &mut self, + buffer: &super::Buffer, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + todo!() + } + + unsafe fn draw_indexed_indirect( + &mut self, + buffer: &super::Buffer, + offset: wgt::BufferAddress, + draw_count: u32, + ) { + todo!() + } + + unsafe fn draw_indirect_count( + &mut self, + buffer: &super::Buffer, + offset: wgt::BufferAddress, + count_buffer: &super::Buffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + todo!() + } + + unsafe fn draw_indexed_indirect_count( + &mut self, + buffer: &super::Buffer, + offset: wgt::BufferAddress, + count_buffer: &super::Buffer, + count_offset: wgt::BufferAddress, + max_count: u32, + ) { + todo!() + } + + unsafe fn begin_compute_pass(&mut self, desc: &crate::ComputePassDescriptor) { + todo!() + } + + unsafe fn end_compute_pass(&mut self) { + todo!() + } + + unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) { + todo!() + } + + unsafe fn dispatch(&mut self, count: [u32; 3]) { + todo!() + } + + unsafe fn dispatch_indirect(&mut self, buffer: &super::Buffer, offset: wgt::BufferAddress) { + todo!() + } +} diff --git a/third_party/rust/wgpu-hal/src/dx11/device.rs b/third_party/rust/wgpu-hal/src/dx11/device.rs new file mode 100644 index 0000000000..3b087c4311 --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/device.rs @@ -0,0 +1,242 @@ +use std::{ffi::c_void, mem}; + +use winapi::um::d3d11; + +use crate::auxil::dxgi::result::HResult; + +impl crate::Device<super::Api> for super::Device { + unsafe fn exit(self, queue: super::Queue) { + todo!() + } + + unsafe fn create_buffer( + &self, + desc: &crate::BufferDescriptor, + ) -> Result<super::Buffer, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_buffer(&self, buffer: super::Buffer) { + todo!() + } + + unsafe fn map_buffer( + &self, + buffer: &super::Buffer, + range: crate::MemoryRange, + ) -> Result<crate::BufferMapping, crate::DeviceError> { + todo!() + } + + unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> { + todo!() + } + + unsafe fn flush_mapped_ranges<I>(&self, buffer: &super::Buffer, ranges: I) + where + I: Iterator<Item = crate::MemoryRange>, + { + todo!() + } + + unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &super::Buffer, ranges: I) + where + I: Iterator<Item = crate::MemoryRange>, + { + todo!() + } + + unsafe fn create_texture( + &self, + desc: &crate::TextureDescriptor, + ) -> Result<super::Texture, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_texture(&self, texture: super::Texture) { + todo!() + } + + unsafe fn create_texture_view( + &self, + texture: &super::Texture, + desc: &crate::TextureViewDescriptor, + ) -> Result<super::TextureView, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_texture_view(&self, view: super::TextureView) { + todo!() + } + + unsafe fn create_sampler( + &self, + desc: &crate::SamplerDescriptor, + ) -> Result<super::Sampler, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_sampler(&self, sampler: super::Sampler) { + todo!() + } + + unsafe fn create_command_encoder( + &self, + desc: &crate::CommandEncoderDescriptor<super::Api>, + ) -> Result<super::CommandEncoder, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_command_encoder(&self, pool: super::CommandEncoder) { + todo!() + } + + unsafe fn create_bind_group_layout( + &self, + desc: &crate::BindGroupLayoutDescriptor, + ) -> Result<super::BindGroupLayout, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_bind_group_layout(&self, bg_layout: super::BindGroupLayout) { + todo!() + } + + unsafe fn create_pipeline_layout( + &self, + desc: &crate::PipelineLayoutDescriptor<super::Api>, + ) -> Result<super::PipelineLayout, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_pipeline_layout(&self, pipeline_layout: super::PipelineLayout) { + todo!() + } + + unsafe fn create_bind_group( + &self, + desc: &crate::BindGroupDescriptor<super::Api>, + ) -> Result<super::BindGroup, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_bind_group(&self, group: super::BindGroup) { + todo!() + } + + unsafe fn create_shader_module( + &self, + desc: &crate::ShaderModuleDescriptor, + shader: crate::ShaderInput, + ) -> Result<super::ShaderModule, crate::ShaderError> { + todo!() + } + + unsafe fn destroy_shader_module(&self, module: super::ShaderModule) { + todo!() + } + + unsafe fn create_render_pipeline( + &self, + desc: &crate::RenderPipelineDescriptor<super::Api>, + ) -> Result<super::RenderPipeline, crate::PipelineError> { + todo!() + } + + unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) { + todo!() + } + + unsafe fn create_compute_pipeline( + &self, + desc: &crate::ComputePipelineDescriptor<super::Api>, + ) -> Result<super::ComputePipeline, crate::PipelineError> { + todo!() + } + + unsafe fn destroy_compute_pipeline(&self, pipeline: super::ComputePipeline) { + todo!() + } + + unsafe fn create_query_set( + &self, + desc: &wgt::QuerySetDescriptor<crate::Label>, + ) -> Result<super::QuerySet, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_query_set(&self, set: super::QuerySet) { + todo!() + } + + unsafe fn create_fence(&self) -> Result<super::Fence, crate::DeviceError> { + todo!() + } + + unsafe fn destroy_fence(&self, fence: super::Fence) { + todo!() + } + + unsafe fn get_fence_value( + &self, + fence: &super::Fence, + ) -> Result<crate::FenceValue, crate::DeviceError> { + todo!() + } + + unsafe fn wait( + &self, + fence: &super::Fence, + value: crate::FenceValue, + timeout_ms: u32, + ) -> Result<bool, crate::DeviceError> { + todo!() + } + + unsafe fn start_capture(&self) -> bool { + todo!() + } + + unsafe fn stop_capture(&self) { + todo!() + } +} + +impl crate::Queue<super::Api> for super::Queue { + unsafe fn submit( + &mut self, + command_buffers: &[&super::CommandBuffer], + signal_fence: Option<(&mut super::Fence, crate::FenceValue)>, + ) -> Result<(), crate::DeviceError> { + todo!() + } + + unsafe fn present( + &mut self, + surface: &mut super::Surface, + texture: super::SurfaceTexture, + ) -> Result<(), crate::SurfaceError> { + todo!() + } + + unsafe fn get_timestamp_period(&self) -> f32 { + todo!() + } +} + +impl super::D3D11Device { + #[allow(trivial_casts)] // come on + pub unsafe fn check_feature_support<T>(&self, feature: d3d11::D3D11_FEATURE) -> T { + unsafe { + let mut value = mem::zeroed::<T>(); + let ret = self.CheckFeatureSupport( + feature, + &mut value as *mut T as *mut c_void, + mem::size_of::<T>() as u32, + ); + assert_eq!(ret.into_result(), Ok(())); + + value + } + } +} diff --git a/third_party/rust/wgpu-hal/src/dx11/instance.rs b/third_party/rust/wgpu-hal/src/dx11/instance.rs new file mode 100644 index 0000000000..104ba9e045 --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/instance.rs @@ -0,0 +1,48 @@ +use crate::auxil; + +impl crate::Instance<super::Api> for super::Instance { + unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> { + let enable_dx11 = match std::env::var("WGPU_UNSTABLE_DX11_BACKEND") { + Ok(string) => string == "1" || string == "true", + Err(_) => false, + }; + + if !enable_dx11 { + return Err(crate::InstanceError); + } + + let lib_d3d11 = super::library::D3D11Lib::new().ok_or(crate::InstanceError)?; + + let (lib_dxgi, factory) = auxil::dxgi::factory::create_factory( + auxil::dxgi::factory::DxgiFactoryType::Factory1, + desc.flags, + )?; + + Ok(super::Instance { + lib_d3d11, + lib_dxgi, + factory, + }) + } + + unsafe fn create_surface( + &self, + display_handle: raw_window_handle::RawDisplayHandle, + window_handle: raw_window_handle::RawWindowHandle, + ) -> Result<super::Surface, crate::InstanceError> { + todo!() + } + + unsafe fn destroy_surface(&self, surface: super::Surface) { + todo!() + } + + unsafe fn enumerate_adapters(&self) -> Vec<crate::ExposedAdapter<super::Api>> { + let adapters = auxil::dxgi::factory::enumerate_adapters(self.factory); + + adapters + .into_iter() + .filter_map(|adapter| super::Adapter::expose(&self.lib_d3d11, adapter)) + .collect() + } +} diff --git a/third_party/rust/wgpu-hal/src/dx11/library.rs b/third_party/rust/wgpu-hal/src/dx11/library.rs new file mode 100644 index 0000000000..1b2defe4f8 --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/library.rs @@ -0,0 +1,144 @@ +use std::ptr; + +use winapi::{ + shared::{ + dxgi, + minwindef::{HMODULE, UINT}, + winerror, + }, + um::{d3d11, d3d11_1, d3d11_2, d3dcommon}, +}; + +use crate::auxil::dxgi::result::HResult; + +type D3D11CreateDeviceFun = unsafe extern "system" fn( + *mut dxgi::IDXGIAdapter, + d3dcommon::D3D_DRIVER_TYPE, + HMODULE, + UINT, + *const d3dcommon::D3D_FEATURE_LEVEL, + UINT, + UINT, + *mut *mut d3d11::ID3D11Device, + *mut d3dcommon::D3D_FEATURE_LEVEL, + *mut *mut d3d11::ID3D11DeviceContext, +) -> native::HRESULT; + +pub(super) struct D3D11Lib { + // We use the os specific symbol to drop the lifetime parameter. + // + // SAFETY: we must ensure this outlives the Library. + d3d11_create_device: libloading::os::windows::Symbol<D3D11CreateDeviceFun>, + + lib: libloading::Library, +} +impl D3D11Lib { + pub fn new() -> Option<Self> { + unsafe { + let lib = libloading::Library::new("d3d11.dll").ok()?; + + let d3d11_create_device = lib + .get::<D3D11CreateDeviceFun>(b"D3D11CreateDevice") + .ok()? + .into_raw(); + + Some(Self { + lib, + d3d11_create_device, + }) + } + } + + pub fn create_device( + &self, + adapter: native::DxgiAdapter, + ) -> Option<(super::D3D11Device, d3dcommon::D3D_FEATURE_LEVEL)> { + let feature_levels = [ + d3dcommon::D3D_FEATURE_LEVEL_11_1, + d3dcommon::D3D_FEATURE_LEVEL_11_0, + d3dcommon::D3D_FEATURE_LEVEL_10_1, + d3dcommon::D3D_FEATURE_LEVEL_10_0, + d3dcommon::D3D_FEATURE_LEVEL_9_3, + d3dcommon::D3D_FEATURE_LEVEL_9_2, + d3dcommon::D3D_FEATURE_LEVEL_9_1, + ]; + + let mut device = native::WeakPtr::<d3d11::ID3D11Device>::null(); + let mut feature_level: d3dcommon::D3D_FEATURE_LEVEL = 0; + + // We need to try this twice. If the first time fails due to E_INVALIDARG + // we are running on a machine without a D3D11.1 runtime, and need to + // retry without the feature level 11_1 feature level. + // + // Why they thought this was a good API, who knows. + + let mut hr = unsafe { + (self.d3d11_create_device)( + adapter.as_mut_ptr() as *mut _, + d3dcommon::D3D_DRIVER_TYPE_UNKNOWN, + ptr::null_mut(), // software implementation DLL??? + 0, // flags + feature_levels.as_ptr(), + feature_levels.len() as u32, + d3d11::D3D11_SDK_VERSION, + device.mut_self(), + &mut feature_level, + ptr::null_mut(), // device context + ) + }; + + // Try again without FL11_1 + if hr == winerror::E_INVALIDARG { + hr = unsafe { + (self.d3d11_create_device)( + adapter.as_mut_ptr() as *mut _, + d3dcommon::D3D_DRIVER_TYPE_UNKNOWN, + ptr::null_mut(), // software implementation DLL??? + 0, // flags + feature_levels[1..].as_ptr(), + feature_levels[1..].len() as u32, + d3d11::D3D11_SDK_VERSION, + device.mut_self(), + &mut feature_level, + ptr::null_mut(), // device context + ) + }; + } + + // Any errors here are real and we should complain about + if let Err(err) = hr.into_result() { + log::error!("Failed to make a D3D11 device: {}", err); + return None; + } + + // We always try to upcast in highest -> lowest order + + // Device -> Device2 + unsafe { + match device.cast::<d3d11_2::ID3D11Device2>().into_result() { + Ok(device2) => { + device.destroy(); + return Some((super::D3D11Device::Device2(device2), feature_level)); + } + Err(hr) => { + log::info!("Failed to cast device to ID3D11Device2: {}", hr) + } + } + } + + // Device -> Device1 + unsafe { + match device.cast::<d3d11_1::ID3D11Device1>().into_result() { + Ok(device1) => { + device.destroy(); + return Some((super::D3D11Device::Device1(device1), feature_level)); + } + Err(hr) => { + log::info!("Failed to cast device to ID3D11Device1: {}", hr) + } + } + } + + Some((super::D3D11Device::Device(device), feature_level)) + } +} diff --git a/third_party/rust/wgpu-hal/src/dx11/mod.rs b/third_party/rust/wgpu-hal/src/dx11/mod.rs new file mode 100644 index 0000000000..a459e4dca6 --- /dev/null +++ b/third_party/rust/wgpu-hal/src/dx11/mod.rs @@ -0,0 +1,137 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use winapi::um::{d3d11, d3d11_1, d3d11_2}; + +mod adapter; +mod command; +mod device; +mod instance; +mod library; + +#[derive(Clone)] +pub struct Api; + +impl crate::Api for Api { + type Instance = Instance; + type Surface = Surface; + type Adapter = Adapter; + type Device = Device; + + type Queue = Queue; + type CommandEncoder = CommandEncoder; + type CommandBuffer = CommandBuffer; + + type Buffer = Buffer; + type Texture = Texture; + type SurfaceTexture = SurfaceTexture; + type TextureView = TextureView; + type Sampler = Sampler; + type QuerySet = QuerySet; + type Fence = Fence; + + type BindGroupLayout = BindGroupLayout; + type BindGroup = BindGroup; + type PipelineLayout = PipelineLayout; + type ShaderModule = ShaderModule; + type RenderPipeline = RenderPipeline; + type ComputePipeline = ComputePipeline; +} + +pub struct Instance { + lib_d3d11: library::D3D11Lib, + lib_dxgi: native::DxgiLib, + factory: native::DxgiFactory, +} + +unsafe impl Send for Instance {} +unsafe impl Sync for Instance {} + +pub struct Surface {} + +pub struct Adapter { + device: D3D11Device, +} + +unsafe impl Send for Adapter {} +unsafe impl Sync for Adapter {} + +native::weak_com_inheritance_chain! { + #[derive(Debug, Copy, Clone, PartialEq)] + enum D3D11Device { + Device(d3d11::ID3D11Device), from_device, as_device, device; + Device1(d3d11_1::ID3D11Device1), from_device1, as_device1, unwrap_device1; + Device2(d3d11_2::ID3D11Device2), from_device2, as_device2, unwrap_device2; + } +} + +pub struct Device {} + +unsafe impl Send for Device {} +unsafe impl Sync for Device {} + +pub struct Queue {} + +#[derive(Debug)] +pub struct CommandEncoder {} + +#[derive(Debug)] +pub struct CommandBuffer {} + +#[derive(Debug)] +pub struct Buffer {} +#[derive(Debug)] +pub struct Texture {} +#[derive(Debug)] +pub struct SurfaceTexture {} + +impl std::borrow::Borrow<Texture> for SurfaceTexture { + fn borrow(&self) -> &Texture { + todo!() + } +} + +#[derive(Debug)] +pub struct TextureView {} +#[derive(Debug)] +pub struct Sampler {} +#[derive(Debug)] +pub struct QuerySet {} +#[derive(Debug)] +pub struct Fence {} +#[derive(Debug)] + +pub struct BindGroupLayout {} +#[derive(Debug)] +pub struct BindGroup {} +#[derive(Debug)] +pub struct PipelineLayout {} +#[derive(Debug)] +pub struct ShaderModule {} +pub struct RenderPipeline {} +pub struct ComputePipeline {} + +impl crate::Surface<Api> for Surface { + unsafe fn configure( + &mut self, + device: &Device, + config: &crate::SurfaceConfiguration, + ) -> Result<(), crate::SurfaceError> { + todo!() + } + + unsafe fn unconfigure(&mut self, device: &Device) { + todo!() + } + + unsafe fn acquire_texture( + &mut self, + _timeout: Option<std::time::Duration>, + ) -> Result<Option<crate::AcquiredSurfaceTexture<Api>>, crate::SurfaceError> { + todo!() + } + + unsafe fn discard_texture(&mut self, texture: SurfaceTexture) { + todo!() + } +} |