Skip to content

Commit

Permalink
hal: Pass buffer arguments as trait objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
nical committed Jan 30, 2024
1 parent 950d765 commit 576f28b
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 42 deletions.
21 changes: 15 additions & 6 deletions wgpu-hal/src/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use std::ops::Range;

use crate::BufferResource;

#[derive(Clone, Debug)]
pub struct Api;
pub struct Context;
Expand All @@ -10,6 +12,13 @@ pub struct Encoder;
#[derive(Debug)]
pub struct Resource;

impl super::Resource for Resource {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl BufferResource for Resource {}

type DeviceResult<T> = Result<T, crate::DeviceError>;

impl crate::Api for Api {
Expand Down Expand Up @@ -130,16 +139,16 @@ impl crate::Device<Api> for Context {
unsafe fn destroy_buffer(&self, buffer: Resource) {}
unsafe fn map_buffer(
&self,
buffer: &Resource,
buffer: &dyn BufferResource,
range: crate::MemoryRange,
) -> DeviceResult<crate::BufferMapping> {
Err(crate::DeviceError::Lost)
}
unsafe fn unmap_buffer(&self, buffer: &Resource) -> DeviceResult<()> {
unsafe fn unmap_buffer(&self, buffer: &dyn BufferResource) -> DeviceResult<()> {
Ok(())
}
unsafe fn flush_mapped_ranges<I>(&self, buffer: &Resource, ranges: I) {}
unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &Resource, ranges: I) {}
unsafe fn flush_mapped_ranges<I>(&self, buffer: &dyn BufferResource, ranges: I) {}
unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &dyn BufferResource, ranges: I) {}

unsafe fn create_texture(&self, desc: &crate::TextureDescriptor) -> DeviceResult<Resource> {
Ok(Resource)
Expand Down Expand Up @@ -281,9 +290,9 @@ impl crate::CommandEncoder<Api> for Encoder {
{
}

unsafe fn clear_buffer(&mut self, buffer: &Resource, range: crate::MemoryRange) {}
unsafe fn clear_buffer(&mut self, buffer: &dyn BufferResource, range: crate::MemoryRange) {}

unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &Resource, dst: &Resource, regions: T) {}
unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &dyn BufferResource, dst: &dyn BufferResource, regions: T) {}

#[cfg(webgl)]
unsafe fn copy_external_image_to_texture<T>(
Expand Down
13 changes: 10 additions & 3 deletions wgpu-hal/src/gles/command.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{downcast, BufferResource};

use super::{conv, Command as C};
use arrayvec::ArrayVec;
use std::{mem, ops::Range};
Expand Down Expand Up @@ -317,7 +319,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
}

unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) {
unsafe fn clear_buffer(&mut self, buffer: &dyn BufferResource, range: crate::MemoryRange) {
let buffer: &super::Buffer = downcast(buffer);

self.cmd_buffer.commands.push(C::ClearBuffer {
dst: buffer.clone(),
dst_target: buffer.target,
Expand All @@ -327,12 +331,15 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {

unsafe fn copy_buffer_to_buffer<T>(
&mut self,
src: &super::Buffer,
dst: &super::Buffer,
src: &dyn BufferResource,
dst: &dyn BufferResource,
regions: T,
) where
T: Iterator<Item = crate::BufferCopy>,
{
let src: &super::Buffer = downcast(src);
let dst: &super::Buffer = downcast(dst);

let (src_target, dst_target) = if src.target == dst.target {
(glow::COPY_READ_BUFFER, glow::COPY_WRITE_BUFFER)
} else {
Expand Down
16 changes: 11 additions & 5 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{conv, PrivateCapabilities};
use crate::auxil::map_naga_stage;
use crate::{auxil::map_naga_stage, downcast, BufferResource};
use glow::HasContext;
use std::{
cmp::max,
Expand Down Expand Up @@ -626,9 +626,11 @@ impl crate::Device<super::Api> for super::Device {

unsafe fn map_buffer(
&self,
buffer: &super::Buffer,
buffer: &dyn BufferResource,
range: crate::MemoryRange,
) -> Result<crate::BufferMapping, crate::DeviceError> {
let buffer: &super::Buffer = downcast(buffer);

let is_coherent = buffer.map_flags & glow::MAP_COHERENT_BIT != 0;
let ptr = match buffer.raw {
None => {
Expand Down Expand Up @@ -663,7 +665,9 @@ impl crate::Device<super::Api> for super::Device {
is_coherent,
})
}
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> {
unsafe fn unmap_buffer(&self, buffer: &dyn BufferResource) -> Result<(), crate::DeviceError> {
let buffer: &super::Buffer = downcast(buffer);

if let Some(raw) = buffer.raw {
if buffer.data.is_none() {
let gl = &self.shared.context.lock();
Expand All @@ -674,10 +678,12 @@ impl crate::Device<super::Api> for super::Device {
}
Ok(())
}
unsafe fn flush_mapped_ranges<I>(&self, buffer: &super::Buffer, ranges: I)
unsafe fn flush_mapped_ranges<I>(&self, buffer: &dyn BufferResource, ranges: I)
where
I: Iterator<Item = crate::MemoryRange>,
{
let buffer: &super::Buffer = downcast(buffer);

if let Some(raw) = buffer.raw {
let gl = &self.shared.context.lock();
unsafe { gl.bind_buffer(buffer.target, Some(raw)) };
Expand All @@ -692,7 +698,7 @@ impl crate::Device<super::Api> for super::Device {
}
}
}
unsafe fn invalidate_mapped_ranges<I>(&self, _buffer: &super::Buffer, _ranges: I) {
unsafe fn invalidate_mapped_ranges<I>(&self, _buffer: &dyn BufferResource, _ranges: I) {
//TODO: do we need to do anything?
}

Expand Down
12 changes: 11 additions & 1 deletion wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ mod conv;
mod device;
mod queue;

use crate::{CopyExtent, TextureDescriptor};
use crate::{BufferResource, CopyExtent, Resource, TextureDescriptor};

#[cfg(not(any(windows, webgl)))]
pub use self::egl::{AdapterContext, AdapterContextLock};
Expand All @@ -120,6 +120,7 @@ use glow::HasContext;

use naga::FastHashMap;
use parking_lot::Mutex;
use std::any::Any;
use std::sync::atomic::{AtomicU32, AtomicU8};
use std::{fmt, ops::Range, sync::Arc};

Expand Down Expand Up @@ -291,6 +292,15 @@ pub struct Buffer {
data: Option<Arc<std::sync::Mutex<Vec<u8>>>>,
}

impl Resource for Buffer {
fn as_any(&self) -> &dyn Any {
self
}
}

impl BufferResource for Buffer {}


#[cfg(send_sync)]
unsafe impl Sync for Buffer {}
#[cfg(send_sync)]
Expand Down
33 changes: 19 additions & 14 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,7 @@ pub mod api {
}

use std::{
borrow::{Borrow, Cow},
fmt,
num::NonZeroU32,
ops::{Range, RangeInclusive},
ptr::NonNull,
sync::Arc,
any::Any, borrow::{Borrow, Cow}, fmt, num::NonZeroU32, ops::{Range, RangeInclusive}, ptr::NonNull, sync::Arc
};

use bitflags::bitflags;
Expand All @@ -109,7 +104,7 @@ pub type MemoryRange = Range<wgt::BufferAddress>;
pub type FenceValue = u64;

/// Drop guard to signal wgpu-hal is no longer using an externally created object.
pub type DropGuard = Box<dyn std::any::Any + Send + Sync>;
pub type DropGuard = Box<dyn Any + Send + Sync>;

#[derive(Clone, Debug, PartialEq, Eq, Error)]
pub enum DeviceError {
Expand Down Expand Up @@ -188,6 +183,16 @@ impl InstanceError {
}
}

pub trait Resource: 'static {
fn as_any(&self) -> &dyn Any;
}

pub trait BufferResource: Resource {}

pub fn downcast<T: Resource>(from: &dyn BufferResource) -> &T {
from.as_any().downcast_ref().unwrap()
}

pub trait Api: Clone + fmt::Debug + Sized {
type Instance: Instance<Self>;
type Surface: Surface<Self>;
Expand All @@ -198,7 +203,7 @@ pub trait Api: Clone + fmt::Debug + Sized {
type CommandEncoder: CommandEncoder<Self>;
type CommandBuffer: WasmNotSendSync + fmt::Debug;

type Buffer: fmt::Debug + WasmNotSendSync + 'static;
type Buffer: fmt::Debug + WasmNotSendSync + BufferResource;
type Texture: fmt::Debug + WasmNotSendSync + 'static;
type SurfaceTexture: fmt::Debug + WasmNotSendSync + Borrow<Self::Texture>;
type TextureView: fmt::Debug + WasmNotSendSync;
Expand Down Expand Up @@ -304,14 +309,14 @@ pub trait Device<A: Api>: WasmNotSendSync {
//TODO: clarify if zero-sized mapping is allowed
unsafe fn map_buffer(
&self,
buffer: &A::Buffer,
buffer: &dyn BufferResource,
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: &dyn BufferResource) -> Result<(), DeviceError>;
unsafe fn flush_mapped_ranges<I>(&self, buffer: &dyn BufferResource, 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: &dyn BufferResource, ranges: I)
where
I: Iterator<Item = MemoryRange>;

Expand Down Expand Up @@ -456,9 +461,9 @@ pub trait CommandEncoder<A: Api>: WasmNotSendSync + fmt::Debug {

// copy operations

unsafe fn clear_buffer(&mut self, buffer: &A::Buffer, range: MemoryRange);
unsafe fn clear_buffer(&mut self, buffer: &dyn BufferResource, range: MemoryRange);

unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &A::Buffer, dst: &A::Buffer, regions: T)
unsafe fn copy_buffer_to_buffer<T>(&mut self, src: &dyn BufferResource, dst: &dyn BufferResource, regions: T)
where
T: Iterator<Item = BufferCopy>;

Expand Down
13 changes: 10 additions & 3 deletions wgpu-hal/src/vulkan/command.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{downcast, BufferResource};

use super::conv;

use arrayvec::ArrayVec;
Expand Down Expand Up @@ -211,7 +213,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
}

unsafe fn clear_buffer(&mut self, buffer: &super::Buffer, range: crate::MemoryRange) {
unsafe fn clear_buffer(&mut self, buffer: &dyn BufferResource, range: crate::MemoryRange) {
let buffer: &super::Buffer = downcast(buffer);

let range_size = range.end - range.start;
if self.device.workarounds.contains(
super::Workarounds::FORCE_FILL_BUFFER_WITH_SIZE_GREATER_4096_ALIGNED_OFFSET_16,
Expand Down Expand Up @@ -254,12 +258,15 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {

unsafe fn copy_buffer_to_buffer<T>(
&mut self,
src: &super::Buffer,
dst: &super::Buffer,
src: &dyn BufferResource,
dst: &dyn BufferResource,
regions: T,
) where
T: Iterator<Item = crate::BufferCopy>,
{
let src: &super::Buffer = downcast(src);
let dst: &super::Buffer = downcast(dst);

let vk_regions_iter = regions.map(|r| vk::BufferCopy {
src_offset: r.src_offset,
dst_offset: r.dst_offset,
Expand Down
16 changes: 12 additions & 4 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::{downcast, BufferResource};

use super::conv;

use arrayvec::ArrayVec;
Expand Down Expand Up @@ -927,9 +929,11 @@ impl crate::Device<super::Api> for super::Device {

unsafe fn map_buffer(
&self,
buffer: &super::Buffer,
buffer: &dyn BufferResource,
range: crate::MemoryRange,
) -> Result<crate::BufferMapping, crate::DeviceError> {
let buffer: &super::Buffer = downcast(buffer);

if let Some(ref block) = buffer.block {
let size = range.end - range.start;
let mut block = block.lock();
Expand All @@ -942,7 +946,9 @@ impl crate::Device<super::Api> for super::Device {
Err(crate::DeviceError::OutOfMemory)
}
}
unsafe fn unmap_buffer(&self, buffer: &super::Buffer) -> Result<(), crate::DeviceError> {
unsafe fn unmap_buffer(&self, buffer: &dyn BufferResource) -> Result<(), crate::DeviceError> {
let buffer: &super::Buffer = downcast(buffer);

if let Some(ref block) = buffer.block {
unsafe { block.lock().unmap(&*self.shared) };
Ok(())
Expand All @@ -951,10 +957,11 @@ impl crate::Device<super::Api> for super::Device {
}
}

unsafe fn flush_mapped_ranges<I>(&self, buffer: &super::Buffer, ranges: I)
unsafe fn flush_mapped_ranges<I>(&self, buffer: &dyn BufferResource, ranges: I)
where
I: Iterator<Item = crate::MemoryRange>,
{
let buffer: &super::Buffer = downcast(buffer);
if let Some(vk_ranges) = self.shared.make_memory_ranges(buffer, ranges) {
unsafe {
self.shared
Expand All @@ -966,10 +973,11 @@ impl crate::Device<super::Api> for super::Device {
.unwrap();
}
}
unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &super::Buffer, ranges: I)
unsafe fn invalidate_mapped_ranges<I>(&self, buffer: &dyn BufferResource, ranges: I)
where
I: Iterator<Item = crate::MemoryRange>,
{
let buffer: &super::Buffer = downcast(buffer);
if let Some(vk_ranges) = self.shared.make_memory_ranges(buffer, ranges) {
unsafe {
self.shared
Expand Down
16 changes: 10 additions & 6 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,10 @@ mod device;
mod instance;

use std::{
borrow::Borrow,
ffi::CStr,
fmt,
num::NonZeroU32,
sync::{
any::Any, borrow::Borrow, ffi::CStr, fmt, num::NonZeroU32, sync::{
atomic::{AtomicIsize, Ordering},
Arc,
},
}
};

use arrayvec::ArrayVec;
Expand All @@ -49,6 +45,8 @@ use ash::{
};
use parking_lot::{Mutex, RwLock};

use crate::{BufferResource, Resource};

const MILLIS_TO_NANOS: u64 = 1_000_000;
const MAX_TOTAL_ATTACHMENTS: usize = crate::MAX_COLOR_ATTACHMENTS * 2 + 1;

Expand Down Expand Up @@ -370,6 +368,12 @@ pub struct Buffer {
block: Option<Mutex<gpu_alloc::MemoryBlock<vk::DeviceMemory>>>,
}

impl Resource for Buffer {
fn as_any(&self) -> &dyn Any { self }
}

impl BufferResource for Buffer {}

#[derive(Debug)]
pub struct AccelerationStructure {
raw: vk::AccelerationStructureKHR,
Expand Down

0 comments on commit 576f28b

Please sign in to comment.