From cd59c76e3a9b05525450f245e73aceb55cb9e035 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Nov 2021 20:19:46 +0800 Subject: [PATCH] Add new BindingResource type SamplerArray (#2113) * implemented SamplerArray * modified shaders * fixed doc * fixed code format --- wgpu-core/src/binding_model.rs | 1 + wgpu-core/src/device/mod.rs | 20 +++++++++++++++++- wgpu/examples/texture-arrays/constant.frag | 6 +++--- .../examples/texture-arrays/constant.frag.spv | Bin 1348 -> 1708 bytes wgpu/examples/texture-arrays/main.rs | 4 ++-- wgpu/examples/texture-arrays/non-uniform.frag | 4 ++-- .../texture-arrays/non-uniform.frag.spv | Bin 976 -> 1328 bytes wgpu/examples/texture-arrays/uniform.frag | 4 ++-- wgpu/examples/texture-arrays/uniform.frag.spv | Bin 996 -> 1376 bytes .../texture-arrays/unsized-non-uniform.frag | 4 ++-- .../unsized-non-uniform.frag.spv | Bin 948 -> 1296 bytes wgpu/src/backend/direct.rs | 10 +++++++++ wgpu/src/backend/web.rs | 3 +++ wgpu/src/lib.rs | 7 ++++++ 14 files changed, 51 insertions(+), 12 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index bc11434c7..030574842 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -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]>), } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 9f4507a12..e9366b733 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -1202,7 +1202,10 @@ impl Device { 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 Device { } } } + 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 diff --git a/wgpu/examples/texture-arrays/constant.frag b/wgpu/examples/texture-arrays/constant.frag index c4cb2894b..a622de379 100644 --- a/wgpu/examples/texture-arrays/constant.frag +++ b/wgpu/examples/texture-arrays/constant.frag @@ -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); diff --git a/wgpu/examples/texture-arrays/constant.frag.spv b/wgpu/examples/texture-arrays/constant.frag.spv index cd85dc6401e47b159ced12ee757ba7f792854f25..2ac4287204008167e8d26ba232da075561e25a55 100644 GIT binary patch literal 1708 zcmZ9KSx-|@6oogm#R4+PB!hAb&R|6aM3KpgjY*SgF#32y+WXL?v`wero4?1O;h%Cy zOkCgPo^awxR`%X&Pv@?4Q-f>Q%m!@4#_XM4o+%p?V>W6-u`QNPOZiT>n%~;qq+;As zaUnGmmbJ7jI6td3NMwZ@!hK;qpdOy}DYXQtws$f{ZHs-NfwghwmHJ=)#D(OEWAq>&>>}jNMe+3qM5{ z-CjHDSj?@&-09hQs~)xGQ^)=L)D@b|cGaw?`!jo7C?jZ z+3Dwr$-8;%ck`yD9NOh#6)pB>wPQ$JAkY&iMrVBZy(H$&aO+9^h~QkEE9nK>oPi^DUMm~Vw!uwk2)rJf!BaWVItQ6fl^+=F;l;G32e&&e_ej-B(e z9C&sTqbG;_!lfJcENaTKV&>e6?bRHoA3Sr2(V4@XAol1rThbS;$#M^LxGT$daYt(J z$qoqc%p&HE;HZBjOFg>qjrbda*|$Td{c}asyZl?yIvaX9^gR*a0KM29{fpcoEpV9s zOH4*~Uo3AuEbz|X#qy@t6OOn3sSf^G&L7p28xx)i%)viaADS)-=u988(PBw}rzVii z325kQ&~7#1KdS}}?+En4GY8Ec23pryD6W3>dB+;fwbXYCih#L&c(}yPu=Re+S;=DL`zkTW+9_?E(5uH?M%_N-z zSn=iK=dUJ)!3@|2Q`DN{lIY``n@IjZ@*m+lr%#nV#vbD(?Bf*uk2kB>+B$D+zRdIf zGH;fh+9}^juh*aFjv;IV>}iO7r@s7Ij(xM-Zmu82_slVI47H(UD@M0~$0TKYrP`D@dh zJ-&o`^}uz8z52&7nC?_xk2?N>8N^<2kKb+t_}zZM`i&lD&TsdV4*x;VAL`AGgD!B6 zevdviS^?^2pR?V4704T_(*{tZ_w+Q_O<;|@HR|yMsKp0r+-nC|C;t{sZJq&nPvLg) zCzH`a5tc%dSQij)$BKq@KKyCr0|vas2Wn*;UEAEj5` z`K!DUe4j77ai>gY=KbcplgixwWwT3Gw=qNEp(gR(tDGO3{6&u4nQz5zmUQY&b64FQMbGQ{LVTl!`&#DoP3iN( zJn@!h;#*>~S5N;JB)JIi*SXD(!M3&Sx+MPeRHnk-P|Ttpy!`PXx39{kmp$1_lH>uS zCOd<`sfo?5A@Z$CdSYtezn1IZ_+zv0;$3TYM2#I)-IAp44N3H(?zVIYoIKd<9HP$N zRCO`C+Q4nu|{O9#WZzz%YZ*b`Nw-V-tL`18)* P-fBzSC2xO~;g$Fw`a@|t delta 386 zcmXw!O-=$q5QVE}z)_Mhh8RX1gc(HTXT`$Agy?p*zycSnxda=|VCEtua0b_2!GoCa zJ?yFEOI5wDdfmNm{6ujWJVs{DE-kjvSG>FKnc0nnRwGANZr!rkq&(i570CZ}`R&Ge z8@UgPf_e2hIN$dUuR-EA8Ao?WiUel9*SI3ZH6=G7;p~BY0Rd>YOO~Z{?W)%!rA_EH zJ1Bp{^-k{hAm^3U&#oQnme=3CdqyvZPiFZ1`O%uoV1XvbC&)ojY0uQsbaSP>c#YRi ZZH}D`hadwjXkY*zeDjK|vp+1}-~`)W7c>9> diff --git a/wgpu/examples/texture-arrays/uniform.frag b/wgpu/examples/texture-arrays/uniform.frag index 3b7a136b1..bda88f3ed 100644 --- a/wgpu/examples/texture-arrays/uniform.frag +++ b/wgpu/examples/texture-arrays/uniform.frag @@ -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); } diff --git a/wgpu/examples/texture-arrays/uniform.frag.spv b/wgpu/examples/texture-arrays/uniform.frag.spv index 671a87262d79f94e5cdb1c9045910820d80a0f0f..aa3ee039c54ccfaa01e4c461828e0c93e91ae79e 100644 GIT binary patch literal 1376 zcmZ9KYikox5QfKYQe$gx*0%Oy-89~-v1%1TRHR500#VxP$E9RfSlDF4=0g4EZ}V6A zMeu#j?%Lpl$((uToy(cC-b~}N*(IB^1v|7{R%}Ly*}Tm<+iD-To5NAqJbZBgW6?ZE zgtKHdtH`3gv$#*-iuAtpxpY}vVrrt3r^;r(lvq*6Ry$~QI<5AHpgR}@!_ki<3X-@V z1!0^;-BCP=;MJyhalf04!)ZcQjOpI^^iPAMG)Xh7>bE3+9Gpbwqj44u&0#CTPW$oq zH0ud5-Lz_8$T;}a52JG-o~`DP%h`3YpIU0^Q9ZA#k=9NV_*L@SzaIfb>XvbuuW}#P8L4(r=|4Qlryh@Uj+9H|Ehdu*^$2> zOC2zJGCKlJPkeTWP;Xh*m(pWbld!)WtJpQ2nGcLyeBKm{-tewV5qho35-am>5Rfp> zmL}YmWyT#@&gG0ZbwKIGnodo|HZLQtGguh7|m(IPB?;bV~{jhrK+IvXgJ( z@GU-+!UON7+6b@2iPjm)@TVe+VM($^Iqu*00`S6Le|F_yE M-wv@qs_;ts7qV+tY5)KL delta 433 zcmXw#Jx)SV5Jus_aAud!>@M#R>h zL&W=o^;dZ2+CY7y63W$gwpdO`dj)Uo`j^e^Pj#8>kQTW$2O-BfRyGtPlyaDWXK_=bD_Vvp0@FC%W@4^!M2$p8QV diff --git a/wgpu/examples/texture-arrays/unsized-non-uniform.frag b/wgpu/examples/texture-arrays/unsized-non-uniform.frag index cd6068144..e49a83103 100644 --- a/wgpu/examples/texture-arrays/unsized-non-uniform.frag +++ b/wgpu/examples/texture-arrays/unsized-non-uniform.frag @@ -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); } diff --git a/wgpu/examples/texture-arrays/unsized-non-uniform.frag.spv b/wgpu/examples/texture-arrays/unsized-non-uniform.frag.spv index 1c0688ff7c127f35d9c4883a21264dfabe582496..1c98e9421156df924fdf8473b5f492bb906eef89 100644 GIT binary patch literal 1296 zcmYk4T~8BH5QYcZA{GG=0Rhn#{3an@s4+2W3?UnnCdHJXcblfWm`%33b^8&#^GB&S z-ubJ%G4Xv)ck50wotbyunR90LROSz^n9W(;mhI4{vS#x_%&nI9!Vco`+1ZOIl~z1Qlrj)tS)=-Kn9bY8KFJAmG+>QR+N``suZ zaaDR<+H|(!a=M(VD!Pf;ZxvQm=e69?Nt%q4=pxPf{+Dq#jxM4wQ@&2#Yq!1DiQgLx z{NdPDnER#vaT=$Y)%06dJoeAR%h5Os zhbE-z?mzM0vkJ$#p#{jTqXzh3eM<#^S&SGhki{fi#kGj7FpOaASdUv>QA&g=R@e50n$$Tv7ra{jTLCF!~X*M`S}W z`)Ww3hrgQp;P8prYmvVpAEEz_CfbnY%uQK*dThxeVDunnmk9Ztsq6T=s@+peKlX7~ zmigEf+=lF&6r5hfO(_`sd$RD^&!J-c2U4?dZ(rzL(TCk4aQ+CX$-WlKjJylxdnc6H zcpK~o91i#5jer+5yn~{KS$GS~2M&il@Fu{|)tC8r6Z8Rx!#w*^X89-%-}^uc54^3H zz-;%W;3&e}%=AGu%=%CY2Pv>e^1#cq#n{ DD0XPM delta 385 zcmXw#OAY~15JjuI(MVcE{QrLmBQuFGHN}8|v2{pHOi6FW25i7)j3v&cRdQ2R=T+T) zudnI5A9!xhH*+j$fsJm#CDSmota%nA`xc&^Z7xfB&zr5lzdC$6<4y_OMT!;k>O07Z z`bM~LU&l5lMTnw+=25R{MGeymIgLu3)yN6tBJI}6aunCDdficMLa*6w`0x%VxtEcg zcNYJ;R;ju9moFmsCcPZ?%rpP*bV=+S?A1@bO diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index af7b08a68..faf6dc6e8 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -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) } diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index be06debff..d629361d7 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -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()) } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 4eabc2251..8f00293aa 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -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