Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more hal methods #5452

Merged
merged 8 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,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 @@ -122,7 +127,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 @@ -168,7 +173,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<
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
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
49 changes: 44 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,50 @@ 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)
}
}

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
62 changes: 59 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,34 @@ 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
///
/// # 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 +5049,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
Loading