Add new BindingResource type SamplerArray (#2113)

* implemented SamplerArray

* modified shaders

* fixed doc

* fixed code format
This commit is contained in:
dan 2021-11-22 20:19:46 +08:00 committed by GitHub
parent 8c0c01b338
commit cd59c76e3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 51 additions and 12 deletions

View File

@ -663,6 +663,7 @@ pub enum BindingResource<'a> {
Buffer(BufferBinding),
BufferArray(Cow<'a, [BufferBinding]>),
Sampler(SamplerId),
SamplerArray(Cow<'a, [SamplerId]>),
TextureView(TextureViewId),
TextureViewArray(Cow<'a, [TextureViewId]>),
}

View File

@ -1202,7 +1202,10 @@ impl<A: HalApi> Device<A> {
false => WritableStorage::Yes,
},
),
Bt::Sampler { .. } => (None, WritableStorage::No),
Bt::Sampler { .. } => (
Some(wgt::Features::TEXTURE_BINDING_ARRAY),
WritableStorage::No,
),
Bt::Texture { .. } => (
Some(wgt::Features::TEXTURE_BINDING_ARRAY),
WritableStorage::No,
@ -1618,6 +1621,21 @@ impl<A: HalApi> Device<A> {
}
}
}
Br::SamplerArray(ref bindings_array) => {
let num_bindings = bindings_array.len();
Self::check_array_binding(self.features, decl.count, num_bindings)?;
let res_index = hal_samplers.len();
for &id in bindings_array.iter() {
let sampler = used
.samplers
.use_extend(&*sampler_guard, id, (), ())
.map_err(|_| Error::InvalidSampler(id))?;
hal_samplers.push(&sampler.raw);
}
(res_index, num_bindings)
}
Br::TextureView(id) => {
let view = used
.views

View File

@ -5,13 +5,13 @@ layout(location = 1) flat in int v_Index; // dynamically non-uniform
layout(location = 0) out vec4 o_Color;
layout(set = 0, binding = 0) uniform texture2D u_Textures[2];
layout(set = 0, binding = 1) uniform sampler u_Sampler;
layout(set = 0, binding = 1) uniform sampler u_Sampler[2];
void main() {
if (v_Index == 0) {
o_Color = vec4(texture(sampler2D(u_Textures[0], u_Sampler), v_TexCoord).rgb, 1.0);
o_Color = vec4(texture(sampler2D(u_Textures[0], u_Sampler[0]), v_TexCoord).rgb, 1.0);
} else if (v_Index == 1) {
o_Color = vec4(texture(sampler2D(u_Textures[1], u_Sampler), v_TexCoord).rgb, 1.0);
o_Color = vec4(texture(sampler2D(u_Textures[1], u_Sampler[1]), v_TexCoord).rgb, 1.0);
} else {
// We need to write something to output color
o_Color = vec4(0.0, 0.0, 1.0, 0.0);

View File

@ -189,7 +189,7 @@ impl framework::Example for Example {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
count: NonZeroU32::new(2),
},
],
});
@ -205,7 +205,7 @@ impl framework::Example for Example {
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&sampler),
resource: wgpu::BindingResource::SamplerArray(&[&sampler, &sampler]),
},
],
layout: &bind_group_layout,

View File

@ -7,8 +7,8 @@ layout(location = 1) nonuniformEXT flat in int v_Index; // dynamically non-unif
layout(location = 0) out vec4 o_Color;
layout(set = 0, binding = 0) uniform texture2D u_Textures[2];
layout(set = 0, binding = 1) uniform sampler u_Sampler;
layout(set = 0, binding = 1) uniform sampler u_Sampler[2];
void main() {
o_Color = vec4(texture(sampler2D(u_Textures[v_Index], u_Sampler), v_TexCoord).rgb, 1.0);
o_Color = vec4(texture(sampler2D(u_Textures[v_Index], u_Sampler[v_Index]), v_TexCoord).rgb, 1.0);
}

View File

