summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-hal/src/dx11
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/wgpu-hal/src/dx11')
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/adapter.rs289
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/command.rs268
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/device.rs242
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/instance.rs48
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/library.rs144
-rw-r--r--third_party/rust/wgpu-hal/src/dx11/mod.rs137
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!()
+ }
+}