Skip to content

Commit

Permalink
[WebGL] Allow creating a texture from an external `web_sys::WebGlFram…
Browse files Browse the repository at this point in the history
…ebuffer` and writing to it (#2609)
  • Loading branch information
expenses authored Jan 24, 2023
1 parent 95a760b commit c039a74
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
24 changes: 20 additions & 4 deletions wgpu-hal/src/gles/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,20 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
self.state.has_pass_label = true;
}

let rendering_to_external_framebuffer = desc
.color_attachments
.iter()
.filter_map(|at| at.as_ref())
.any(|at| match at.target.view.inner {
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
super::TextureInner::ExternalFramebuffer { .. } => true,
_ => false,
});

if rendering_to_external_framebuffer && desc.color_attachments.len() != 1 {
panic!("Multiple render attachments with external framebuffers are not supported.");
}

match desc
.color_attachments
.first()
Expand Down Expand Up @@ -514,10 +528,12 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
}
}

// set the draw buffers and states
self.cmd_buffer
.commands
.push(C::SetDrawColorBuffers(desc.color_attachments.len() as u8));
if !rendering_to_external_framebuffer {
// set the draw buffers and states
self.cmd_buffer
.commands
.push(C::SetDrawColorBuffers(desc.color_attachments.len() as u8));
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,8 @@ impl crate::Device<super::Api> for super::Device {
super::TextureInner::Texture { raw, .. } => {
unsafe { gl.delete_texture(raw) };
}
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
super::TextureInner::ExternalFramebuffer { .. } => {}
}
}

Expand Down
38 changes: 25 additions & 13 deletions wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ impl Default for VertexAttribKind {
}

#[derive(Clone, Debug)]
struct TextureFormatDesc {
internal: u32,
external: u32,
data_type: u32,
pub struct TextureFormatDesc {
pub internal: u32,
pub external: u32,
pub data_type: u32,
}

struct AdapterShared {
Expand Down Expand Up @@ -249,7 +249,7 @@ unsafe impl Sync for Buffer {}
unsafe impl Send for Buffer {}

#[derive(Clone, Debug)]
enum TextureInner {
pub enum TextureInner {
Renderbuffer {
raw: glow::Renderbuffer,
},
Expand All @@ -258,30 +258,42 @@ enum TextureInner {
raw: glow::Texture,
target: BindTarget,
},
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
ExternalFramebuffer {
inner: web_sys::WebGlFramebuffer,
},
}

// SAFE: WASM doesn't have threads
#[cfg(target_arch = "wasm32")]
unsafe impl Send for TextureInner {}
#[cfg(target_arch = "wasm32")]
unsafe impl Sync for TextureInner {}

impl TextureInner {
fn as_native(&self) -> (glow::Texture, BindTarget) {
match *self {
Self::Renderbuffer { .. } | Self::DefaultRenderbuffer => {
panic!("Unexpected renderbuffer");
}
Self::Texture { raw, target } => (raw, target),
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
Self::ExternalFramebuffer { .. } => panic!("Unexpected external framebuffer"),
}
}
}

#[derive(Debug)]
pub struct Texture {
inner: TextureInner,
drop_guard: Option<crate::DropGuard>,
mip_level_count: u32,
array_layer_count: u32,
format: wgt::TextureFormat,
pub inner: TextureInner,
pub drop_guard: Option<crate::DropGuard>,
pub mip_level_count: u32,
pub array_layer_count: u32,
pub format: wgt::TextureFormat,
#[allow(unused)]
format_desc: TextureFormatDesc,
copy_size: CopyExtent,
is_cubemap: bool,
pub format_desc: TextureFormatDesc,
pub copy_size: CopyExtent,
pub is_cubemap: bool,
}

impl Texture {
Expand Down
4 changes: 4 additions & 0 deletions wgpu-hal/src/gles/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ impl super::Queue {
};
}
}
#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
super::TextureInner::ExternalFramebuffer { ref inner } => unsafe {
gl.bind_external_framebuffer(glow::FRAMEBUFFER, inner);
},
}
}

Expand Down
18 changes: 12 additions & 6 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,23 @@ compile_error!("Metal API enabled on non-Apple OS. If your project is not using
#[cfg(all(feature = "dx12", not(windows)))]
compile_error!("DX12 API enabled on non-Windows OS. If your project is not using resolver=\"2\" in Cargo.toml, it should.");

/// DirectX11 API internals.
#[cfg(all(feature = "dx11", windows))]
mod dx11;
pub mod dx11;
/// DirectX12 API internals.
#[cfg(all(feature = "dx12", windows))]
mod dx12;
mod empty;
pub mod dx12;
/// A dummy API implementation.
pub mod empty;
/// GLES API internals.
#[cfg(all(feature = "gles"))]
mod gles;
pub mod gles;
/// Metal API internals.
#[cfg(all(feature = "metal"))]
mod metal;
pub mod metal;
/// Vulkan API internals.
#[cfg(feature = "vulkan")]
mod vulkan;
pub mod vulkan;

pub mod auxil;
pub mod api {
Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/backend/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Context {
Ok((device, queue))
}

#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))]
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten", feature = "webgl"))]
pub unsafe fn create_texture_from_hal<A: wgc::hub::HalApi>(
&self,
hal_texture: A::Texture,
Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2118,7 +2118,7 @@ impl Device {
/// - `hal_texture` must be created from this device internal handle
/// - `hal_texture` must be created respecting `desc`
/// - `hal_texture` must be initialized
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))]
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten", feature = "webgl"))]
pub unsafe fn create_texture_from_hal<A: wgc::hub::HalApi>(
&self,
hal_texture: A::Texture,
Expand Down

0 comments on commit c039a74

Please sign in to comment.