@ -5,11 +5,11 @@ layout(location = 1) flat in int v_Index; // dynamically non-uniform
layout(location = 0) out vec4 o_Color;
layout(set = 0, binding = 0) uniform texture2D u_Textures[2];
layout(set = 0, binding = 1) uniform sampler u_Sampler;
layout(set = 0, binding = 1) uniform sampler u_Sampler[2];
layout(push_constant) uniform Uniforms {
int u_Index; // dynamically uniform
};
void main() {
o_Color = vec4(texture(sampler2D(u_Textures[u_Index], u_Sampler), v_TexCoord).rgb, 1.0);
o_Color = vec4(texture(sampler2D(u_Textures[u_Index], u_Sampler[u_Index]), v_TexCoord).rgb, 1.0);
}

View File

@ -7,8 +7,8 @@ layout(location = 1) nonuniformEXT flat in int v_Index; // dynamically non-unif
layout(location = 0) out vec4 o_Color;
layout(set = 0, binding = 0) uniform texture2D u_Textures[];
layout(set = 0, binding = 1) uniform sampler u_Sampler;
layout(set = 0, binding = 1) uniform sampler u_Sampler[];
void main() {
o_Color = vec4(texture(sampler2D(u_Textures[v_Index], u_Sampler), v_TexCoord).rgb, 1.0);
o_Color = vec4(texture(sampler2D(u_Textures[v_Index], u_Sampler[v_Index]), v_TexCoord).rgb, 1.0);
}

View File

@ -1114,15 +1114,20 @@ impl crate::Context for Context {
use wgc::binding_model as bm;
let mut arrayed_texture_views = Vec::new();
let mut arrayed_samplers = Vec::new();
if device.features.contains(Features::TEXTURE_BINDING_ARRAY) {
// gather all the array view IDs first
for entry in desc.entries.iter() {
if let BindingResource::TextureViewArray(array) = entry.resource {
arrayed_texture_views.extend(array.iter().map(|view| view.id));
}
if let BindingResource::SamplerArray(array) = entry.resource {
arrayed_samplers.extend(array.iter().map(|sampler| sampler.id));
}
}
}
let mut remaining_arrayed_texture_views = &arrayed_texture_views[..];
let mut remaining_arrayed_samplers = &arrayed_samplers[..];
let mut arrayed_buffer_bindings = Vec::new();
if device.features.contains(Features::BUFFER_BINDING_ARRAY) {
@ -1161,6 +1166,11 @@ impl crate::Context for Context {
bm::BindingResource::BufferArray(Borrowed(slice))
}
BindingResource::Sampler(sampler) => bm::BindingResource::Sampler(sampler.id),
BindingResource::SamplerArray(array) => {
let slice = &remaining_arrayed_samplers[..array.len()];
remaining_arrayed_samplers = &remaining_arrayed_samplers[array.len()..];
bm::BindingResource::SamplerArray(Borrowed(slice))
}
BindingResource::TextureView(texture_view) => {
bm::BindingResource::TextureView(texture_view.id)
}

View File

@ -1380,6 +1380,9 @@ impl crate::Context for Context {
panic!("Web backend does not support arrays of buffers")
}
crate::BindingResource::Sampler(sampler) => JsValue::from(sampler.id.0.clone()),
crate::BindingResource::SamplerArray(..) => {
panic!("Web backend does not support arrays of samplers")
}
crate::BindingResource::TextureView(texture_view) => {
JsValue::from(texture_view.id.0.clone())
}

View File

@ -1005,6 +1005,13 @@ pub enum BindingResource<'a> {
///
/// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set to None.
Sampler(&'a Sampler),
/// Binding is backed by an array of samplers.
///
/// [`Features::TEXTURE_BINDING_ARRAY`] must be supported to use this feature.
///
/// Corresponds to [`wgt::BindingType::Sampler`] with [`BindGroupLayoutEntry::count`] set
/// to Some.
SamplerArray(&'a [&'a Sampler]),
/// Binding is backed by a texture.
///
/// Corresponds to [`wgt::BindingType::Texture`] and [`wgt::BindingType::StorageTexture`] with