Skip to content

Commit 4516789

Browse files
committed
[wgpu-core] Allow creation of bind groups containing external textures
Adds a `BindingResource` variant for external textures. In core's create_bind_group() implementation, allow binding either external textures or texture views to `BindingType::ExternalTexture` layout entries. In either case, provide HAL with a `hal::ExternalTextureBinding`, consisting of 3 `hal::TextureBinding`s and a `hal::BufferBinding`. In the texture view case we use the device's default params buffer for the buffer. When there are fewer than 3 planes we can simply repeat an existing plane multiple times - the contents of the params buffer will ensure the shader only accesses the correct number of planes anyway. Track the view or external texture in `BindGroupStates` to ensure they remain alive whilst required. And finally, add the corresponding API to wgpu, with an implementation for the wgpu-core backend.
1 parent 7a2067a commit 4516789

File tree

16 files changed

+278
-35
lines changed

16 files changed

+278
-35
lines changed

wgpu-core/src/binding_model.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@ use crate::{
1919
device::{
2020
bgl, Device, DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT,
2121
},
22-
id::{BindGroupLayoutId, BufferId, SamplerId, TextureViewId, TlasId},
22+
id::{BindGroupLayoutId, BufferId, ExternalTextureId, SamplerId, TextureViewId, TlasId},
2323
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
2424
pipeline::{ComputePipeline, RenderPipeline},
2525
resource::{
26-
Buffer, DestroyedResourceError, InvalidResourceError, Labeled, MissingBufferUsageError,
27-
MissingTextureUsageError, ResourceErrorIdent, Sampler, TextureView, Tlas, TrackingData,
26+
Buffer, DestroyedResourceError, ExternalTexture, InvalidResourceError, Labeled,
27+
MissingBufferUsageError, MissingTextureUsageError, ResourceErrorIdent, Sampler,
28+
TextureView, Tlas, TrackingData,
2829
},
2930
resource_log,
3031
snatch::{SnatchGuard, Snatchable},
@@ -492,8 +493,14 @@ impl BindingTypeMaxCountValidator {
492493
/// cbindgen:ignore
493494
#[derive(Clone, Debug)]
494495
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
495-
pub struct BindGroupEntry<'a, B = BufferId, S = SamplerId, TV = TextureViewId, TLAS = TlasId>
496-
where
496+
pub struct BindGroupEntry<
497+
'a,
498+
B = BufferId,
499+
S = SamplerId,
500+
TV = TextureViewId,
501+
TLAS = TlasId,
502+
ET = ExternalTextureId,
503+
> where
497504
[BufferBinding<B>]: ToOwned,
498505
[S]: ToOwned,
499506
[TV]: ToOwned,
@@ -506,15 +513,21 @@ where
506513
pub binding: u32,
507514
#[cfg_attr(
508515
feature = "serde",
509-
serde(bound(deserialize = "BindingResource<'a, B, S, TV, TLAS>: Deserialize<'de>"))
516+
serde(bound(deserialize = "BindingResource<'a, B, S, TV, TLAS, ET>: Deserialize<'de>"))
510517
)]
511518
/// Resource to attach to the binding
512-
pub resource: BindingResource<'a, B, S, TV, TLAS>,
519+
pub resource: BindingResource<'a, B, S, TV, TLAS, ET>,
513520
}
514521

515522
/// cbindgen:ignore
516-
pub type ResolvedBindGroupEntry<'a> =
517-
BindGroupEntry<'a, Arc<Buffer>, Arc<Sampler>, Arc<TextureView>, Arc<Tlas>>;
523+
pub type ResolvedBindGroupEntry<'a> = BindGroupEntry<
524+
'a,
525+
Arc<Buffer>,
526+
Arc<Sampler>,
527+
Arc<TextureView>,
528+
Arc<Tlas>,
529+
Arc<ExternalTexture>,
530+
>;
518531

519532
/// Describes a group of bindings and the resources to be bound.
520533
#[derive(Clone, Debug)]
@@ -526,15 +539,16 @@ pub struct BindGroupDescriptor<
526539
S = SamplerId,
527540
TV = TextureViewId,
528541
TLAS = TlasId,
542+
ET = ExternalTextureId,
529543
> where
530544
[BufferBinding<B>]: ToOwned,
531545
[S]: ToOwned,
532546
[TV]: ToOwned,
533547
<[BufferBinding<B>] as ToOwned>::Owned: fmt::Debug,
534548
<[S] as ToOwned>::Owned: fmt::Debug,
535549
<[TV] as ToOwned>::Owned: fmt::Debug,
536-
[BindGroupEntry<'a, B, S, TV, TLAS>]: ToOwned,
537-
<[BindGroupEntry<'a, B, S, TV, TLAS>] as ToOwned>::Owned: fmt::Debug,
550+
[BindGroupEntry<'a, B, S, TV, TLAS, ET>]: ToOwned,
551+
<[BindGroupEntry<'a, B, S, TV, TLAS, ET>] as ToOwned>::Owned: fmt::Debug,
538552
{
539553
/// Debug label of the bind group.
540554
///
@@ -545,11 +559,12 @@ pub struct BindGroupDescriptor<
545559
#[cfg_attr(
546560
feature = "serde",
547561
serde(bound(
548-
deserialize = "<[BindGroupEntry<'a, B, S, TV, TLAS>] as ToOwned>::Owned: Deserialize<'de>"
562+
deserialize = "<[BindGroupEntry<'a, B, S, TV, TLAS, ET>] as ToOwned>::Owned: Deserialize<'de>"
549563
))
550564
)]
551565
/// The resources to bind to this bind group.
552-
pub entries: Cow<'a, [BindGroupEntry<'a, B, S, TV, TLAS>]>,
566+
#[allow(clippy::type_complexity)]
567+
pub entries: Cow<'a, [BindGroupEntry<'a, B, S, TV, TLAS, ET>]>,
553568
}
554569

