Skip to content

Commit

Permalink
Implement queue.copy_external_image_to_texture for WebGL2 and improve…
Browse files Browse the repository at this point in the history
… WebGPU Impl (#3288)

Co-authored-by: Teodor Tanasoaia <28601907+teoxoy@users.noreply.github.com>
Closes #1888
  • Loading branch information
cwfitzgerald authored Jan 24, 2023
1 parent 964c94a commit 95a760b
Show file tree
Hide file tree
Showing 25 changed files with 1,220 additions and 63 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non

`Instance::create_surface()` now returns `Result<Surface, CreateSurfaceError>` instead of `Surface`. This allows an error to be returned instead of panicking if the given window is a HTML canvas and obtaining a WebGPU or WebGL 2 context fails. (No other platforms currently report any errors through this path.) By @kpreid in [#3052](https://github.com/gfx-rs/wgpu/pull/3052/)

#### `Queue::copy_external_image_to_texture` on WebAssembly

There's a new api `Queue::copy_external_image_to_texture` which allows you to create wgpu textures from various web image primitives. Specificically from HtmlVideoElement, HtmlCanvasElement, OffscreenCanvas, and ImageBitmap. This provides multiple low-copy ways of interacting with the browser. WebGL is also supported, though WebGL has some additional restrictions, represented by the UNRESTRICTED_EXTERNAL_IMAGE_COPIES downlevel flag. By @cwfitzgerald in [#3288](https://github.com/gfx-rs/wgpu/pull/3288)

#### Instance creation now takes `InstanceDescriptor` instead of `Backends`

`Instance::new()` and `hub::Global::new()` now take an `InstanceDescriptor` struct which cointains both the existing `Backends` selection as well as a new `Dx12Compiler` field for selecting which Dx12 shader compiler to use.
Expand Down Expand Up @@ -300,14 +304,12 @@ let texture = device.create_texture(&wgpu::TextureDescriptor {

- Don't use a pointer to a local copy of a `PhysicalDeviceDriverProperties` struct after it has gone out of scope. In fact, don't make a local copy at all. Introduce a helper function for building `CStr`s from C character arrays, and remove some `unsafe` blocks. By @jimblandy in [#3076](https://github.com/gfx-rs/wgpu/pull/3076).


## wgpu-0.14.2 (2022-11-28)

### Bug Fixes

- Fix incorrect offset in `get_mapped_range` by @nical in [#3233](https://github.com/gfx-rs/wgpu/pull/3233)


## wgpu-0.14.1 (2022-11-02)

### Bug Fixes
Expand Down
48 changes: 46 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ env_logger = "0.9"
futures-intrusive = "0.4"
fxhash = "0.2.1"
glam = "0.21.3"
image = { version = "0.24", default-features = false, features = ["png"] }
libloading = "0.7"
libc = "0.2"
log = "0.4"
Expand Down
21 changes: 15 additions & 6 deletions wgpu-core/src/command/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::iter;

pub type ImageCopyBuffer = wgt::ImageCopyBuffer<BufferId>;
pub type ImageCopyTexture = wgt::ImageCopyTexture<TextureId>;
pub type ImageCopyTextureTagged = wgt::ImageCopyTextureTagged<TextureId>;

#[derive(Clone, Copy, Debug)]
pub enum CopySide {
Expand All @@ -44,6 +45,8 @@ pub enum TransferError {
MissingCopySrcUsageFlag,
#[error("destination buffer/texture is missing the `COPY_DST` usage flag")]
MissingCopyDstUsageFlag(Option<BufferId>, Option<TextureId>),
#[error("destination texture is missing the `RENDER_ATTACHMENT` usage flag")]
MissingRenderAttachmentUsageFlag(TextureId),
#[error("copy of {start_offset}..{end_offset} would end up overrunning the bounds of the {side:?} buffer of size {buffer_size}")]
BufferOverrun {
start_offset: BufferAddress,
Expand All @@ -66,6 +69,8 @@ pub enum TransferError {
},
#[error("unable to select texture mip level {level} out of {total}")]
InvalidTextureMipLevel { level: u32, total: u32 },
#[error("texture dimension must be 2D when copying from an external texture")]
InvalidDimensionExternal(TextureId),
#[error("buffer offset {0} is not aligned to block size or `COPY_BUFFER_ALIGNMENT`")]
UnalignedBufferOffset(BufferAddress),
#[error("copy size {0} does not respect `COPY_BUFFER_ALIGNMENT`")]
Expand Down Expand Up @@ -102,6 +107,10 @@ pub enum TransferError {
format: wgt::TextureFormat,
aspect: wgt::TextureAspect,
},
#[error(
"copying to textures with format {0:?} is forbidden when copying from external texture"
)]
ExternalCopyToForbiddenTextureFormat(wgt::TextureFormat),
#[error("the entire texture must be copied when copying from depth texture")]
InvalidDepthTextureExtent,
#[error(
Expand Down Expand Up @@ -701,8 +710,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[cfg(feature = "trace")]
if let Some(ref mut list) = cmd_buf.commands {
list.push(TraceCommand::CopyBufferToTexture {
src: source.clone(),
dst: destination.clone(),
src: *source,
dst: *destination,
size: *copy_size,
});
}
Expand Down Expand Up @@ -837,8 +846,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[cfg(feature = "trace")]
if let Some(ref mut list) = cmd_buf.commands {
list.push(TraceCommand::CopyTextureToBuffer {
src: source.clone(),
dst: destination.clone(),
src: *source,
dst: *destination,
size: *copy_size,
});
}
Expand Down Expand Up @@ -1002,8 +1011,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[cfg(feature = "trace")]
if let Some(ref mut list) = cmd_buf.commands {
list.push(TraceCommand::CopyTextureToTexture {
src: source.clone(),
dst: destination.clone(),
src: *source,
dst: *destination,
size: *copy_size,
});
}
Expand Down
24 changes: 24 additions & 0 deletions wgpu-core/src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,30 @@ pub fn is_valid_copy_dst_texture_format(
}
}

#[cfg_attr(
any(not(target_arch = "wasm32"), feature = "emscripten"),
allow(unused)
)]
pub fn is_valid_external_image_copy_dst_texture_format(format: wgt::TextureFormat) -> bool {
use wgt::TextureFormat as Tf;
match format {
Tf::R8Unorm
| Tf::R16Float
| Tf::R32Float
| Tf::Rg8Unorm
| Tf::Rg16Float
| Tf::Rg32Float
| Tf::Rgba8Unorm
| Tf::Rgba8UnormSrgb
| Tf::Bgra8Unorm
| Tf::Bgra8UnormSrgb
| Tf::Rgb10a2Unorm
| Tf::Rgba16Float
| Tf::Rgba32Float => true,
_ => false,
}
}

pub fn map_buffer_usage(usage: wgt::BufferUsages) -> hal::BufferUses {
let mut u = hal::BufferUses::empty();
u.set(
Expand Down
Loading

0 comments on commit 95a760b

Please sign in to comment.