summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-hal/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/wgpu-hal/src/dx12/adapter.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/dx12/command.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/dx12/device.rs15
-rw-r--r--third_party/rust/wgpu-hal/src/dx12/instance.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/dx12/mod.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/empty.rs24
-rw-r--r--third_party/rust/wgpu-hal/src/gles/adapter.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/gles/command.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/gles/device.rs21
-rw-r--r--third_party/rust/wgpu-hal/src/gles/egl.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/gles/queue.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/gles/web.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/gles/wgl.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/lib.rs253
-rw-r--r--third_party/rust/wgpu-hal/src/metal/adapter.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/metal/command.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/metal/device.rs15
-rw-r--r--third_party/rust/wgpu-hal/src/metal/mod.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/metal/surface.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/vulkan/adapter.rs181
-rw-r--r--third_party/rust/wgpu-hal/src/vulkan/command.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/vulkan/device.rs4
-rw-r--r--third_party/rust/wgpu-hal/src/vulkan/instance.rs8
-rw-r--r--third_party/rust/wgpu-hal/src/vulkan/mod.rs6
24 files changed, 442 insertions, 165 deletions
diff --git a/third_party/rust/wgpu-hal/src/dx12/adapter.rs b/third_party/rust/wgpu-hal/src/dx12/adapter.rs
index 960e1790a9..b417a88a6f 100644
--- a/third_party/rust/wgpu-hal/src/dx12/adapter.rs
+++ b/third_party/rust/wgpu-hal/src/dx12/adapter.rs
@@ -432,7 +432,9 @@ impl super::Adapter {
}
}
-impl crate::Adapter<super::Api> for super::Adapter {
+impl crate::Adapter for super::Adapter {
+ type A = super::Api;
+
unsafe fn open(
&self,
_features: wgt::Features,
diff --git a/third_party/rust/wgpu-hal/src/dx12/command.rs b/third_party/rust/wgpu-hal/src/dx12/command.rs
index 9d96d29cae..3c535b2234 100644
--- a/third_party/rust/wgpu-hal/src/dx12/command.rs
+++ b/third_party/rust/wgpu-hal/src/dx12/command.rs
@@ -249,7 +249,9 @@ impl super::CommandEncoder {
}
}
-impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
+impl crate::CommandEncoder for super::CommandEncoder {
+ type A = super::Api;
+
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
let list = loop {
if let Some(list) = self.free_lists.pop() {
diff --git a/third_party/rust/wgpu-hal/src/dx12/device.rs b/third_party/rust/wgpu-hal/src/dx12/device.rs
index 3603b033b8..23bd409dc4 100644
--- a/third_party/rust/wgpu-hal/src/dx12/device.rs
+++ b/third_party/rust/wgpu-hal/src/dx12/device.rs
@@ -323,7 +323,9 @@ impl super::Device {
}
}
-impl crate::Device<super::Api> for super::Device {
+impl crate::Device for super::Device {
+ type A = super::Api;
+
unsafe fn exit(mut self, _queue: super::Queue) {
self.rtv_pool.lock().free_handle(self.null_rtv_handle);
self.mem_allocator = None;
@@ -1098,7 +1100,16 @@ impl crate::Device<super::Api> for super::Device {
}
let mut dynamic_buffers = Vec::new();
- for (layout, entry) in desc.layout.entries.iter().zip(desc.entries.iter()) {
+ let layout_and_entry_iter = desc.entries.iter().map(|entry| {
+ let layout = desc
+ .layout
+ .entries
+ .iter()
+ .find(|layout_entry| layout_entry.binding == entry.binding)
+ .expect("internal error: no layout entry found with binding slot");
+ (layout, entry)
+ });
+ for (layout, entry) in layout_and_entry_iter {
match layout.ty {
wgt::BindingType::Buffer {
has_dynamic_offset: true,
diff --git a/third_party/rust/wgpu-hal/src/dx12/instance.rs b/third_party/rust/wgpu-hal/src/dx12/instance.rs
index 020809328e..1dba7101df 100644
--- a/third_party/rust/wgpu-hal/src/dx12/instance.rs
+++ b/third_party/rust/wgpu-hal/src/dx12/instance.rs
@@ -13,7 +13,9 @@ impl Drop for super::Instance {
}
}
-impl crate::Instance<super::Api> for super::Instance {
+impl crate::Instance for super::Instance {
+ type A = super::Api;
+
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init DX12 Backend");
let lib_main = d3d12::D3D12Lib::new().map_err(|e| {
diff --git a/third_party/rust/wgpu-hal/src/dx12/mod.rs b/third_party/rust/wgpu-hal/src/dx12/mod.rs
index 13b43f8aca..4f958943ca 100644
--- a/third_party/rust/wgpu-hal/src/dx12/mod.rs
+++ b/third_party/rust/wgpu-hal/src/dx12/mod.rs
@@ -639,7 +639,9 @@ impl SwapChain {
}
}
-impl crate::Surface<Api> for Surface {
+impl crate::Surface for Surface {
+ type A = Api;
+
unsafe fn configure(
&self,
device: &Device,
@@ -884,7 +886,9 @@ impl crate::Surface<Api> for Surface {
}
}
-impl crate::Queue<Api> for Queue {
+impl crate::Queue for Queue {
+ type A = Api;
+
unsafe fn submit(
&self,
command_buffers: &[&CommandBuffer],
diff --git a/third_party/rust/wgpu-hal/src/empty.rs b/third_party/rust/wgpu-hal/src/empty.rs
index d58e779b96..ad00da1b7f 100644
--- a/third_party/rust/wgpu-hal/src/empty.rs
+++ b/third_party/rust/wgpu-hal/src/empty.rs
@@ -39,7 +39,9 @@ impl crate::Api for Api {
type ComputePipeline = Resource;
}
-impl crate::Instance<Api> for Context {
+impl crate::Instance for Context {
+ type A = Api;
+
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
Ok(Context)
}
@@ -56,7 +58,9 @@ impl crate::Instance<Api> for Context {
}
}
-impl crate::Surface<Api> for Context {
+impl crate::Surface for Context {
+ type A = Api;
+
unsafe fn configure(
&self,
device: &Context,
@@ -76,7 +80,9 @@ impl crate::Surface<Api> for Context {
unsafe fn discard_texture(&self, texture: Resource) {}
}
-impl crate::Adapter<Api> for Context {
+impl crate::Adapter for Context {
+ type A = Api;
+
unsafe fn open(
&self,
features: wgt::Features,
@@ -100,7 +106,9 @@ impl crate::Adapter<Api> for Context {
}
}
-impl crate::Queue<Api> for Context {
+impl crate::Queue for Context {
+ type A = Api;
+
unsafe fn submit(
&self,
command_buffers: &[&Resource],
@@ -122,7 +130,9 @@ impl crate::Queue<Api> for Context {
}
}
-impl crate::Device<Api> for Context {
+impl crate::Device for Context {
+ type A = Api;
+
unsafe fn exit(self, queue: Context) {}
unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult<Resource> {
Ok(Resource)
@@ -259,7 +269,9 @@ impl crate::Device<Api> for Context {
unsafe fn destroy_acceleration_structure(&self, _acceleration_structure: Resource) {}
}
-impl crate::CommandEncoder<Api> for Encoder {
+impl crate::CommandEncoder for Encoder {
+ type A = Api;
+
unsafe fn begin_encoding(&mut self, label: crate::Label) -> DeviceResult<()> {
Ok(())
}
diff --git a/third_party/rust/wgpu-hal/src/gles/adapter.rs b/third_party/rust/wgpu-hal/src/gles/adapter.rs
index c09725e85f..b9d044337c 100644
--- a/third_party/rust/wgpu-hal/src/gles/adapter.rs
+++ b/third_party/rust/wgpu-hal/src/gles/adapter.rs
@@ -922,7 +922,9 @@ impl super::Adapter {
}
}
-impl crate::Adapter<super::Api> for super::Adapter {
+impl crate::Adapter for super::Adapter {
+ type A = super::Api;
+
unsafe fn open(
&self,
features: wgt::Features,
diff --git a/third_party/rust/wgpu-hal/src/gles/command.rs b/third_party/rust/wgpu-hal/src/gles/command.rs
index 4385e2a31e..258dee76e5 100644
--- a/third_party/rust/wgpu-hal/src/gles/command.rs
+++ b/third_party/rust/wgpu-hal/src/gles/command.rs
@@ -250,7 +250,9 @@ impl super::CommandEncoder {
}
}
-impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
+impl crate::CommandEncoder for super::CommandEncoder {
+ type A = super::Api;
+
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
self.state = State::default();
self.cmd_buffer.label = label.map(str::to_string);
diff --git a/third_party/rust/wgpu-hal/src/gles/device.rs b/third_party/rust/wgpu-hal/src/gles/device.rs
index 2678488cf8..50c07f3ff0 100644
--- a/third_party/rust/wgpu-hal/src/gles/device.rs
+++ b/third_party/rust/wgpu-hal/src/gles/device.rs
@@ -483,7 +483,9 @@ impl super::Device {
}
}
-impl crate::Device<super::Api> for super::Device {
+impl crate::Device for super::Device {
+ type A = super::Api;
+
unsafe fn exit(self, queue: super::Queue) {
let gl = &self.shared.context.lock();
unsafe { gl.delete_vertex_array(self.main_vao) };
@@ -1123,8 +1125,10 @@ impl crate::Device<super::Api> for super::Device {
!0;
bg_layout
.entries
- .last()
- .map_or(0, |b| b.binding as usize + 1)
+ .iter()
+ .map(|b| b.binding)
+ .max()
+ .map_or(0, |idx| idx as usize + 1)
]
.into_boxed_slice();
@@ -1177,7 +1181,16 @@ impl crate::Device<super::Api> for super::Device {
) -> Result<super::BindGroup, crate::DeviceError> {
let mut contents = Vec::new();
- for (entry, layout) in desc.entries.iter().zip(desc.layout.entries.iter()) {
+ let layout_and_entry_iter = desc.entries.iter().map(|entry| {
+ let layout = desc
+ .layout
+ .entries
+ .iter()
+ .find(|layout_entry| layout_entry.binding == entry.binding)
+ .expect("internal error: no layout entry found with binding slot");
+ (entry, layout)
+ });
+ for (entry, layout) in layout_and_entry_iter {
let binding = match layout.ty {
wgt::BindingType::Buffer { .. } => {
let bb = &desc.buffers[entry.resource_index as usize];
diff --git a/third_party/rust/wgpu-hal/src/gles/egl.rs b/third_party/rust/wgpu-hal/src/gles/egl.rs
index f4bfcf5487..b166f4f102 100644
--- a/third_party/rust/wgpu-hal/src/gles/egl.rs
+++ b/third_party/rust/wgpu-hal/src/gles/egl.rs
@@ -703,7 +703,9 @@ impl Instance {
unsafe impl Send for Instance {}
unsafe impl Sync for Instance {}
-impl crate::Instance<super::Api> for Instance {
+impl crate::Instance for Instance {
+ type A = super::Api;
+
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init OpenGL (EGL) Backend");
#[cfg(Emscripten)]
@@ -1165,7 +1167,9 @@ impl Surface {
}
}
-impl crate::Surface<super::Api> for Surface {
+impl crate::Surface for Surface {
+ type A = super::Api;
+
unsafe fn configure(
&self,
device: &super::Device,
diff --git a/third_party/rust/wgpu-hal/src/gles/queue.rs b/third_party/rust/wgpu-hal/src/gles/queue.rs
index 5db5af9a16..29dfb79d04 100644
--- a/third_party/rust/wgpu-hal/src/gles/queue.rs
+++ b/third_party/rust/wgpu-hal/src/gles/queue.rs
@@ -1748,7 +1748,9 @@ impl super::Queue {
}
}
-impl crate::Queue<super::Api> for super::Queue {
+impl crate::Queue for super::Queue {
+ type A = super::Api;
+
unsafe fn submit(
&self,
command_buffers: &[&super::CommandBuffer],
diff --git a/third_party/rust/wgpu-hal/src/gles/web.rs b/third_party/rust/wgpu-hal/src/gles/web.rs
index 797d6f91d7..ab2ccef8b6 100644
--- a/third_party/rust/wgpu-hal/src/gles/web.rs
+++ b/third_party/rust/wgpu-hal/src/gles/web.rs
@@ -116,7 +116,9 @@ unsafe impl Sync for Instance {}
#[cfg(send_sync)]
unsafe impl Send for Instance {}
-impl crate::Instance<super::Api> for Instance {
+impl crate::Instance for Instance {
+ type A = super::Api;
+
unsafe fn init(_desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init OpenGL (WebGL) Backend");
Ok(Instance {
@@ -309,7 +311,9 @@ impl Surface {
}
}
-impl crate::Surface<super::Api> for Surface {
+impl crate::Surface for Surface {
+ type A = super::Api;
+
unsafe fn configure(
&self,
device: &super::Device,
diff --git a/third_party/rust/wgpu-hal/src/gles/wgl.rs b/third_party/rust/wgpu-hal/src/gles/wgl.rs
index c9039090b7..2564892969 100644
--- a/third_party/rust/wgpu-hal/src/gles/wgl.rs
+++ b/third_party/rust/wgpu-hal/src/gles/wgl.rs
@@ -422,7 +422,9 @@ fn create_instance_device() -> Result<InstanceDevice, crate::InstanceError> {
Ok(InstanceDevice { dc, _tx: drop_tx })
}
-impl crate::Instance<super::Api> for Instance {
+impl crate::Instance for Instance {
+ type A = super::Api;
+
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init OpenGL (WGL) Backend");
let opengl_module = unsafe { LoadLibraryA("opengl32.dll\0".as_ptr() as *const _) };
@@ -676,7 +678,9 @@ impl Surface {
}
}
-impl crate::Surface<super::Api> for Surface {
+impl crate::Surface for Surface {
+ type A = super::Api;
+
unsafe fn configure(
&self,
device: &super::Device,
diff --git a/third_party/rust/wgpu-hal/src/lib.rs b/third_party/rust/wgpu-hal/src/lib.rs
index f1794a4a89..79bd54e66e 100644
--- a/third_party/rust/wgpu-hal/src/lib.rs
+++ b/third_party/rust/wgpu-hal/src/lib.rs
@@ -191,13 +191,13 @@ impl InstanceError {
}
pub trait Api: Clone + fmt::Debug + Sized {
- type Instance: Instance<Self>;
- type Surface: Surface<Self>;
- type Adapter: Adapter<Self>;
- type Device: Device<Self>;
+ type Instance: Instance<A = Self>;
+ type Surface: Surface<A = Self>;
+ type Adapter: Adapter<A = Self>;
+ type Device: Device<A = Self>;
- type Queue: Queue<Self>;
- type CommandEncoder: CommandEncoder<Self>;
+ type Queue: Queue<A = Self>;
+ type CommandEncoder: CommandEncoder<A = Self>;
type CommandBuffer: WasmNotSendSync + fmt::Debug;
type Buffer: fmt::Debug + WasmNotSendSync + 'static;
@@ -218,18 +218,22 @@ pub trait Api: Clone + fmt::Debug + Sized {
type AccelerationStructure: fmt::Debug + WasmNotSendSync + 'static;
}
-pub trait Instance<A: Api>: Sized + WasmNotSendSync {
+pub trait Instance: Sized + WasmNotSendSync {
+ type A: Api;
+
unsafe fn init(desc: &InstanceDescriptor) -> Result<Self, InstanceError>;
unsafe fn create_surface(
&self,
display_handle: raw_window_handle::RawDisplayHandle,
window_handle: raw_window_handle::RawWindowHandle,
- ) -> Result<A::Surface, InstanceError>;
- unsafe fn destroy_surface(&self, surface: A::Surface);
- unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<A>>;
+ ) -> Result<<Self::A as Api>::Surface, InstanceError>;
+ unsafe fn destroy_surface(&self, surface: <Self::A as Api>::Surface);
+ unsafe fn enumerate_adapters(&self) -> Vec<ExposedAdapter<Self::A>>;
}
-pub trait Surface<A: Api>: WasmNotSendSync {
+pub trait Surface: WasmNotSendSync {
+ type A: Api;
+
/// Configures the surface to use the given device.
///
/// # Safety
@@ -240,7 +244,7 @@ pub trait Surface<A: Api>: WasmNotSendSync {
/// - All surfaces created using other devices must have been unconfigured before this call.
unsafe fn configure(
&self,
- device: &A::Device,
+ device: &<Self::A as Api>::Device,
config: &SurfaceConfiguration,
) -> Result<(), SurfaceError>;
@@ -252,7 +256,7 @@ pub trait Surface<A: Api>: WasmNotSendSync {
/// - All [`AcquiredSurfaceTexture`]s must have been destroyed.
/// - All [`Api::TextureView`]s derived from the [`AcquiredSurfaceTexture`]s must have been destroyed.
/// - The surface must have been configured on the given device.
- unsafe fn unconfigure(&self, device: &A::Device);
+ unsafe fn unconfigure(&self, device: &<Self::A as Api>::Device);
/// Returns the next texture to be presented by the swapchain for drawing
///
@@ -267,16 +271,18 @@ pub trait Surface<A: Api>: WasmNotSendSync {
unsafe fn acquire_texture(
&self,
timeout: Option<std::time::Duration>,
- ) -> Result<Option<AcquiredSurfaceTexture<A>>, SurfaceError>;
- unsafe fn discard_texture(&self, texture: A::SurfaceTexture);
+ ) -> Result<Option<AcquiredSurfaceTexture<Self::A>>, SurfaceError>;
+ unsafe fn discard_texture(&self, texture: <Self::A as Api>::SurfaceTexture);
}
-pub trait Adapter<A: Api>: WasmNotSendSync {
+pub trait Adapter: WasmNotSendSync {
+ type A: Api;
+
unsafe fn open(
&self,
features: wgt::Features,
limits: &wgt::Limits,
- ) -> Result<OpenDevice<A>, DeviceError>;
+ ) -> Result<OpenDevice<Self::A>, DeviceError>;
/// Return the set of supported capabilities for a texture format.
unsafe fn texture_format_capabilities(
@@ -287,7 +293,10 @@ pub trait Adapter<A: Api>: WasmNotSendSync {
/// Returns the capabilities of working with a specified surface.
///
/// `None` means presentation is not supported for it.
- unsafe fn surface_capabilities(&self, surface: &A::Surface) -> Option<SurfaceCapabilities>;
+ unsafe fn surface_capabilities(
+ &self,
+ surface: &<Self::A as Api>::Surface,
+ ) -> Option<SurfaceCapabilities>;
/// Creates a [`PresentationTimestamp`] using the adapter's WSI.
///
@@ -295,97 +304,111 @@ pub trait Adapter<A: Api>: WasmNotSendSync {
unsafe fn get_presentation_timestamp(&self) -> wgt::PresentationTimestamp;
}
-pub trait Device<A: Api>: WasmNotSendSync {
+pub trait Device: WasmNotSendSync {
+ type A: Api;
+
/// Exit connection to this logical device.
- unsafe fn exit(self, queue: A::Queue);
+ unsafe fn exit(self, queue: <Self::A as Api>::Queue);
/// Creates a new buffer.
///
/// The initial usage is `BufferUses::empty()`.
- unsafe fn create_buffer(&self, desc: &BufferDescriptor) -> Result<A::Buffer, DeviceError>;
- unsafe fn destroy_buffer(&self, buffer: A::Buffer);
+ unsafe fn create_buffer(
+ &self,
+ desc: &BufferDescriptor,
+ ) -> Result<<Self::A as Api>::Buffer, DeviceError>;
+ unsafe fn destroy_buffer(&self, buffer: <Self::A as Api>::Buffer);
//TODO: clarify if zero-sized mapping is allowed
unsafe fn map_buffer(
&self,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
range: MemoryRange,
) -> Result<BufferMapping, DeviceError>;
- unsafe fn unmap_buffer(&self, buffer: &A::Buffer) -> Result<(), DeviceError>;
- unsafe fn flush_mapped_ranges<I>(&self, buffer: &A::Buffer, ranges: I)
+ unsafe fn unmap_buffer(&self, buffer: &<Self::A as Api>::Buffer) -> Result<(), DeviceError>;
+ unsafe fn flush_mapped_ranges<I>(&self, buffer: &<Self::A as Api>::Buffer, ranges: I)
where
I: Iterator<Item = MemoryRange>;
- unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &A::Buffer, ranges: I)
+ unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &<Self::A as Api>::Buffer, ranges: I)
where
I: Iterator<Item = MemoryRange>;
/// Creates a new texture.
///
/// The initial usage for all subresources is `TextureUses::UNINITIALIZED`.
- unsafe fn create_texture(&self, desc: &TextureDescriptor) -> Result<A::Texture, DeviceError>;
- unsafe fn destroy_texture(&self, texture: A::Texture);
+ unsafe fn create_texture(
+ &self,
+ desc: &TextureDescriptor,
+ ) -> Result<<Self::A as Api>::Texture, DeviceError>;
+ unsafe fn destroy_texture(&self, texture: <Self::A as Api>::Texture);
unsafe fn create_texture_view(
&self,
- texture: &A::Texture,
+ texture: &<Self::A as Api>::Texture,
desc: &TextureViewDescriptor,
- ) -> Result<A::TextureView, DeviceError>;
- unsafe fn destroy_texture_view(&self, view: A::TextureView);
- unsafe fn create_sampler(&self, desc: &SamplerDescriptor) -> Result<A::Sampler, DeviceError>;
- unsafe fn destroy_sampler(&self, sampler: A::Sampler);
+ ) -> Result<<Self::A as Api>::TextureView, DeviceError>;
+ unsafe fn destroy_texture_view(&self, view: <Self::A as Api>::TextureView);
+ unsafe fn create_sampler(
+ &self,
+ desc: &SamplerDescriptor,
+ ) -> Result<<Self::A as Api>::Sampler, DeviceError>;
+ unsafe fn destroy_sampler(&self, sampler: <Self::A as Api>::Sampler);
/// Create a fresh [`CommandEncoder`].
///
/// The new `CommandEncoder` is in the "closed" state.
unsafe fn create_command_encoder(
&self,
- desc: &CommandEncoderDescriptor<A>,
- ) -> Result<A::CommandEncoder, DeviceError>;
- unsafe fn destroy_command_encoder(&self, pool: A::CommandEncoder);
+ desc: &CommandEncoderDescriptor<Self::A>,
+ ) -> Result<<Self::A as Api>::CommandEncoder, DeviceError>;
+ unsafe fn destroy_command_encoder(&self, pool: <Self::A as Api>::CommandEncoder);
/// Creates a bind group layout.
unsafe fn create_bind_group_layout(
&self,
desc: &BindGroupLayoutDescriptor,
- ) -> Result<A::BindGroupLayout, DeviceError>;
- unsafe fn destroy_bind_group_layout(&self, bg_layout: A::BindGroupLayout);
+ ) -> Result<<Self::A as Api>::BindGroupLayout, DeviceError>;
+ unsafe fn destroy_bind_group_layout(&self, bg_layout: <Self::A as Api>::BindGroupLayout);
unsafe fn create_pipeline_layout(
&self,
- desc: &PipelineLayoutDescriptor<A>,
- ) -> Result<A::PipelineLayout, DeviceError>;
- unsafe fn destroy_pipeline_layout(&self, pipeline_layout: A::PipelineLayout);
+ desc: &PipelineLayoutDescriptor<Self::A>,
+ ) -> Result<<Self::A as Api>::PipelineLayout, DeviceError>;
+ unsafe fn destroy_pipeline_layout(&self, pipeline_layout: <Self::A as Api>::PipelineLayout);
unsafe fn create_bind_group(
&self,
- desc: &BindGroupDescriptor<A>,
- ) -> Result<A::BindGroup, DeviceError>;
- unsafe fn destroy_bind_group(&self, group: A::BindGroup);
+ desc: &BindGroupDescriptor<Self::A>,
+ ) -> Result<<Self::A as Api>::BindGroup, DeviceError>;
+ unsafe fn destroy_bind_group(&self, group: <Self::A as Api>::BindGroup);
unsafe fn create_shader_module(
&self,
desc: &ShaderModuleDescriptor,
shader: ShaderInput,
- ) -> Result<A::ShaderModule, ShaderError>;
- unsafe fn destroy_shader_module(&self, module: A::ShaderModule);
+ ) -> Result<<Self::A as Api>::ShaderModule, ShaderError>;
+ unsafe fn destroy_shader_module(&self, module: <Self::A as Api>::ShaderModule);
unsafe fn create_render_pipeline(
&self,
- desc: &RenderPipelineDescriptor<A>,
- ) -> Result<A::RenderPipeline, PipelineError>;
- unsafe fn destroy_render_pipeline(&self, pipeline: A::RenderPipeline);
+ desc: &RenderPipelineDescriptor<Self::A>,
+ ) -> Result<<Self::A as Api>::RenderPipeline, PipelineError>;
+ unsafe fn destroy_render_pipeline(&self, pipeline: <Self::A as Api>::RenderPipeline);
unsafe fn create_compute_pipeline(
&self,
- desc: &ComputePipelineDescriptor<A>,
- ) -> Result<A::ComputePipeline, PipelineError>;
- unsafe fn destroy_compute_pipeline(&self, pipeline: A::ComputePipeline);
+ desc: &ComputePipelineDescriptor<Self::A>,
+ ) -> Result<<Self::A as Api>::ComputePipeline, PipelineError>;
+ unsafe fn destroy_compute_pipeline(&self, pipeline: <Self::A as Api>::ComputePipeline);
unsafe fn create_query_set(
&self,
desc: &wgt::QuerySetDescriptor<Label>,
- ) -> Result<A::QuerySet, DeviceError>;
- unsafe fn destroy_query_set(&self, set: A::QuerySet);
- unsafe fn create_fence(&self) -> Result<A::Fence, DeviceError>;
- unsafe fn destroy_fence(&self, fence: A::Fence);
- unsafe fn get_fence_value(&self, fence: &A::Fence) -> Result<FenceValue, DeviceError>;
+ ) -> Result<<Self::A as Api>::QuerySet, DeviceError>;
+ unsafe fn destroy_query_set(&self, set: <Self::A as Api>::QuerySet);
+ unsafe fn create_fence(&self) -> Result<<Self::A as Api>::Fence, DeviceError>;
+ unsafe fn destroy_fence(&self, fence: <Self::A as Api>::Fence);
+ unsafe fn get_fence_value(
+ &self,
+ fence: &<Self::A as Api>::Fence,
+ ) -> Result<FenceValue, DeviceError>;
/// Calling wait with a lower value than the current fence value will immediately return.
unsafe fn wait(
&self,
- fence: &A::Fence,
+ fence: &<Self::A as Api>::Fence,
value: FenceValue,
timeout_ms: u32,
) -> Result<bool, DeviceError>;
@@ -396,22 +419,24 @@ pub trait Device<A: Api>: WasmNotSendSync {
unsafe fn create_acceleration_structure(
&self,
desc: &AccelerationStructureDescriptor,
- ) -> Result<A::AccelerationStructure, DeviceError>;
+ ) -> Result<<Self::A as Api>::AccelerationStructure, DeviceError>;
unsafe fn get_acceleration_structure_build_sizes(
&self,
- desc: &GetAccelerationStructureBuildSizesDescriptor<A>,
+ desc: &GetAccelerationStructureBuildSizesDescriptor<Self::A>,
) -> AccelerationStructureBuildSizes;
unsafe fn get_acceleration_structure_device_address(
&self,
- acceleration_structure: &A::AccelerationStructure,
+ acceleration_structure: &<Self::A as Api>::AccelerationStructure,
) -> wgt::BufferAddress;
unsafe fn destroy_acceleration_structure(
&self,
- acceleration_structure: A::AccelerationStructure,
+ acceleration_structure: <Self::A as Api>::AccelerationStructure,
);
}
-pub trait Queue<A: Api>: WasmNotSendSync {
+pub trait Queue: WasmNotSendSync {
+ type A: Api;
+
/// Submits the command buffers for execution on GPU.
///
/// Valid usage:
@@ -422,14 +447,14 @@ pub trait Queue<A: Api>: WasmNotSendSync {
/// passed to the surface_textures argument.
unsafe fn submit(
&self,
- command_buffers: &[&A::CommandBuffer],
- surface_textures: &[&A::SurfaceTexture],
- signal_fence: Option<(&mut A::Fence, FenceValue)>,
+ command_buffers: &[&<Self::A as Api>::CommandBuffer],
+ surface_textures: &[&<Self::A as Api>::SurfaceTexture],
+ signal_fence: Option<(&mut <Self::A as Api>::Fence, FenceValue)>,
) -> Result<(), DeviceError>;
unsafe fn present(
&self,
- surface: &A::Surface,
- texture: A::SurfaceTexture,
+ surface: &<Self::A as Api>::Surface,
+ texture: <Self::A as Api>::SurfaceTexture,
) -> Result<(), SurfaceError>;
unsafe fn get_timestamp_period(&self) -> f32;
}
@@ -472,7 +497,9 @@ pub trait Queue<A: Api>: WasmNotSendSync {
/// built it.
///
/// - A `CommandEncoder` must not outlive its `Device`.
-pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
+pub trait CommandEncoder: WasmNotSendSync + fmt::Debug {
+ type A: Api;
+
/// Begin encoding a new command buffer.
///
/// This puts this `CommandEncoder` in the "recording" state.
@@ -510,7 +537,7 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
///
/// [`CommandBuffer`]: Api::CommandBuffer
/// [`begin_encoding`]: CommandEncoder::begin_encoding
- unsafe fn end_encoding(&mut self) -> Result<A::CommandBuffer, DeviceError>;
+ unsafe fn end_encoding(&mut self) -> Result<<Self::A as Api>::CommandBuffer, DeviceError>;
/// Reclaim all resources belonging to this `CommandEncoder`.
///
@@ -525,22 +552,26 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// [`CommandBuffer`]: Api::CommandBuffer
unsafe fn reset_all<I>(&mut self, command_buffers: I)
where
- I: Iterator<Item = A::CommandBuffer>;
+ I: Iterator<Item = <Self::A as Api>::CommandBuffer>;
unsafe fn transition_buffers<'a, T>(&mut self, barriers: T)
where
- T: Iterator<Item = BufferBarrier<'a, A>>;
+ T: Iterator<Item = BufferBarrier<'a, Self::A>>;
unsafe fn transition_textures<'a, T>(&mut self, barriers: T)
where
- T: Iterator<Item = TextureBarrier<'a, A>>;
+ T: Iterator<Item = TextureBarrier<'a, Self::A>>;
// copy operations
- unsafe fn clear_buffer(&mut self, buffer: &A::Buffer, range: MemoryRange);
+ unsafe fn clear_buffer(&mut self, buffer: &<Self::A as Api>::Buffer, range: MemoryRange);
- unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &A::Buffer, dst: &A::Buffer, regions: T)
- where
+ unsafe fn copy_buffer_to_buffer<T>(
+ &mut self,
+ src: &<Self::A as Api>::Buffer,
+ dst: &<Self::A as Api>::Buffer,
+ regions: T,
+ ) where
T: Iterator<Item = BufferCopy>;
/// Copy from an external image to an internal texture.
@@ -551,7 +582,7 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
unsafe fn copy_external_image_to_texture<T>(
&mut self,
src: &wgt::ImageCopyExternalImage,
- dst: &A::Texture,
+ dst: &<Self::A as Api>::Texture,
dst_premultiplication: bool,
regions: T,
) where
@@ -563,9 +594,9 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// Note: the copy extent is in physical size (rounded to the block size)
unsafe fn copy_texture_to_texture<T>(
&mut self,
- src: &A::Texture,
+ src: &<Self::A as Api>::Texture,
src_usage: TextureUses,
- dst: &A::Texture,
+ dst: &<Self::A as Api>::Texture,
regions: T,
) where
T: Iterator<Item = TextureCopy>;
@@ -574,8 +605,12 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// Works with a single array layer.
/// Note: `dst` current usage has to be `TextureUses::COPY_DST`.
/// Note: the copy extent is in physical size (rounded to the block size)
- unsafe fn copy_buffer_to_texture<T>(&mut self, src: &A::Buffer, dst: &A::Texture, regions: T)
- where
+ unsafe fn copy_buffer_to_texture<T>(
+ &mut self,
+ src: &<Self::A as Api>::Buffer,
+ dst: &<Self::A as Api>::Texture,
+ regions: T,
+ ) where
T: Iterator<Item = BufferTextureCopy>;
/// Copy from texture to buffer.
@@ -583,9 +618,9 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// Note: the copy extent is in physical size (rounded to the block size)
unsafe fn copy_texture_to_buffer<T>(
&mut self,
- src: &A::Texture,
+ src: &<Self::A as Api>::Texture,
src_usage: TextureUses,
- dst: &A::Buffer,
+ dst: &<Self::A as Api>::Buffer,
regions: T,
) where
T: Iterator<Item = BufferTextureCopy>;
@@ -596,9 +631,9 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// of all the preceding groups to be taken from `layout`.
unsafe fn set_bind_group(
&mut self,
- layout: &A::PipelineLayout,
+ layout: &<Self::A as Api>::PipelineLayout,
index: u32,
- group: &A::BindGroup,
+ group: &<Self::A as Api>::BindGroup,
dynamic_offsets: &[wgt::DynamicOffset],
);
@@ -612,7 +647,7 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// - The range of push constants written must be valid for the pipeline layout at draw time.
unsafe fn set_push_constants(
&mut self,
- layout: &A::PipelineLayout,
+ layout: &<Self::A as Api>::PipelineLayout,
stages: wgt::ShaderStages,
offset_bytes: u32,
data: &[u32],
@@ -627,18 +662,18 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
/// # Safety:
///
/// - If `set` is an occlusion query set, it must be the same one as used in the [`RenderPassDescriptor::occlusion_query_set`] parameter.
- unsafe fn begin_query(&mut self, set: &A::QuerySet, index: u32);
+ unsafe fn begin_query(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
/// # Safety:
///
/// - If `set` is an occlusion query set, it must be the same one as used in the [`RenderPassDescriptor::occlusion_query_set`] parameter.
- unsafe fn end_query(&mut self, set: &A::QuerySet, index: u32);
- unsafe fn write_timestamp(&mut self, set: &A::QuerySet, index: u32);
- unsafe fn reset_queries(&mut self, set: &A::QuerySet, range: Range<u32>);
+ unsafe fn end_query(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
+ unsafe fn write_timestamp(&mut self, set: &<Self::A as Api>::QuerySet, index: u32);
+ unsafe fn reset_queries(&mut self, set: &<Self::A as Api>::QuerySet, range: Range<u32>);
unsafe fn copy_query_results(
&mut self,
- set: &A::QuerySet,
+ set: &<Self::A as Api>::QuerySet,
range: Range<u32>,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
offset: wgt::BufferAddress,
stride: wgt::BufferSize,
);
@@ -646,17 +681,17 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
// render passes
// Begins a render pass, clears all active bindings.
- unsafe fn begin_render_pass(&mut self, desc: &RenderPassDescriptor<A>);
+ unsafe fn begin_render_pass(&mut self, desc: &RenderPassDescriptor<Self::A>);
unsafe fn end_render_pass(&mut self);
- unsafe fn set_render_pipeline(&mut self, pipeline: &A::RenderPipeline);
+ unsafe fn set_render_pipeline(&mut self, pipeline: &<Self::A as Api>::RenderPipeline);
unsafe fn set_index_buffer<'a>(
&mut self,
- binding: BufferBinding<'a, A>,
+ binding: BufferBinding<'a, Self::A>,
format: wgt::IndexFormat,
);
- unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: BufferBinding<'a, A>);
+ unsafe fn set_vertex_buffer<'a>(&mut self, index: u32, binding: BufferBinding<'a, Self::A>);
unsafe fn set_viewport(&mut self, rect: &Rect<f32>, depth_range: Range<f32>);
unsafe fn set_scissor_rect(&mut self, rect: &Rect<u32>);
unsafe fn set_stencil_reference(&mut self, value: u32);
@@ -679,29 +714,29 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
);
unsafe fn draw_indirect(
&mut self,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
offset: wgt::BufferAddress,
draw_count: u32,
);
unsafe fn draw_indexed_indirect(
&mut self,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
offset: wgt::BufferAddress,
draw_count: u32,
);
unsafe fn draw_indirect_count(
&mut self,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
offset: wgt::BufferAddress,
- count_buffer: &A::Buffer,
+ count_buffer: &<Self::A as Api>::Buffer,
count_offset: wgt::BufferAddress,
max_count: u32,
);
unsafe fn draw_indexed_indirect_count(
&mut self,
- buffer: &A::Buffer,
+ buffer: &<Self::A as Api>::Buffer,
offset: wgt::BufferAddress,
- count_buffer: &A::Buffer,
+ count_buffer: &<Self::A as Api>::Buffer,
count_offset: wgt::BufferAddress,
max_count: u32,
);
@@ -709,13 +744,17 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
// compute passes
// Begins a compute pass, clears all active bindings.
- unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<A>);
+ unsafe fn begin_compute_pass(&mut self, desc: &ComputePassDescriptor<Self::A>);
unsafe fn end_compute_pass(&mut self);
- unsafe fn set_compute_pipeline(&mut self, pipeline: &A::ComputePipeline);
+ unsafe fn set_compute_pipeline(&mut self, pipeline: &<Self::A as Api>::ComputePipeline);
unsafe fn dispatch(&mut self, count: [u32; 3]);
- unsafe fn dispatch_indirect(&mut self, buffer: &A::Buffer, offset: wgt::BufferAddress);
+ unsafe fn dispatch_indirect(
+ &mut self,
+ buffer: &<Self::A as Api>::Buffer,
+ offset: wgt::BufferAddress,
+ );
/// To get the required sizes for the buffer allocations use `get_acceleration_structure_build_sizes` per descriptor
/// All buffers must be synchronized externally
@@ -729,8 +768,8 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {
descriptor_count: u32,
descriptors: T,
) where
- A: 'a,
- T: IntoIterator<Item = BuildAccelerationStructureDescriptor<'a, A>>;
+ Self::A: 'a,
+ T: IntoIterator<Item = BuildAccelerationStructureDescriptor<'a, Self::A>>;
unsafe fn place_acceleration_structure_barrier(
&mut self,
diff --git a/third_party/rust/wgpu-hal/src/metal/adapter.rs b/third_party/rust/wgpu-hal/src/metal/adapter.rs
index 9ec777b0f0..6211896838 100644
--- a/third_party/rust/wgpu-hal/src/metal/adapter.rs
+++ b/third_party/rust/wgpu-hal/src/metal/adapter.rs
@@ -18,7 +18,9 @@ impl super::Adapter {
}
}
-impl crate::Adapter<super::Api> for super::Adapter {
+impl crate::Adapter for super::Adapter {
+ type A = super::Api;
+
unsafe fn open(
&self,
features: wgt::Features,
diff --git a/third_party/rust/wgpu-hal/src/metal/command.rs b/third_party/rust/wgpu-hal/src/metal/command.rs
index 6f1a0d9c2f..341712c323 100644
--- a/third_party/rust/wgpu-hal/src/metal/command.rs
+++ b/third_party/rust/wgpu-hal/src/metal/command.rs
@@ -168,7 +168,9 @@ impl super::CommandState {
}
}
-impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
+impl crate::CommandEncoder for super::CommandEncoder {
+ type A = super::Api;
+
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
let queue = &self.raw_queue.lock();
let retain_references = self.shared.settings.retain_command_buffer_references;
diff --git a/third_party/rust/wgpu-hal/src/metal/device.rs b/third_party/rust/wgpu-hal/src/metal/device.rs
index d7fd06c8f3..179429f5d7 100644
--- a/third_party/rust/wgpu-hal/src/metal/device.rs
+++ b/third_party/rust/wgpu-hal/src/metal/device.rs
@@ -273,7 +273,9 @@ impl super::Device {
}
}
-impl crate::Device<super::Api> for super::Device {
+impl crate::Device for super::Device {
+ type A = super::Api;
+
unsafe fn exit(self, _queue: super::Queue) {}
unsafe fn create_buffer(&self, desc: &crate::BufferDescriptor) -> DeviceResult<super::Buffer> {
@@ -706,7 +708,16 @@ impl crate::Device<super::Api> for super::Device {
for (&stage, counter) in super::NAGA_STAGES.iter().zip(bg.counters.iter_mut()) {
let stage_bit = map_naga_stage(stage);
let mut dynamic_offsets_count = 0u32;
- for (entry, layout) in desc.entries.iter().zip(desc.layout.entries.iter()) {
+ let layout_and_entry_iter = desc.entries.iter().map(|entry| {
+ let layout = desc
+ .layout
+ .entries
+ .iter()
+ .find(|layout_entry| layout_entry.binding == entry.binding)
+ .expect("internal error: no layout entry found with binding slot");
+ (entry, layout)
+ });
+ for (entry, layout) in layout_and_entry_iter {
let size = layout.count.map_or(1, |c| c.get());
if let wgt::BindingType::Buffer {
has_dynamic_offset: true,
diff --git a/third_party/rust/wgpu-hal/src/metal/mod.rs b/third_party/rust/wgpu-hal/src/metal/mod.rs
index 62fbf3d49d..6aeafb0f86 100644
--- a/third_party/rust/wgpu-hal/src/metal/mod.rs
+++ b/third_party/rust/wgpu-hal/src/metal/mod.rs
@@ -80,7 +80,9 @@ impl Instance {
}
}
-impl crate::Instance<Api> for Instance {
+impl crate::Instance for Instance {
+ type A = Api;
+
unsafe fn init(_desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init Metal Backend");
// We do not enable metal validation based on the validation flags as it affects the entire
@@ -365,7 +367,9 @@ impl std::borrow::Borrow<Texture> for SurfaceTexture {
unsafe impl Send for SurfaceTexture {}
unsafe impl Sync for SurfaceTexture {}
-impl crate::Queue<Api> for Queue {
+impl crate::Queue for Queue {
+ type A = Api;
+
unsafe fn submit(
&self,
command_buffers: &[&CommandBuffer],
diff --git a/third_party/rust/wgpu-hal/src/metal/surface.rs b/third_party/rust/wgpu-hal/src/metal/surface.rs
index a97eff0aae..889e319493 100644
--- a/third_party/rust/wgpu-hal/src/metal/surface.rs
+++ b/third_party/rust/wgpu-hal/src/metal/surface.rs
@@ -169,7 +169,9 @@ impl super::Surface {
}
}
-impl crate::Surface<super::Api> for super::Surface {
+impl crate::Surface for super::Surface {
+ type A = super::Api;
+
unsafe fn configure(
&self,
device: &super::Device,
diff --git a/third_party/rust/wgpu-hal/src/vulkan/adapter.rs b/third_party/rust/wgpu-hal/src/vulkan/adapter.rs
index 83b3dfa8e5..2665463792 100644
--- a/third_party/rust/wgpu-hal/src/vulkan/adapter.rs
+++ b/third_party/rust/wgpu-hal/src/vulkan/adapter.rs
@@ -20,25 +20,85 @@ fn indexing_features() -> wgt::Features {
| wgt::Features::PARTIALLY_BOUND_BINDING_ARRAY
}
-/// Aggregate of the `vk::PhysicalDevice*Features` structs used by `gfx`.
+/// Features supported by a [`vk::PhysicalDevice`] and its extensions.
+///
+/// This is used in two phases:
+///
+/// - When enumerating adapters, this represents the features offered by the
+/// adapter. [`Instance::expose_adapter`] calls `vkGetPhysicalDeviceFeatures2`
+/// (or `vkGetPhysicalDeviceFeatures` if that is not available) to collect
+/// this information about the `VkPhysicalDevice` represented by the
+/// `wgpu_hal::ExposedAdapter`.
+///
+/// - When opening a device, this represents the features we would like to
+/// enable. At `wgpu_hal::Device` construction time,
+/// [`PhysicalDeviceFeatures::from_extensions_and_requested_features`]
+/// constructs an value of this type indicating which Vulkan features to
+/// enable, based on the `wgpu_types::Features` requested.
#[derive(Debug, Default)]
pub struct PhysicalDeviceFeatures {
+ /// Basic Vulkan 1.0 features.
core: vk::PhysicalDeviceFeatures,
+
+ /// Features provided by `VK_EXT_descriptor_indexing`, promoted to Vulkan 1.2.
pub(super) descriptor_indexing: Option<vk::PhysicalDeviceDescriptorIndexingFeaturesEXT>,
+
+ /// Features provided by `VK_KHR_imageless_framebuffer`, promoted to Vulkan 1.2.
imageless_framebuffer: Option<vk::PhysicalDeviceImagelessFramebufferFeaturesKHR>,
+
+ /// Features provided by `VK_KHR_timeline_semaphore`, promoted to Vulkan 1.2
timeline_semaphore: Option<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>,
+
+ /// Features provided by `VK_EXT_image_robustness`, promoted to Vulkan 1.3
image_robustness: Option<vk::PhysicalDeviceImageRobustnessFeaturesEXT>,
+
+ /// Features provided by `VK_EXT_robustness2`.
robustness2: Option<vk::PhysicalDeviceRobustness2FeaturesEXT>,
+
+ /// Features provided by `VK_KHR_multiview`, promoted to Vulkan 1.1.
multiview: Option<vk::PhysicalDeviceMultiviewFeaturesKHR>,
+
+ /// Features provided by `VK_KHR_sampler_ycbcr_conversion`, promoted to Vulkan 1.1.
sampler_ycbcr_conversion: Option<vk::PhysicalDeviceSamplerYcbcrConversionFeatures>,
+
+ /// Features provided by `VK_EXT_texture_compression_astc_hdr`, promoted to Vulkan 1.3.
astc_hdr: Option<vk::PhysicalDeviceTextureCompressionASTCHDRFeaturesEXT>,
+
+ /// Features provided by `VK_KHR_shader_float16_int8` (promoted to Vulkan
+ /// 1.2) and `VK_KHR_16bit_storage` (promoted to Vulkan 1.1). We use these
+ /// features together, or not at all.
shader_float16: Option<(
vk::PhysicalDeviceShaderFloat16Int8Features,
vk::PhysicalDevice16BitStorageFeatures,
)>,
+
+ /// Features provided by `VK_KHR_acceleration_structure`.
acceleration_structure: Option<vk::PhysicalDeviceAccelerationStructureFeaturesKHR>,
+
+ /// Features provided by `VK_KHR_buffer_device_address`, promoted to Vulkan 1.2.
+ ///
+ /// We only use this feature for
+ /// [`Features::RAY_TRACING_ACCELERATION_STRUCTURE`], which requires
+ /// `VK_KHR_acceleration_structure`, which depends on
+ /// `VK_KHR_buffer_device_address`, so [`Instance::expose_adapter`] only
+ /// bothers to check if `VK_KHR_acceleration_structure` is available,
+ /// leaving this `None`.
+ ///
+ /// However, we do populate this when creating a device if
+ /// [`Features::RAY_TRACING_ACCELERATION_STRUCTURE`] is requested.
buffer_device_address: Option<vk::PhysicalDeviceBufferDeviceAddressFeaturesKHR>,
+
+ /// Features provided by `VK_KHR_ray_query`,
+ ///
+ /// Vulkan requires that the feature be present if the `VK_KHR_ray_query`
+ /// extension is present, so [`Instance::expose_adapter`] doesn't bother retrieving
+ /// this from `vkGetPhysicalDeviceFeatures2`.
+ ///
+ /// However, we do populate this when creating a device if ray tracing is requested.
ray_query: Option<vk::PhysicalDeviceRayQueryFeaturesKHR>,
+
+ /// Features provided by `VK_KHR_zero_initialize_workgroup_memory`, promoted
+ /// to Vulkan 1.3.
zero_initialize_workgroup_memory:
Option<vk::PhysicalDeviceZeroInitializeWorkgroupMemoryFeatures>,
}
@@ -91,9 +151,32 @@ impl PhysicalDeviceFeatures {
info
}
- /// Create a `PhysicalDeviceFeatures` that will be used to create a logical device.
+ /// Create a `PhysicalDeviceFeatures` that can be used to create a logical
+ /// device.
///
- /// `requested_features` should be the same as what was used to generate `enabled_extensions`.
+ /// Return a `PhysicalDeviceFeatures` value capturing all the Vulkan
+ /// features needed for the given [`Features`], [`DownlevelFlags`], and
+ /// [`PrivateCapabilities`]. You can use the returned value's
+ /// [`add_to_device_create_builder`] method to configure a
+ /// [`DeviceCreateInfoBuilder`] to build a logical device providing those
+ /// features.
+ ///
+ /// To ensure that the returned value is able to select all the Vulkan
+ /// features needed to express `requested_features`, `downlevel_flags`, and
+ /// `private_caps`:
+ ///
+ /// - The given `enabled_extensions` set must include all the extensions
+ /// selected by [`Adapter::required_device_extensions`] when passed
+ /// `features`.
+ ///
+ /// - The given `device_api_version` must be the Vulkan API version of the
+ /// physical device we will use to create the logical device.
+ ///
+ /// [`Features`]: wgt::Features
+ /// [`DownlevelFlags`]: wgt::DownlevelFlags
+ /// [`PrivateCapabilities`]: super::PrivateCapabilities
+ /// [`DeviceCreateInfoBuilder`]: vk::DeviceCreateInfoBuilder
+ /// [`Adapter::required_device_extensions`]: super::Adapter::required_device_extensions
fn from_extensions_and_requested_features(
device_api_version: u32,
enabled_extensions: &[&'static CStr],
@@ -354,11 +437,16 @@ impl PhysicalDeviceFeatures {
}
}
+ /// Compute the wgpu [`Features`] and [`DownlevelFlags`] supported by a physical device.
+ ///
+ /// Given `self`, together with the instance and physical device it was
+ /// built from, and a `caps` also built from those, determine which wgpu
+ /// features and downlevel flags the device can support.
fn to_wgpu(
&self,
instance: &ash::Instance,
phd: vk::PhysicalDevice,
- caps: &PhysicalDeviceCapabilities,
+ caps: &PhysicalDeviceProperties,
) -> (wgt::Features, wgt::DownlevelFlags) {
use crate::auxil::db;
use wgt::{DownlevelFlags as Df, Features as F};
@@ -639,15 +727,52 @@ impl PhysicalDeviceFeatures {
}
}
-/// Information gathered about a physical device capabilities.
+/// Vulkan "properties" structures gathered about a physical device.
+///
+/// This structure holds the properties of a [`vk::PhysicalDevice`]:
+/// - the standard Vulkan device properties
+/// - the `VkExtensionProperties` structs for all available extensions, and
+/// - the per-extension properties structures for the available extensions that
+/// `wgpu` cares about.
+///
+/// Generally, if you get it from any of these functions, it's stored
+/// here:
+/// - `vkEnumerateDeviceExtensionProperties`
+/// - `vkGetPhysicalDeviceProperties`
+/// - `vkGetPhysicalDeviceProperties2`
+///
+/// This also includes a copy of the device API version, since we can
+/// use that as a shortcut for searching for an extension, if the
+/// extension has been promoted to core in the current version.
+///
+/// This does not include device features; for those, see
+/// [`PhysicalDeviceFeatures`].
#[derive(Default, Debug)]
-pub struct PhysicalDeviceCapabilities {
+pub struct PhysicalDeviceProperties {
+ /// Extensions supported by the `vk::PhysicalDevice`,
+ /// as returned by `vkEnumerateDeviceExtensionProperties`.
supported_extensions: Vec<vk::ExtensionProperties>,
+
+ /// Properties of the `vk::PhysicalDevice`, as returned by
+ /// `vkGetPhysicalDeviceProperties`.
properties: vk::PhysicalDeviceProperties,
+
+ /// Additional `vk::PhysicalDevice` properties from the
+ /// `VK_KHR_maintenance3` extension, promoted to Vulkan 1.1.
maintenance_3: Option<vk::PhysicalDeviceMaintenance3Properties>,
+
+ /// Additional `vk::PhysicalDevice` properties from the
+ /// `VK_EXT_descriptor_indexing` extension, promoted to Vulkan 1.2.
descriptor_indexing: Option<vk::PhysicalDeviceDescriptorIndexingPropertiesEXT>,
+
+ /// Additional `vk::PhysicalDevice` properties from the
+ /// `VK_KHR_acceleration_structure` extension.
acceleration_structure: Option<vk::PhysicalDeviceAccelerationStructurePropertiesKHR>,
+
+ /// Additional `vk::PhysicalDevice` properties from the
+ /// `VK_KHR_driver_properties` extension, promoted to Vulkan 1.2.
driver: Option<vk::PhysicalDeviceDriverPropertiesKHR>,
+
/// The device API version.
///
/// Which is the version of Vulkan supported for device-level functionality.
@@ -657,10 +782,10 @@ pub struct PhysicalDeviceCapabilities {
}
// This is safe because the structs have `p_next: *mut c_void`, which we null out/never read.
-unsafe impl Send for PhysicalDeviceCapabilities {}
-unsafe impl Sync for PhysicalDeviceCapabilities {}
+unsafe impl Send for PhysicalDeviceProperties {}
+unsafe impl Sync for PhysicalDeviceProperties {}
-impl PhysicalDeviceCapabilities {
+impl PhysicalDeviceProperties {
pub fn properties(&self) -> vk::PhysicalDeviceProperties {
self.properties
}
@@ -899,9 +1024,9 @@ impl super::InstanceShared {
fn inspect(
&self,
phd: vk::PhysicalDevice,
- ) -> (PhysicalDeviceCapabilities, PhysicalDeviceFeatures) {
+ ) -> (PhysicalDeviceProperties, PhysicalDeviceFeatures) {
let capabilities = {
- let mut capabilities = PhysicalDeviceCapabilities::default();
+ let mut capabilities = PhysicalDeviceProperties::default();
capabilities.supported_extensions =
unsafe { self.raw.enumerate_device_extension_properties(phd).unwrap() };
capabilities.properties = unsafe { self.raw.get_physical_device_properties(phd) };
@@ -923,9 +1048,10 @@ impl super::InstanceShared {
let mut builder = vk::PhysicalDeviceProperties2KHR::builder();
if supports_maintenance3 {
- capabilities.maintenance_3 =
- Some(vk::PhysicalDeviceMaintenance3Properties::default());
- builder = builder.push_next(capabilities.maintenance_3.as_mut().unwrap());
+ let next = capabilities
+ .maintenance_3
+ .insert(vk::PhysicalDeviceMaintenance3Properties::default());
+ builder = builder.push_next(next);
}
if supports_descriptor_indexing {
@@ -1001,7 +1127,8 @@ impl super::InstanceShared {
builder = builder.push_next(next);
}
- // `VK_KHR_imageless_framebuffer` is promoted to 1.2, but has no changes, so we can keep using the extension unconditionally.
+ // `VK_KHR_imageless_framebuffer` is promoted to 1.2, but has no
+ // changes, so we can keep using the extension unconditionally.
if capabilities.supports_extension(vk::KhrImagelessFramebufferFn::name()) {
let next = features
.imageless_framebuffer
@@ -1009,7 +1136,8 @@ impl super::InstanceShared {
builder = builder.push_next(next);
}
- // `VK_KHR_timeline_semaphore` is promoted to 1.2, but has no changes, so we can keep using the extension unconditionally.
+ // `VK_KHR_timeline_semaphore` is promoted to 1.2, but has no
+ // changes, so we can keep using the extension unconditionally.
if capabilities.supports_extension(vk::KhrTimelineSemaphoreFn::name()) {
let next = features
.timeline_semaphore
@@ -1295,7 +1423,7 @@ impl super::Adapter {
self.raw
}
- pub fn physical_device_capabilities(&self) -> &PhysicalDeviceCapabilities {
+ pub fn physical_device_capabilities(&self) -> &PhysicalDeviceProperties {
&self.phd_capabilities
}
@@ -1320,7 +1448,20 @@ impl super::Adapter {
supported_extensions
}
- /// `features` must be the same features used to create `enabled_extensions`.
+ /// Create a `PhysicalDeviceFeatures` for opening a logical device with
+ /// `features` from this adapter.
+ ///
+ /// The given `enabled_extensions` set must include all the extensions
+ /// selected by [`required_device_extensions`] when passed `features`.
+ /// Otherwise, the `PhysicalDeviceFeatures` value may not be able to select
+ /// all the Vulkan features needed to represent `features` and this
+ /// adapter's characteristics.
+ ///
+ /// Typically, you'd simply call `required_device_extensions`, and then pass
+ /// its return value and the feature set you gave it directly to this
+ /// function. But it's fine to add more extensions to the list.
+ ///
+ /// [`required_device_extensions`]: Self::required_device_extensions
pub fn physical_device_features(
&self,
enabled_extensions: &[&'static CStr],
@@ -1607,7 +1748,9 @@ impl super::Adapter {
}
}
-impl crate::Adapter<super::Api> for super::Adapter {
+impl crate::Adapter for super::Adapter {
+ type A = super::Api;
+
unsafe fn open(
&self,
features: wgt::Features,
diff --git a/third_party/rust/wgpu-hal/src/vulkan/command.rs b/third_party/rust/wgpu-hal/src/vulkan/command.rs
index 42ea907738..43a2471954 100644
--- a/third_party/rust/wgpu-hal/src/vulkan/command.rs
+++ b/third_party/rust/wgpu-hal/src/vulkan/command.rs
@@ -60,7 +60,9 @@ impl super::CommandEncoder {
}
}
-impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
+impl crate::CommandEncoder for super::CommandEncoder {
+ type A = super::Api;
+
unsafe fn begin_encoding(&mut self, label: crate::Label) -> Result<(), crate::DeviceError> {
if self.free.is_empty() {
let vk_info = vk::CommandBufferAllocateInfo::builder()
diff --git a/third_party/rust/wgpu-hal/src/vulkan/device.rs b/third_party/rust/wgpu-hal/src/vulkan/device.rs
index c00c3d1d43..70028cc700 100644
--- a/third_party/rust/wgpu-hal/src/vulkan/device.rs
+++ b/third_party/rust/wgpu-hal/src/vulkan/device.rs
@@ -830,7 +830,9 @@ impl super::Device {
}
}
-impl crate::Device<super::Api> for super::Device {
+impl crate::Device for super::Device {
+ type A = super::Api;
+
unsafe fn exit(self, queue: super::Queue) {
unsafe { self.mem_allocator.into_inner().cleanup(&*self.shared) };
unsafe { self.desc_allocator.into_inner().cleanup(&*self.shared) };
diff --git a/third_party/rust/wgpu-hal/src/vulkan/instance.rs b/third_party/rust/wgpu-hal/src/vulkan/instance.rs
index 771938b0b0..a0d29a13a3 100644
--- a/third_party/rust/wgpu-hal/src/vulkan/instance.rs
+++ b/third_party/rust/wgpu-hal/src/vulkan/instance.rs
@@ -579,7 +579,9 @@ impl Drop for super::InstanceShared {
}
}
-impl crate::Instance<super::Api> for super::Instance {
+impl crate::Instance for super::Instance {
+ type A = super::Api;
+
unsafe fn init(desc: &crate::InstanceDescriptor) -> Result<Self, crate::InstanceError> {
profiling::scope!("Init Vulkan Backend");
use crate::auxil::cstr_from_bytes_until_nul;
@@ -956,7 +958,9 @@ impl crate::Instance<super::Api> for super::Instance {
}
}
-impl crate::Surface<super::Api> for super::Surface {
+impl crate::Surface for super::Surface {
+ type A = super::Api;
+
unsafe fn configure(
&self,
device: &super::Device,
diff --git a/third_party/rust/wgpu-hal/src/vulkan/mod.rs b/third_party/rust/wgpu-hal/src/vulkan/mod.rs
index 1f922e83da..0cd385045c 100644
--- a/third_party/rust/wgpu-hal/src/vulkan/mod.rs
+++ b/third_party/rust/wgpu-hal/src/vulkan/mod.rs
@@ -189,7 +189,7 @@ pub struct Adapter {
instance: Arc<InstanceShared>,
//queue_families: Vec<vk::QueueFamilyProperties>,
known_memory_flags: vk::MemoryPropertyFlags,
- phd_capabilities: adapter::PhysicalDeviceCapabilities,
+ phd_capabilities: adapter::PhysicalDeviceProperties,
//phd_features: adapter::PhysicalDeviceFeatures,
downlevel_flags: wgt::DownlevelFlags,
private_caps: PrivateCapabilities,
@@ -594,7 +594,9 @@ impl Fence {
}
}
-impl crate::Queue<Api> for Queue {
+impl crate::Queue for Queue {
+ type A = Api;
+
unsafe fn submit(
&self,
command_buffers: &[&CommandBuffer],