555570
/// cbindgen:ignore
@@ -560,6 +575,7 @@ pub type ResolvedBindGroupDescriptor<'a> = BindGroupDescriptor<
560575
Arc<Sampler>,
561576
Arc<TextureView>,
562577
Arc<Tlas>,
578+
Arc<ExternalTexture>,
563579
>;
564580

565581
/// Describes a [`BindGroupLayout`].
@@ -881,8 +897,14 @@ pub type ResolvedBufferBinding = BufferBinding<Arc<Buffer>>;
881897
// They're different enough that it doesn't make sense to share a common type
882898
#[derive(Debug, Clone)]
883899
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
884-
pub enum BindingResource<'a, B = BufferId, S = SamplerId, TV = TextureViewId, TLAS = TlasId>
885-
where
900+
pub enum BindingResource<
901+
'a,
902+
B = BufferId,
903+
S = SamplerId,
904+
TV = TextureViewId,
905+
TLAS = TlasId,
906+
ET = ExternalTextureId,
907+
> where
886908
[BufferBinding<B>]: ToOwned,
887909
[S]: ToOwned,
888910
[TV]: ToOwned,
@@ -909,10 +931,17 @@ where
909931
)]
910932
TextureViewArray(Cow<'a, [TV]>),
911933
AccelerationStructure(TLAS),
934+
ExternalTexture(ET),
912935
}
913936

914-
pub type ResolvedBindingResource<'a> =
915-
BindingResource<'a, Arc<Buffer>, Arc<Sampler>, Arc<TextureView>, Arc<Tlas>>;
937+
pub type ResolvedBindingResource<'a> = BindingResource<
938+
'a,
939+
Arc<Buffer>,
940+
Arc<Sampler>,
941+
Arc<TextureView>,
942+
Arc<Tlas>,
943+
Arc<ExternalTexture>,
944+
>;
916945

917946
#[derive(Clone, Debug, Error)]
918947
#[non_exhaustive]

wgpu-core/src/device/global.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ impl Global {
802802
sampler_storage: &Storage<Fallible<resource::Sampler>>,
803803
texture_view_storage: &Storage<Fallible<resource::TextureView>>,
804804
tlas_storage: &Storage<Fallible<resource::Tlas>>,
805+
external_texture_storage: &Storage<Fallible<resource::ExternalTexture>>,
805806
) -> Result<ResolvedBindGroupEntry<'a>, binding_model::CreateBindGroupError>
806807
{
807808
let resolve_buffer = |bb: &BufferBinding| {
@@ -833,6 +834,12 @@ impl Global {
833834
.get()
834835
.map_err(binding_model::CreateBindGroupError::from)
835836
};
837+
let resolve_external_texture = |id: &id::ExternalTextureId| {
838+
external_texture_storage
839+
.get(*id)
840+
.get()
841+
.map_err(binding_model::CreateBindGroupError::from)
842+
};
836843
let resource = match e.resource {
837844
BindingResource::Buffer(ref buffer) => {
838845
ResolvedBindingResource::Buffer(resolve_buffer(buffer)?)
@@ -867,6 +874,9 @@ impl Global {
867874
BindingResource::AccelerationStructure(ref tlas) => {
868875
ResolvedBindingResource::AccelerationStructure(resolve_tlas(tlas)?)
869876
}
877+
BindingResource::ExternalTexture(ref et) => {
878+
ResolvedBindingResource::ExternalTexture(resolve_external_texture(et)?)
879+
}
870880
};
871881
Ok(ResolvedBindGroupEntry {
872882
binding: e.binding,
@@ -879,6 +889,7 @@ impl Global {
879889
let texture_view_guard = hub.texture_views.read();
880890
let sampler_guard = hub.samplers.read();
881891
let tlas_guard = hub.tlas_s.read();
892+
let external_texture_guard = hub.external_textures.read();
882893
desc.entries
883894
.iter()
884895
.map(|e| {
@@ -888,6 +899,7 @@ impl Global {
888899
&sampler_guard,
889900
&texture_view_guard,
890901
&tlas_guard,
902+
&external_texture_guard,
891903
)
892904
})
893905
.collect::<Result<Vec<_>, _>>()

0 commit comments

Comments
 (0)