mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Allow obtaining custom implementation from wgpu api types (#7541)
This commit is contained in:
parent
a9a3ea3a41
commit
6666d528b2
@ -3,9 +3,9 @@ use std::pin::Pin;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use wgpu::custom::{
|
use wgpu::custom::{
|
||||||
AdapterInterface, DeviceInterface, DispatchAdapter, DispatchDevice, DispatchQueue,
|
AdapterInterface, ComputePipelineInterface, DeviceInterface, DispatchAdapter, DispatchDevice,
|
||||||
DispatchShaderModule, DispatchSurface, InstanceInterface, QueueInterface, RequestAdapterFuture,
|
DispatchQueue, DispatchShaderModule, DispatchSurface, InstanceInterface, QueueInterface,
|
||||||
ShaderModuleInterface,
|
RequestAdapterFuture, ShaderModuleInterface,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -163,9 +163,10 @@ impl DeviceInterface for CustomDevice {
|
|||||||
|
|
||||||
fn create_compute_pipeline(
|
fn create_compute_pipeline(
|
||||||
&self,
|
&self,
|
||||||
_desc: &wgpu::ComputePipelineDescriptor<'_>,
|
desc: &wgpu::ComputePipelineDescriptor<'_>,
|
||||||
) -> wgpu::custom::DispatchComputePipeline {
|
) -> wgpu::custom::DispatchComputePipeline {
|
||||||
unimplemented!()
|
let module = desc.module.as_custom::<CustomShaderModule>().unwrap();
|
||||||
|
wgpu::custom::DispatchComputePipeline::custom(CustomComputePipeline(module.0.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn create_pipeline_cache(
|
unsafe fn create_pipeline_cache(
|
||||||
@ -265,7 +266,7 @@ impl DeviceInterface for CustomDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CustomShaderModule(Counter);
|
pub struct CustomShaderModule(pub Counter);
|
||||||
|
|
||||||
impl ShaderModuleInterface for CustomShaderModule {
|
impl ShaderModuleInterface for CustomShaderModule {
|
||||||
fn get_compilation_info(&self) -> Pin<Box<dyn wgpu::custom::ShaderCompilationInfoFuture>> {
|
fn get_compilation_info(&self) -> Pin<Box<dyn wgpu::custom::ShaderCompilationInfoFuture>> {
|
||||||
@ -346,3 +347,12 @@ impl QueueInterface for CustomQueue {
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CustomComputePipeline(pub Counter);
|
||||||
|
|
||||||
|
impl ComputePipelineInterface for CustomComputePipeline {
|
||||||
|
fn get_bind_group_layout(&self, _index: u32) -> wgpu::custom::DispatchBindGroupLayout {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use custom::Counter;
|
use custom::{Counter, CustomShaderModule};
|
||||||
use wgpu::{DeviceDescriptor, RequestAdapterOptions};
|
use wgpu::{DeviceDescriptor, RequestAdapterOptions};
|
||||||
|
|
||||||
mod custom;
|
mod custom;
|
||||||
@ -31,12 +31,26 @@ async fn main() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(counter.count(), 5);
|
assert_eq!(counter.count(), 5);
|
||||||
|
|
||||||
let _module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("shader"),
|
label: Some("shader"),
|
||||||
source: wgpu::ShaderSource::Dummy(PhantomData),
|
source: wgpu::ShaderSource::Dummy(PhantomData),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let custom_module = module.as_custom::<CustomShaderModule>().unwrap();
|
||||||
|
assert_eq!(custom_module.0.count(), 6);
|
||||||
|
let _module_clone = module.clone();
|
||||||
assert_eq!(counter.count(), 6);
|
assert_eq!(counter.count(), 6);
|
||||||
|
|
||||||
|
let _pipeline = device.create_compute_pipeline(&wgpu::ComputePipelineDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: None,
|
||||||
|
module: &module,
|
||||||
|
entry_point: None,
|
||||||
|
compilation_options: Default::default(),
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(counter.count(), 7);
|
||||||
}
|
}
|
||||||
assert_eq!(counter.count(), 1);
|
assert_eq!(counter.count(), 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,6 +133,12 @@ impl Adapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of adapter (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::AdapterInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(custom)]
|
#[cfg(custom)]
|
||||||
/// Creates Adapter from custom implementation
|
/// Creates Adapter from custom implementation
|
||||||
pub fn from_custom<T: custom::AdapterInterface>(adapter: T) -> Self {
|
pub fn from_custom<T: custom::AdapterInterface>(adapter: T) -> Self {
|
||||||
|
|||||||
@ -17,6 +17,14 @@ static_assertions::assert_impl_all!(BindGroup: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(BindGroup => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(BindGroup => .inner);
|
||||||
|
|
||||||
|
impl BindGroup {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of BindGroup (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::BindGroupInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Resource to be bound by a [`BindGroup`] for use with a pipeline.
|
/// Resource to be bound by a [`BindGroup`] for use with a pipeline.
|
||||||
///
|
///
|
||||||
/// The pipeline’s [`BindGroupLayout`] must contain a matching [`BindingType`].
|
/// The pipeline’s [`BindGroupLayout`] must contain a matching [`BindingType`].
|
||||||
|
|||||||
@ -20,6 +20,14 @@ static_assertions::assert_impl_all!(BindGroupLayout: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(BindGroupLayout => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(BindGroupLayout => .inner);
|
||||||
|
|
||||||
|
impl BindGroupLayout {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of BindGroupLayout (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::BindGroupLayoutInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a [`BindGroupLayout`].
|
/// Describes a [`BindGroupLayout`].
|
||||||
///
|
///
|
||||||
/// For use with [`Device::create_bind_group_layout`].
|
/// For use with [`Device::create_bind_group_layout`].
|
||||||
|
|||||||
@ -174,6 +174,12 @@ impl Blas {
|
|||||||
hal_blas_callback(None)
|
hal_blas_callback(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Blas (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: crate::custom::BlasInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context version of [BlasTriangleGeometry].
|
/// Context version of [BlasTriangleGeometry].
|
||||||
|
|||||||
@ -386,6 +386,12 @@ impl Buffer {
|
|||||||
) -> BufferViewMut<'_> {
|
) -> BufferViewMut<'_> {
|
||||||
self.slice(bounds).get_mapped_range_mut()
|
self.slice(bounds).get_mapped_range_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Buffer (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::BufferInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A slice of a [`Buffer`], to be mapped, used for vertex or index data, or the like.
|
/// A slice of a [`Buffer`], to be mapped, used for vertex or index data, or the like.
|
||||||
|
|||||||
@ -13,3 +13,11 @@ pub struct CommandBuffer {
|
|||||||
}
|
}
|
||||||
#[cfg(send_sync)]
|
#[cfg(send_sync)]
|
||||||
static_assertions::assert_impl_all!(CommandBuffer: Send, Sync);
|
static_assertions::assert_impl_all!(CommandBuffer: Send, Sync);
|
||||||
|
|
||||||
|
impl CommandBuffer {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of CommandBuffer (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::CommandBufferInterface>(&self) -> Option<&T> {
|
||||||
|
self.buffer.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -262,6 +262,12 @@ impl CommandEncoder {
|
|||||||
hal_command_encoder_callback(None)
|
hal_command_encoder_callback(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of CommandEncoder (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::CommandEncoderInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`] must be enabled on the device in order to call these functions.
|
/// [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`] must be enabled on the device in order to call these functions.
|
||||||
|
|||||||
@ -94,6 +94,12 @@ impl ComputePass<'_> {
|
|||||||
self.inner
|
self.inner
|
||||||
.dispatch_workgroups_indirect(&indirect_buffer.inner, indirect_offset);
|
.dispatch_workgroups_indirect(&indirect_buffer.inner, indirect_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of ComputePass (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::ComputePassInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions.
|
/// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions.
|
||||||
|
|||||||
@ -27,6 +27,12 @@ impl ComputePipeline {
|
|||||||
let bind_group = self.inner.get_bind_group_layout(index);
|
let bind_group = self.inner.get_bind_group_layout(index);
|
||||||
BindGroupLayout { inner: bind_group }
|
BindGroupLayout { inner: bind_group }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of ComputePipeline (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::ComputePipelineInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes a compute pipeline.
|
/// Describes a compute pipeline.
|
||||||
|
|||||||
@ -34,6 +34,12 @@ pub type DeviceDescriptor<'a> = wgt::DeviceDescriptor<Label<'a>>;
|
|||||||
static_assertions::assert_impl_all!(DeviceDescriptor<'_>: Send, Sync);
|
static_assertions::assert_impl_all!(DeviceDescriptor<'_>: Send, Sync);
|
||||||
|
|
||||||
impl Device {
|
impl Device {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Device (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::DeviceInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(custom)]
|
#[cfg(custom)]
|
||||||
/// Creates Device from custom implementation
|
/// Creates Device from custom implementation
|
||||||
pub fn from_custom<T: custom::DeviceInterface>(device: T) -> Self {
|
pub fn from_custom<T: custom::DeviceInterface>(device: T) -> Self {
|
||||||
|
|||||||
@ -208,6 +208,12 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Instance (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::InstanceInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieves all available [`Adapter`]s that match the given [`Backends`].
|
/// Retrieves all available [`Adapter`]s that match the given [`Backends`].
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|||||||
@ -87,4 +87,10 @@ impl PipelineCache {
|
|||||||
pub fn get_data(&self) -> Option<Vec<u8>> {
|
pub fn get_data(&self) -> Option<Vec<u8>> {
|
||||||
self.inner.get_data()
|
self.inner.get_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of PipelineCache (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::PipelineCacheInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,14 @@ static_assertions::assert_impl_all!(PipelineLayout: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(PipelineLayout => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(PipelineLayout => .inner);
|
||||||
|
|
||||||
|
impl PipelineLayout {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of PipelineLayout (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::PipelineLayoutInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a [`PipelineLayout`].
|
/// Describes a [`PipelineLayout`].
|
||||||
///
|
///
|
||||||
/// For use with [`Device::create_pipeline_layout`].
|
/// For use with [`Device::create_pipeline_layout`].
|
||||||
|
|||||||
@ -15,6 +15,14 @@ static_assertions::assert_impl_all!(QuerySet: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(QuerySet => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(QuerySet => .inner);
|
||||||
|
|
||||||
|
impl QuerySet {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of QuerySet (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::QuerySetInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a [`QuerySet`].
|
/// Describes a [`QuerySet`].
|
||||||
///
|
///
|
||||||
/// For use with [`Device::create_query_set`].
|
/// For use with [`Device::create_query_set`].
|
||||||
|
|||||||
@ -19,6 +19,22 @@ static_assertions::assert_impl_all!(Queue: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(Queue => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(Queue => .inner);
|
||||||
|
|
||||||
|
impl Queue {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Queue (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::QueueInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Creates Queue from custom implementation
|
||||||
|
pub fn from_custom<T: custom::QueueInterface>(queue: T) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: dispatch::DispatchQueue::custom(queue),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Identifier for a particular call to [`Queue::submit`]. Can be used
|
/// Identifier for a particular call to [`Queue::submit`]. Can be used
|
||||||
/// as part of an argument to [`Device::poll`] to block for a particular
|
/// as part of an argument to [`Device::poll`] to block for a particular
|
||||||
/// submission to finish.
|
/// submission to finish.
|
||||||
@ -51,6 +67,14 @@ pub struct QueueWriteBufferView<'a> {
|
|||||||
#[cfg(send_sync)]
|
#[cfg(send_sync)]
|
||||||
static_assertions::assert_impl_all!(QueueWriteBufferView<'_>: Send, Sync);
|
static_assertions::assert_impl_all!(QueueWriteBufferView<'_>: Send, Sync);
|
||||||
|
|
||||||
|
impl QueueWriteBufferView<'_> {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of QueueWriteBufferView (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::QueueWriteBufferInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for QueueWriteBufferView<'_> {
|
impl Deref for QueueWriteBufferView<'_> {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
|
|
||||||
@ -81,14 +105,6 @@ impl Drop for QueueWriteBufferView<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Queue {
|
impl Queue {
|
||||||
#[cfg(custom)]
|
|
||||||
/// Creates Queue from custom implementation
|
|
||||||
pub fn from_custom<T: custom::QueueInterface>(queue: T) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: dispatch::DispatchQueue::custom(queue),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copies the bytes of `data` into `buffer` starting at `offset`.
|
/// Copies the bytes of `data` into `buffer` starting at `offset`.
|
||||||
///
|
///
|
||||||
/// The data must be written fully in-bounds, that is, `offset + data.len() <= buffer.len()`.
|
/// The data must be written fully in-bounds, that is, `offset + data.len() <= buffer.len()`.
|
||||||
|
|||||||
@ -18,6 +18,14 @@ static_assertions::assert_impl_all!(RenderBundle: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(RenderBundle => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(RenderBundle => .inner);
|
||||||
|
|
||||||
|
impl RenderBundle {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of RenderBundle (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::RenderBundleInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a [`RenderBundle`].
|
/// Describes a [`RenderBundle`].
|
||||||
///
|
///
|
||||||
/// For use with [`RenderBundleEncoder::finish`].
|
/// For use with [`RenderBundleEncoder::finish`].
|
||||||
|
|||||||
@ -188,6 +188,12 @@ impl<'a> RenderBundleEncoder<'a> {
|
|||||||
self.inner
|
self.inner
|
||||||
.draw_indexed_indirect(&indirect_buffer.inner, indirect_offset);
|
.draw_indexed_indirect(&indirect_buffer.inner, indirect_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of RenderBundleEncoder (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::RenderBundleEncoderInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions.
|
/// [`Features::PUSH_CONSTANTS`] must be enabled on the device in order to call these functions.
|
||||||
|
|||||||
@ -306,6 +306,12 @@ impl RenderPass<'_> {
|
|||||||
self.inner
|
self.inner
|
||||||
.multi_draw_indexed_indirect(&indirect_buffer.inner, indirect_offset, count);
|
.multi_draw_indexed_indirect(&indirect_buffer.inner, indirect_offset, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of RenderPass (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::RenderPassInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call these functions.
|
/// [`Features::MULTI_DRAW_INDIRECT_COUNT`] must be enabled on the device in order to call these functions.
|
||||||
|
|||||||
@ -28,6 +28,12 @@ impl RenderPipeline {
|
|||||||
let layout = self.inner.get_bind_group_layout(index);
|
let layout = self.inner.get_bind_group_layout(index);
|
||||||
BindGroupLayout { inner: layout }
|
BindGroupLayout { inner: layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of RenderPipeline (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::RenderPipelineInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies an interpretation of the bytes of a vertex buffer as vertex attributes.
|
/// Specifies an interpretation of the bytes of a vertex buffer as vertex attributes.
|
||||||
|
|||||||
@ -18,6 +18,14 @@ static_assertions::assert_impl_all!(Sampler: Send, Sync);
|
|||||||
|
|
||||||
crate::cmp::impl_eq_ord_hash_proxy!(Sampler => .inner);
|
crate::cmp::impl_eq_ord_hash_proxy!(Sampler => .inner);
|
||||||
|
|
||||||
|
impl Sampler {
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Sampler (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::SamplerInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes a [`Sampler`].
|
/// Describes a [`Sampler`].
|
||||||
///
|
///
|
||||||
/// For use with [`Device::create_sampler`].
|
/// For use with [`Device::create_sampler`].
|
||||||
|
|||||||
@ -29,6 +29,12 @@ impl ShaderModule {
|
|||||||
pub fn get_compilation_info(&self) -> impl Future<Output = CompilationInfo> + WasmNotSend {
|
pub fn get_compilation_info(&self) -> impl Future<Output = CompilationInfo> + WasmNotSend {
|
||||||
self.inner.get_compilation_info()
|
self.inner.get_compilation_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of ShaderModule (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::ShaderModuleInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compilation information for a shader module.
|
/// Compilation information for a shader module.
|
||||||
|
|||||||
@ -171,6 +171,12 @@ impl Surface<'_> {
|
|||||||
hal_surface_callback(None)
|
hal_surface_callback(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Surface (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::SurfaceInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This custom implementation is required because [`Surface::_surface`] doesn't
|
// This custom implementation is required because [`Surface::_surface`] doesn't
|
||||||
|
|||||||
@ -38,6 +38,12 @@ impl SurfaceTexture {
|
|||||||
self.presented = true;
|
self.presented = true;
|
||||||
self.detail.present();
|
self.detail.present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of SurfaceTexture (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: crate::custom::SurfaceOutputDetailInterface>(&self) -> Option<&T> {
|
||||||
|
self.detail.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SurfaceTexture {
|
impl Drop for SurfaceTexture {
|
||||||
|
|||||||
@ -37,6 +37,12 @@ impl Texture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Texture (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::TextureInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a view of this texture, specifying an interpretation of its texels and
|
/// Creates a view of this texture, specifying an interpretation of its texels and
|
||||||
/// possibly a subset of its layers and mip levels.
|
/// possibly a subset of its layers and mip levels.
|
||||||
///
|
///
|
||||||
|
|||||||
@ -40,6 +40,12 @@ impl TextureView {
|
|||||||
hal_texture_view_callback(None)
|
hal_texture_view_callback(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of TextureView (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: custom::TextureViewInterface>(&self) -> Option<&T> {
|
||||||
|
self.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes a [`TextureView`].
|
/// Describes a [`TextureView`].
|
||||||
|
|||||||
@ -57,6 +57,12 @@ impl Tlas {
|
|||||||
hal_tlas_callback(None)
|
hal_tlas_callback(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
/// Returns custom implementation of Tlas (if custom backend and is internally T)
|
||||||
|
pub fn as_custom<T: crate::custom::TlasInterface>(&self) -> Option<&T> {
|
||||||
|
self.shared.inner.as_custom()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Entry for a top level acceleration structure build.
|
/// Entry for a top level acceleration structure build.
|
||||||
|
|||||||
@ -18,6 +18,11 @@ macro_rules! dyn_type {
|
|||||||
pub(crate) fn new<T: $interface>(t: T) -> Self {
|
pub(crate) fn new<T: $interface>(t: T) -> Self {
|
||||||
Self(Arc::new(t))
|
Self(Arc::new(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::allow_attributes, dead_code)]
|
||||||
|
pub(crate) fn downcast<T: $interface>(&self) -> Option<&T> {
|
||||||
|
self.0.as_ref().as_any().downcast_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Deref for $name {
|
impl core::ops::Deref for $name {
|
||||||
@ -46,6 +51,10 @@ macro_rules! dyn_type {
|
|||||||
pub(crate) fn new<T: $interface>(t: T) -> Self {
|
pub(crate) fn new<T: $interface>(t: T) -> Self {
|
||||||
Self(Arc::new(t))
|
Self(Arc::new(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn downcast<T: $interface>(&self) -> Option<&T> {
|
||||||
|
self.0.as_ref().as_any().downcast_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::ops::Deref for $name {
|
impl core::ops::Deref for $name {
|
||||||
|
|||||||
@ -54,8 +54,20 @@ pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>)
|
|||||||
#[cfg(not(send_sync))]
|
#[cfg(not(send_sync))]
|
||||||
pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + 'static>;
|
pub type BufferMapCallback = Box<dyn FnOnce(Result<(), crate::BufferAsyncError>) + 'static>;
|
||||||
|
|
||||||
|
// remove when rust 1.86
|
||||||
|
#[cfg_attr(not(custom), expect(dead_code))]
|
||||||
|
pub trait AsAny {
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: 'static> AsAny for T {
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Common traits on all the interface traits
|
// Common traits on all the interface traits
|
||||||
trait_alias!(CommonTraits: Any + Debug + WasmNotSendSync);
|
trait_alias!(CommonTraits: AsAny + Any + Debug + WasmNotSendSync);
|
||||||
|
|
||||||
pub trait InstanceInterface: CommonTraits {
|
pub trait InstanceInterface: CommonTraits {
|
||||||
fn new(desc: &crate::InstanceDescriptor) -> Self
|
fn new(desc: &crate::InstanceDescriptor) -> Self
|
||||||
@ -575,6 +587,16 @@ macro_rules! dispatch_types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
#[inline]
|
||||||
|
#[allow(clippy::allow_attributes, unused)]
|
||||||
|
pub fn as_custom<T: $interface>(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
Self::Custom(value) => value.downcast(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(webgpu)]
|
#[cfg(webgpu)]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::allow_attributes, unused)]
|
#[allow(clippy::allow_attributes, unused)]
|
||||||
@ -693,6 +715,16 @@ macro_rules! dispatch_types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(custom)]
|
||||||
|
#[inline]
|
||||||
|
#[allow(clippy::allow_attributes, unused)]
|
||||||
|
pub fn as_custom<T: $interface>(&self) -> Option<&T> {
|
||||||
|
match self {
|
||||||
|
Self::Custom(value) => value.downcast(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(webgpu)]
|
#[cfg(webgpu)]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(clippy::allow_attributes, unused)]
|
#[allow(clippy::allow_attributes, unused)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user