Skip to content

Commit

Permalink
allow creation of wgpu_hal textures for gles backend
Browse files Browse the repository at this point in the history
This should be enough to allow external textures to work on Linux. For Android, we still need to implement logic to generate shaders with samplerOESExternal and select the correct shader depending on the type of texture being created.
  • Loading branch information
i509VCB committed Sep 27, 2022
1 parent 2c1d7a8 commit 9abc9eb
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 46 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ SurfaceConfiguration {
- Split Blendability and Filterability into Two Different TextureFormatFeatureFlags; by @stakka in [#3012](https://github.com/gfx-rs/wgpu/pull/3012)
- Expose `alpha_mode` on SurfaceConfiguration, by @jinleili in [#2836](https://github.com/gfx-rs/wgpu/pull/2836)
- Introduce fields for driver name and info in `AdapterInfo`, by @i509VCB in [#3037](https://github.com/gfx-rs/wgpu/pull/3037)
- Add way to create gles hal textures from raw gl names to allow externally managed textures. By @i509VCB [#3046](https://github.com/gfx-rs/wgpu/pull/3046)

### Bug Fixes

Expand Down Expand Up @@ -126,6 +127,7 @@ SurfaceConfiguration {
- Provide a means for `wgpu` users to access `vk::Queue` and the queue index. By @anlumo in [#2950](https://github.com/gfx-rs/wgpu/pull/2950)
- Use the use effective api version for determining device features instead of wrongly assuming `VkPhysicalDeviceProperties.apiVersion`
is the actual version of the device. By @i509VCB in [#3011](https://github.com/gfx-rs/wgpu/pull/3011)
- `DropGuard` has been moved to the root of the wgpu-hal crate. By @i509VCB [#3046](https://github.com/gfx-rs/wgpu/pull/3046)

### Performance

Expand Down
3 changes: 1 addition & 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 @@ -28,6 +28,7 @@ default-members = ["wgpu", "wgpu-hal", "wgpu-info"]
[patch.crates-io]
#naga = { path = "../naga" }
#glow = { path = "../glow" }
glow = { git = "https://github.com/grovesNL/glow/", rev = "c8a011fcd57a5c68cc917ed394baa484bdefc909" }
#d3d12 = { path = "../d3d12-rs" }
#metal = { path = "../metal-rs" }
#web-sys = { path = "../wasm-bindgen/crates/web-sys" }
Expand Down
4 changes: 4 additions & 0 deletions deno_webgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.19", features = ["full"] }
wgpu-core = { path = "../wgpu-core", features = ["trace", "replay", "serde", "strict_asserts"] }
wgpu-types = { path = "../wgpu-types", features = ["trace", "replay", "serde"] }

# TODO: Remove when wgpu depends on new glow release.
[patch.crates-io]
glow = { git = "https://github.com/grovesNL/glow/", rev = "c8a011fcd57a5c68cc917ed394baa484bdefc909" }
3 changes: 2 additions & 1 deletion wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,13 @@ gpu-descriptor = { version = "0.2", optional = true }
smallvec = { version = "1", optional = true, features = ["union"] }

# backend: Gles
glow = { version = "0.11.1", optional = true }
glow = { version = "0.11.2", optional = true }

# backend: Dx12
bit-set = { version = "0.5", optional = true }
range-alloc = { version = "0.1", optional = true }


[dependencies.wgt]
package = "wgpu-types"
path = "../wgpu-types"
Expand Down
11 changes: 11 additions & 0 deletions wgpu-hal/src/auxil/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ pub fn align_to(value: u32, alignment: u32) -> u32 {
}

impl crate::CopyExtent {
pub fn map_extent_to_copy_size(extent: &wgt::Extent3d, dim: wgt::TextureDimension) -> Self {
Self {
width: extent.width,
height: extent.height,
depth: match dim {
wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => 1,
wgt::TextureDimension::D3 => extent.depth_or_array_layers,
},
}
}

pub fn min(&self, other: &Self) -> Self {
Self {
width: self.width.min(other.width),
Expand Down
118 changes: 84 additions & 34 deletions wgpu-hal/src/gles/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,77 @@ impl CompilationContext<'_> {
}

impl super::Device {
/// # Safety
///
/// - `name` must be created respecting `desc`
/// - `name` must be a texture
/// - If `drop_guard` is `Some`, the application must manually destroy the texture id. This
/// can be done inside the `Drop` impl of `drop_guard`.
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))] // create_texture_from_gl_name is only available on native.
pub unsafe fn texture_from_raw(
&self,
name: u32,
desc: &crate::TextureDescriptor,
drop_guard: Option<crate::DropGuard>,
) -> super::Texture {
let name = std::num::NonZeroU32::new(name).expect("Invalid GL name");
let mut copy_size = crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension);

let (target, _, is_cubemap) = super::Texture::get_info_from_desc(&mut copy_size, desc);

super::Texture {
inner: super::TextureInner::Texture {
raw: glow::NativeTexture(name),
target,
},
drop_guard,
mip_level_count: desc.mip_level_count,
array_layer_count: if desc.dimension == wgt::TextureDimension::D2 {
desc.size.depth_or_array_layers
} else {
1
},
format: desc.format,
format_desc: self.shared.describe_texture_format(desc.format),
copy_size,
is_cubemap,
}
}

/// # Safety
///
/// - `name` must be created respecting `desc`
/// - `name` must be a renderbuffer
/// - If `drop_guard` is `Some`, the application must manually destroy the texture id. This
/// can be done inside the `Drop` impl of `drop_guard`.
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))]
pub unsafe fn texture_from_raw_renderbuffer(
&self,
name: u32,
desc: &crate::TextureDescriptor,
drop_guard: Option<crate::DropGuard>,
) -> super::Texture {
let name = std::num::NonZeroU32::new(name).expect("Invalid GL name");
let copy_size = crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension);

super::Texture {
inner: super::TextureInner::Renderbuffer {
raw: glow::NativeRenderbuffer(name),
},
drop_guard,
mip_level_count: desc.mip_level_count,
array_layer_count: if desc.dimension == wgt::TextureDimension::D2 {
desc.size.depth_or_array_layers
} else {
1
},
format: desc.format,
format_desc: self.shared.describe_texture_format(desc.format),
copy_size,
is_cubemap: false,
}
}

unsafe fn compile_shader(
gl: &glow::Context,
shader: &str,
Expand Down Expand Up @@ -581,32 +652,8 @@ impl crate::Device<super::Api> for super::Device {
(super::TextureInner::Renderbuffer { raw }, false)
} else {
let raw = gl.create_texture().unwrap();
let (target, is_3d, is_cubemap) = match desc.dimension {
wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => {
if desc.size.depth_or_array_layers > 1 {
//HACK: detect a cube map
let cube_count = if desc.size.width == desc.size.height
&& desc.size.depth_or_array_layers % 6 == 0
&& desc.sample_count == 1
{
Some(desc.size.depth_or_array_layers / 6)
} else {
None
};
match cube_count {
None => (glow::TEXTURE_2D_ARRAY, true, false),
Some(1) => (glow::TEXTURE_CUBE_MAP, false, true),
Some(_) => (glow::TEXTURE_CUBE_MAP_ARRAY, true, true),
}
} else {
(glow::TEXTURE_2D, false, false)
}
}
wgt::TextureDimension::D3 => {
copy_size.depth = desc.size.depth_or_array_layers;
(glow::TEXTURE_3D, true, false)
}
};
let (target, is_3d, is_cubemap) =
super::Texture::get_info_from_desc(&mut copy_size, desc);

gl.bind_texture(target, Some(raw));
//Note: this has to be done before defining the storage!
Expand Down Expand Up @@ -663,6 +710,7 @@ impl crate::Device<super::Api> for super::Device {

Ok(super::Texture {
inner,
drop_guard: None,
mip_level_count: desc.mip_level_count,
array_layer_count: if desc.dimension == wgt::TextureDimension::D2 {
desc.size.depth_or_array_layers
Expand All @@ -676,14 +724,16 @@ impl crate::Device<super::Api> for super::Device {
})
}
unsafe fn destroy_texture(&self, texture: super::Texture) {
let gl = &self.shared.context.lock();
match texture.inner {
super::TextureInner::Renderbuffer { raw, .. } => {
gl.delete_renderbuffer(raw);
}
super::TextureInner::DefaultRenderbuffer => {}
super::TextureInner::Texture { raw, .. } => {
gl.delete_texture(raw);
if texture.drop_guard.is_none() {
let gl = &self.shared.context.lock();
match texture.inner {
super::TextureInner::Renderbuffer { raw, .. } => {
gl.delete_renderbuffer(raw);
}
super::TextureInner::DefaultRenderbuffer => {}
super::TextureInner::Texture { raw, .. } => {
gl.delete_texture(raw);
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/gles/egl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,7 @@ impl crate::Surface<super::Api> for Surface {
inner: super::TextureInner::Renderbuffer {
raw: sc.renderbuffer,
},
drop_guard: None,
array_layer_count: 1,
mip_level_count: 1,
format: sc.format,
Expand Down
41 changes: 39 additions & 2 deletions wgpu-hal/src/gles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ mod conv;
mod device;
mod queue;

use crate::{CopyExtent, TextureDescriptor};

#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))]
pub use self::egl::{AdapterContext, AdapterContextLock};
#[cfg(any(not(target_arch = "wasm32"), feature = "emscripten"))]
Expand Down Expand Up @@ -265,19 +267,21 @@ impl TextureInner {
#[derive(Debug)]
pub struct Texture {
inner: TextureInner,
drop_guard: Option<crate::DropGuard>,
mip_level_count: u32,
array_layer_count: u32,
format: wgt::TextureFormat,
#[allow(unused)]
format_desc: TextureFormatDesc,
copy_size: crate::CopyExtent,
copy_size: CopyExtent,
is_cubemap: bool,
}

impl Texture {
pub fn default_framebuffer(format: wgt::TextureFormat) -> Self {
Self {
inner: TextureInner::DefaultRenderbuffer,
drop_guard: None,
mip_level_count: 1,
array_layer_count: 1,
format,
Expand All @@ -286,14 +290,47 @@ impl Texture {
external: 0,
data_type: 0,
},
copy_size: crate::CopyExtent {
copy_size: CopyExtent {
width: 0,
height: 0,
depth: 0,
},
is_cubemap: false,
}
}

/// Returns the `target`, whether the image is 3d and whether the image is a cubemap.
fn get_info_from_desc(
copy_size: &mut CopyExtent,
desc: &TextureDescriptor,
) -> (u32, bool, bool) {
match desc.dimension {
wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => {
if desc.size.depth_or_array_layers > 1 {
//HACK: detect a cube map
let cube_count = if desc.size.width == desc.size.height
&& desc.size.depth_or_array_layers % 6 == 0
&& desc.sample_count == 1
{
Some(desc.size.depth_or_array_layers / 6)
} else {
None
};
match cube_count {
None => (glow::TEXTURE_2D_ARRAY, true, false),
Some(1) => (glow::TEXTURE_CUBE_MAP, false, true),
Some(_) => (glow::TEXTURE_CUBE_MAP_ARRAY, true, true),
}
} else {
(glow::TEXTURE_2D, false, false)
}
}
wgt::TextureDimension::D3 => {
copy_size.depth = desc.size.depth_or_array_layers;
(glow::TEXTURE_3D, true, false)
}
}
}
}

#[derive(Clone, Debug)]
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/gles/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ impl crate::Surface<super::Api> for Surface {
raw: self.texture.unwrap(),
target: glow::TEXTURE_2D,
},
drop_guard: None,
array_layer_count: 1,
mip_level_count: 1,
format: sc.format,
Expand Down
3 changes: 3 additions & 0 deletions wgpu-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ pub type Label<'a> = Option<&'a str>;
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>;

#[derive(Clone, Debug, PartialEq, Error)]
pub enum DeviceError {
#[error("out of memory")]
Expand Down
4 changes: 2 additions & 2 deletions wgpu-hal/src/vulkan/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ impl super::Device {
pub unsafe fn texture_from_raw(
vk_image: vk::Image,
desc: &crate::TextureDescriptor,
drop_guard: Option<super::DropGuard>,
drop_guard: Option<crate::DropGuard>,
) -> super::Texture {
super::Texture {
raw: vk_image,
Expand All @@ -619,7 +619,7 @@ impl super::Device {
aspects: crate::FormatAspects::from(desc.format),
format_info: desc.format.describe(),
raw_flags: vk::ImageCreateFlags::empty(),
copy_size: conv::map_extent_to_copy_size(&desc.size, desc.dimension),
copy_size: crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension),
}
}

Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl super::Instance {
extensions: Vec<&'static CStr>,
flags: crate::InstanceFlags,
has_nv_optimus: bool,
drop_guard: Option<super::DropGuard>,
drop_guard: Option<crate::DropGuard>,
) -> Result<Self, crate::InstanceError> {
log::info!("Instance version: 0x{:x}", driver_api_version);

Expand Down
6 changes: 2 additions & 4 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ use parking_lot::Mutex;
const MILLIS_TO_NANOS: u64 = 1_000_000;
const MAX_TOTAL_ATTACHMENTS: usize = crate::MAX_COLOR_ATTACHMENTS * 2 + 1;

pub type DropGuard = Box<dyn std::any::Any + Send + Sync>;

#[derive(Clone)]
pub struct Api;

Expand Down Expand Up @@ -82,7 +80,7 @@ struct DebugUtils {
pub struct InstanceShared {
raw: ash::Instance,
extensions: Vec<&'static CStr>,
drop_guard: Option<DropGuard>,
drop_guard: Option<crate::DropGuard>,
flags: crate::InstanceFlags,
debug_utils: Option<DebugUtils>,
get_physical_device_properties: Option<khr::GetPhysicalDeviceProperties2>,
Expand Down Expand Up @@ -347,7 +345,7 @@ pub struct Buffer {
#[derive(Debug)]
pub struct Texture {
raw: vk::Image,
drop_guard: Option<DropGuard>,
drop_guard: Option<crate::DropGuard>,
block: Option<gpu_alloc::MemoryBlock<vk::DeviceMemory>>,
usage: crate::TextureUses,
aspects: crate::FormatAspects,
Expand Down

0 comments on commit 9abc9eb

Please sign in to comment.