mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
introduce DynResource & DynBuffer as first user
This commit is contained in:
parent
c6a3d92734
commit
d2508d9ad6
@ -87,6 +87,25 @@ impl crate::Api for Api {
|
||||
type AccelerationStructure = AccelerationStructure;
|
||||
}
|
||||
|
||||
crate::impl_dyn_resource!(
|
||||
BindGroup,
|
||||
BindGroupLayout,
|
||||
Buffer,
|
||||
CommandBuffer,
|
||||
CommandEncoder,
|
||||
ComputePipeline,
|
||||
Fence,
|
||||
PipelineCache,
|
||||
PipelineLayout,
|
||||
QuerySet,
|
||||
RenderPipeline,
|
||||
Sampler,
|
||||
ShaderModule,
|
||||
Surface,
|
||||
Texture,
|
||||
TextureView
|
||||
);
|
||||
|
||||
// Limited by D3D12's root signature size of 64. Each element takes 1 or 2 entries.
|
||||
const MAX_ROOT_ELEMENTS: usize = 64;
|
||||
const ZERO_BUFFER_SIZE: wgt::BufferAddress = 256 << 10;
|
||||
@ -407,6 +426,8 @@ pub struct Buffer {
|
||||
unsafe impl Send for Buffer {}
|
||||
unsafe impl Sync for Buffer {}
|
||||
|
||||
impl crate::DynBuffer for Buffer {}
|
||||
|
||||
impl crate::BufferBinding<'_, Api> {
|
||||
fn resolve_size(&self) -> wgt::BufferAddress {
|
||||
match self.size {
|
||||
|
83
wgpu-hal/src/dynamic/mod.rs
Normal file
83
wgpu-hal/src/dynamic/mod.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use std::any::Any;
|
||||
|
||||
use wgt::WasmNotSendSync;
|
||||
|
||||
/// Base trait for all resources, allows downcasting via [`Any`].
|
||||
pub trait DynResource: Any + WasmNotSendSync + 'static {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
/// Utility macro for implementing `DynResource` for a list of types.
|
||||
macro_rules! impl_dyn_resource {
|
||||
($($type:ty),*) => {
|
||||
$(
|
||||
impl crate::DynResource for $type {
|
||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
pub(crate) use impl_dyn_resource;
|
||||
|
||||
/// Extension trait for `DynResource` used by implementations of various dynamic resource traits.
|
||||
trait DynResourceExt {
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `self` is not downcastable to `T`.
|
||||
fn expect_downcast_ref<T: DynResource>(&self) -> &T;
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `self` is not downcastable to `T`.
|
||||
fn expect_downcast_mut<T: DynResource>(&mut self) -> &mut T;
|
||||
|
||||
/// Unboxes a `Box<dyn DynResource>` to a concrete type.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - `self` must be the correct concrete type.
|
||||
unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T;
|
||||
}
|
||||
|
||||
impl<R: DynResource + ?Sized> DynResourceExt for R {
|
||||
fn expect_downcast_ref<'a, T: DynResource>(&'a self) -> &'a T {
|
||||
self.as_any()
|
||||
.downcast_ref()
|
||||
.expect("Resource doesn't have the expected backend type.")
|
||||
}
|
||||
|
||||
fn expect_downcast_mut<'a, T: DynResource>(&'a mut self) -> &'a mut T {
|
||||
self.as_any_mut()
|
||||
.downcast_mut()
|
||||
.expect("Resource doesn't have the expected backend type.")
|
||||
}
|
||||
|
||||
unsafe fn unbox<T: DynResource + 'static>(self: Box<Self>) -> T {
|
||||
debug_assert!(
|
||||
<Self as Any>::type_id(self.as_ref()) == std::any::TypeId::of::<T>(),
|
||||
"Resource doesn't have the expected type, expected {:?}, got {:?}",
|
||||
std::any::TypeId::of::<T>(),
|
||||
<Self as Any>::type_id(self.as_ref())
|
||||
);
|
||||
|
||||
let casted_ptr = Box::into_raw(self).cast::<T>();
|
||||
// SAFETY: This is adheres to the safety contract of `Box::from_raw` because:
|
||||
//
|
||||
// - We are casting the value of a previously `Box`ed value, which guarantees:
|
||||
// - `casted_ptr` is not null.
|
||||
// - `casted_ptr` is valid for reads and writes, though by itself this does not mean
|
||||
// valid reads and writes for `T` (read on for that).
|
||||
// - We don't change the allocator.
|
||||
// - The contract of `Box::from_raw` requires that an initialized and aligned `T` is stored
|
||||
// within `casted_ptr`.
|
||||
*unsafe { Box::from_raw(casted_ptr) }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DynBuffer: DynResource + std::fmt::Debug {}
|
@ -40,6 +40,10 @@ impl crate::Api for Api {
|
||||
type ComputePipeline = Resource;
|
||||
}
|
||||
|
||||
crate::impl_dyn_resource!(Context, Encoder, Resource);
|
||||
|
||||
impl crate::DynBuffer for Resource {}
|
||||
|
||||
impl crate::Instance for Context {
|
||||
type A = Api;
|
||||
|
||||
|
@ -164,6 +164,24 @@ impl crate::Api for Api {
|
||||
type ComputePipeline = ComputePipeline;
|
||||
}
|
||||
|
||||
crate::impl_dyn_resource!(
|
||||
BindGroup,
|
||||
BindGroupLayout,
|
||||
Buffer,
|
||||
CommandBuffer,
|
||||
CommandEncoder,
|
||||
ComputePipeline,
|
||||
Fence,
|
||||
PipelineLayout,
|
||||
QuerySet,
|
||||
RenderPipeline,
|
||||
Sampler,
|
||||
ShaderModule,
|
||||
Surface,
|
||||
Texture,
|
||||
TextureView
|
||||
);
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Flags that affect internal code paths but do not
|
||||
/// change the exposed feature set.
|
||||
@ -307,6 +325,8 @@ unsafe impl Sync for Buffer {}
|
||||
#[cfg(send_sync)]
|
||||
unsafe impl Send for Buffer {}
|
||||
|
||||
impl crate::DynBuffer for Buffer {}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TextureInner {
|
||||
Renderbuffer {
|
||||
|
@ -262,6 +262,11 @@ pub mod api {
|
||||
pub use super::vulkan::Api as Vulkan;
|
||||
}
|
||||
|
||||
mod dynamic;
|
||||
|
||||
pub use dynamic::DynBuffer;
|
||||
pub(crate) use dynamic::{impl_dyn_resource, DynResource};
|
||||
|
||||
use std::{
|
||||
borrow::{Borrow, Cow},
|
||||
fmt,
|
||||
@ -399,7 +404,7 @@ pub trait Api: Clone + fmt::Debug + Sized {
|
||||
/// [`CommandEncoder`]: Api::CommandEncoder
|
||||
type CommandBuffer: WasmNotSendSync + fmt::Debug;
|
||||
|
||||
type Buffer: fmt::Debug + WasmNotSendSync + 'static;
|
||||
type Buffer: DynBuffer;
|
||||
type Texture: fmt::Debug + WasmNotSendSync + 'static;
|
||||
type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow<Self::Texture>;
|
||||
type TextureView: fmt::Debug + WasmNotSendSync;
|
||||
|
@ -71,6 +71,24 @@ impl crate::Api for Api {
|
||||
type AccelerationStructure = AccelerationStructure;
|
||||
}
|
||||
|
||||
crate::impl_dyn_resource!(
|
||||
BindGroup,
|
||||
BindGroupLayout,
|
||||
Buffer,
|
||||
CommandBuffer,
|
||||
CommandEncoder,
|
||||
ComputePipeline,
|
||||
Fence,
|
||||
PipelineLayout,
|
||||
QuerySet,
|
||||
RenderPipeline,
|
||||
Sampler,
|
||||
ShaderModule,
|
||||
Surface,
|
||||
Texture,
|
||||
TextureView
|
||||
);
|
||||
|
||||
pub struct Instance {
|
||||
managed_metal_layer_delegate: surface::HalManagedMetalLayerDelegate,
|
||||
}
|
||||
@ -460,6 +478,8 @@ pub struct Buffer {
|
||||
unsafe impl Send for Buffer {}
|
||||
unsafe impl Sync for Buffer {}
|
||||
|
||||
impl crate::DynBuffer for Buffer {}
|
||||
|
||||
impl Buffer {
|
||||
fn as_raw(&self) -> BufferPtr {
|
||||
unsafe { NonNull::new_unchecked(self.raw.as_ptr()) }
|
||||
|
@ -78,6 +78,25 @@ impl crate::Api for Api {
|
||||
type ComputePipeline = ComputePipeline;
|
||||
}
|
||||
|
||||
crate::impl_dyn_resource!(
|
||||
BindGroup,
|
||||
BindGroupLayout,
|
||||
Buffer,
|
||||
CommandBuffer,
|
||||
CommandEncoder,
|
||||
ComputePipeline,
|
||||
Fence,
|
||||
PipelineCache,
|
||||
PipelineLayout,
|
||||
QuerySet,
|
||||
RenderPipeline,
|
||||
Sampler,
|
||||
ShaderModule,
|
||||
Surface,
|
||||
Texture,
|
||||
TextureView
|
||||
);
|
||||
|
||||
struct DebugUtils {
|
||||
extension: ext::debug_utils::Instance,
|
||||
messenger: vk::DebugUtilsMessengerEXT,
|
||||
@ -631,6 +650,8 @@ pub struct Buffer {
|
||||
block: Option<Mutex<gpu_alloc::MemoryBlock<vk::DeviceMemory>>>,
|
||||
}
|
||||
|
||||
impl crate::DynBuffer for Buffer {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AccelerationStructure {
|
||||
raw: vk::AccelerationStructureKHR,
|
||||
|
Loading…
Reference in New Issue
Block a user