Skip to content

Commit

Permalink
Add more hal methods (#5452)
Browse files Browse the repository at this point in the history
* Add return value to Texture::as_hal()

* Add TextureView::as_hal()

* Add CommandEncoder::as_hal_mut()

* Add changelog

* Add TextureView::raw_handle()

* Add CommandEncoder::raw_handle()

* Add additional docs for command_encoder_as_hal_mut
  • Loading branch information
JMS55 authored Apr 2, 2024
1 parent 0c5bebc commit ed843f8
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 15 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ Bottom level categories:
- Breaking change: [`wgpu_core::pipeline::ProgrammableStageDescriptor`](https://docs.rs/wgpu-core/latest/wgpu_core/pipeline/struct.ProgrammableStageDescriptor.html#structfield.entry_point) is now optional. By @ErichDonGubler in [#5305](https://github.com/gfx-rs/wgpu/pull/5305).
- `Features::downlevel{_webgl2,}_features` was made const by @MultisampledNight in [#5343](https://github.com/gfx-rs/wgpu/pull/5343)

- More as_hal methods and improvements by @JMS55 in [#5452](https://github.com/gfx-rs/wgpu/pull/5452)
- Added `wgpu::CommandEncoder::as_hal_mut`
- Added `wgpu::TextureView::as_hal`
- `wgpu::Texture::as_hal` now returns a user-defined type to match the other as_hal functions

#### GLES

- Log an error when GLES texture format heuristics fail. By @PolyMeilex in [#5266](https://github.com/gfx-rs/wgpu/issues/5266)
Expand All @@ -125,7 +130,7 @@ Bottom level categories:
#### WebGPU

- Implement the `device_set_device_lost_callback` method for `ContextWebGpu`. By @suti in [#5438](https://github.com/gfx-rs/wgpu/pull/5438)
- Add support for storage texture access modes `ReadOnly` and `ReadWrite`. By @JolifantoBambla in [#5434](https://github.com/gfx-rs/wgpu/pull/5434)
- Add support for storage texture access modes `ReadOnly` and `ReadWrite`. By @JolifantoBambla in [#5434](https://github.com/gfx-rs/wgpu/pull/5434)

### Bug Fixes

Expand Down Expand Up @@ -181,7 +186,7 @@ This release includes `wgpu`, `wgpu-core`, and `wgpu-hal`. All other crates are

### Major Changes

#### Vendored WebGPU Bindings from `web_sys`
#### Vendored WebGPU Bindings from `web_sys`

**`--cfg=web_sys_unstable_apis` is no longer needed in your `RUSTFLAGS` to compile for WebGPU!!!**

Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<A: HalApi> CommandEncoder<A> {
}
}

fn open(&mut self) -> Result<&mut A::CommandEncoder, DeviceError> {
pub(crate) fn open(&mut self) -> Result<&mut A::CommandEncoder, DeviceError> {
if !self.is_open {
self.is_open = true;
let label = self.label.as_deref();
Expand Down
53 changes: 49 additions & 4 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use crate::{
},
global::Global,
hal_api::HalApi,
id::{AdapterId, BufferId, DeviceId, Id, Marker, SurfaceId, TextureId},
id::{
AdapterId, BufferId, CommandEncoderId, DeviceId, Id, Marker, SurfaceId, TextureId,
TextureViewId,
},
init_tracker::{BufferInitTracker, TextureInitTracker},
resource, resource_log,
snatch::{ExclusiveSnatchGuard, SnatchGuard, Snatchable},
Expand Down Expand Up @@ -924,11 +927,11 @@ impl Global {
/// # Safety
///
/// - The raw texture handle must not be manually destroyed
pub unsafe fn texture_as_hal<A: HalApi, F: FnOnce(Option<&A::Texture>)>(
pub unsafe fn texture_as_hal<A: HalApi, F: FnOnce(Option<&A::Texture>) -> R, R>(
&self,
id: TextureId,
hal_texture_callback: F,
) {
) -> R {
profiling::scope!("Texture::as_hal");

let hub = A::hub(self);
Expand All @@ -937,7 +940,26 @@ impl Global {
let snatch_guard = texture.device.snatchable_lock.read();
let hal_texture = texture.raw(&snatch_guard);

hal_texture_callback(hal_texture);
hal_texture_callback(hal_texture)
}

/// # Safety
///
/// - The raw texture view handle must not be manually destroyed
pub unsafe fn texture_view_as_hal<A: HalApi, F: FnOnce(Option<&A::TextureView>) -> R, R>(
&self,
id: TextureViewId,
hal_texture_view_callback: F,
) -> R {
profiling::scope!("TextureView::as_hal");

let hub = A::hub(self);
let texture_view_opt = { hub.texture_views.try_get(id).ok().flatten() };
let texture_view = texture_view_opt.as_ref().unwrap();
let snatch_guard = texture_view.device.snatchable_lock.read();
let hal_texture_view = texture_view.raw(&snatch_guard);

hal_texture_view_callback(hal_texture_view)
}

/// # Safety
Expand Down Expand Up @@ -1005,6 +1027,29 @@ impl Global {

hal_surface_callback(hal_surface)
}

/// # Safety
///
/// - The raw command encoder handle must not be manually destroyed
pub unsafe fn command_encoder_as_hal_mut<
A: HalApi,
F: FnOnce(Option<&mut A::CommandEncoder>) -> R,
R,
>(
&self,
id: CommandEncoderId,
hal_command_encoder_callback: F,
) -> R {
profiling::scope!("CommandEncoder::as_hal");

let hub = A::hub(self);
let cmd_buf = hub.command_buffers.get(id.transmute()).unwrap();
let mut cmd_buf_data = cmd_buf.data.lock();
let cmd_buf_data = cmd_buf_data.as_mut().unwrap();
let cmd_buf_raw = cmd_buf_data.encoder.open().ok();

hal_command_encoder_callback(cmd_buf_raw)
}
}

/// A texture that has been marked as destroyed and is staged for actual deletion soon.
Expand Down
18 changes: 18 additions & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ pub struct TextureView {
attachment: FramebufferAttachment,
}

impl TextureView {
/// # Safety
///
/// - The image view handle must not be manually destroyed
pub unsafe fn raw_handle(&self) -> vk::ImageView {
self.raw
}
}

#[derive(Debug)]
pub struct Sampler {
raw: vk::Sampler,
Expand Down Expand Up @@ -481,6 +490,15 @@ pub struct CommandEncoder {
end_of_pass_timer_query: Option<(vk::QueryPool, u32)>,
}

impl CommandEncoder {
/// # Safety
///
/// - The command buffer handle must not be manually destroyed
pub unsafe fn raw_handle(&self) -> vk::CommandBuffer {
self.active
}
}

impl fmt::Debug for CommandEncoder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CommandEncoder")
Expand Down
50 changes: 45 additions & 5 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ use std::{
slice,
sync::Arc,
};
use wgc::command::{bundle_ffi::*, compute_ffi::*, render_ffi::*};
use wgc::device::DeviceLostClosure;
use wgc::{
command::{bundle_ffi::*, compute_ffi::*, render_ffi::*},
device::DeviceLostClosure,
id::{CommandEncoderId, TextureViewId},
};
use wgt::WasmNotSendSync;

const LABEL: &str = "label";
Expand Down Expand Up @@ -207,14 +210,51 @@ impl ContextWgpuCore {
}
}

pub unsafe fn texture_as_hal<A: wgc::hal_api::HalApi, F: FnOnce(Option<&A::Texture>)>(
pub unsafe fn texture_as_hal<
A: wgc::hal_api::HalApi,
F: FnOnce(Option<&A::Texture>) -> R,
R,
>(
&self,
texture: &Texture,
hal_texture_callback: F,
) {
) -> R {
unsafe {
self.0
.texture_as_hal::<A, F, R>(texture.id, hal_texture_callback)
}
}

pub unsafe fn texture_view_as_hal<
A: wgc::hal_api::HalApi,
F: FnOnce(Option<&A::TextureView>) -> R,
R,
>(
&self,
texture_view_id: TextureViewId,
hal_texture_view_callback: F,
) -> R {
unsafe {
self.0
.texture_as_hal::<A, F>(texture.id, hal_texture_callback)
.texture_view_as_hal::<A, F, R>(texture_view_id, hal_texture_view_callback)
}
}

/// This method will start the wgpu_core level command recording.
pub unsafe fn command_encoder_as_hal_mut<
A: wgc::hal_api::HalApi,
F: FnOnce(Option<&mut A::CommandEncoder>) -> R,
R,
>(
&self,
command_encoder_id: CommandEncoderId,
hal_command_encoder_callback: F,
) -> R {
unsafe {
self.0.command_encoder_as_hal_mut::<A, F, R>(
command_encoder_id,
hal_command_encoder_callback,
)
}
}

Expand Down
64 changes: 61 additions & 3 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3115,18 +3115,18 @@ impl Texture {
///
/// - The raw handle obtained from the hal Texture must not be manually destroyed
#[cfg(wgpu_core)]
pub unsafe fn as_hal<A: wgc::hal_api::HalApi, F: FnOnce(Option<&A::Texture>)>(
pub unsafe fn as_hal<A: wgc::hal_api::HalApi, F: FnOnce(Option<&A::Texture>) -> R, R>(
&self,
hal_texture_callback: F,
) {
) -> R {
let texture = self.data.as_ref().downcast_ref().unwrap();

if let Some(ctx) = self
.context
.as_any()
.downcast_ref::<crate::backend::ContextWgpuCore>()
{
unsafe { ctx.texture_as_hal::<A, F>(texture, hal_texture_callback) }
unsafe { ctx.texture_as_hal::<A, F, R>(texture, hal_texture_callback) }
} else {
hal_texture_callback(None)
}
Expand Down Expand Up @@ -3470,6 +3470,36 @@ impl CommandEncoder {
destination_offset,
)
}

/// Returns the inner hal CommandEncoder using a callback. The hal command encoder will be `None` if the
/// backend type argument does not match with this wgpu CommandEncoder
///
/// This method will start the wgpu_core level command recording.
///
/// # Safety
///
/// - The raw handle obtained from the hal CommandEncoder must not be manually destroyed
#[cfg(wgpu_core)]
pub unsafe fn as_hal_mut<
A: wgc::hal_api::HalApi,
F: FnOnce(Option<&mut A::CommandEncoder>) -> R,
R,
>(
&mut self,
hal_command_encoder_callback: F,
) -> Option<R> {
use core::id::CommandEncoderId;

self.context
.as_any()
.downcast_ref::<crate::backend::ContextWgpuCore>()
.map(|ctx| unsafe {
ctx.command_encoder_as_hal_mut::<A, F, R>(
CommandEncoderId::from(self.id.unwrap()),
hal_command_encoder_callback,
)
})
}
}

/// [`Features::TIMESTAMP_QUERY_INSIDE_ENCODERS`] must be enabled on the device in order to call these functions.
Expand Down Expand Up @@ -5021,6 +5051,34 @@ impl TextureView {
pub fn global_id(&self) -> Id<Self> {
Id(self.id.global_id(), PhantomData)
}

/// Returns the inner hal TextureView using a callback. The hal texture will be `None` if the
/// backend type argument does not match with this wgpu Texture
///
/// # Safety
///
/// - The raw handle obtained from the hal TextureView must not be manually destroyed
#[cfg(wgpu_core)]
pub unsafe fn as_hal<A: wgc::hal_api::HalApi, F: FnOnce(Option<&A::TextureView>) -> R, R>(
&self,
hal_texture_view_callback: F,
) -> R {
use core::id::TextureViewId;

let texture_view_id = TextureViewId::from(self.id);

if let Some(ctx) = self
.context
.as_any()
.downcast_ref::<crate::backend::ContextWgpuCore>()
{
unsafe {
ctx.texture_view_as_hal::<A, F, R>(texture_view_id, hal_texture_view_callback)
}
} else {
hal_texture_view_callback(None)
}
}
}

impl Sampler {
Expand Down

0 comments on commit ed843f8

Please sign in to comment.