@@ -19,7 +19,7 @@ use smallvec::SmallVec;
1919use thiserror:: Error ;
2020use wgt:: { BufferAddress , TextureFormat , TextureViewDimension } ;
2121
22- use std:: { borrow:: Cow , iter, marker:: PhantomData , mem, ops:: Range , ptr} ;
22+ use std:: { borrow:: Cow , iter, marker:: PhantomData , mem, num :: NonZeroU32 , ops:: Range , ptr} ;
2323
2424mod life;
2525pub mod queue;
@@ -1183,10 +1183,13 @@ impl<A: HalApi> Device<A> {
11831183 } ) ?;
11841184 }
11851185
1186+ let bgl_flags = conv:: bind_group_layout_flags ( self . features ) ;
1187+
11861188 let mut hal_bindings = entry_map. values ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
11871189 hal_bindings. sort_by_key ( |b| b. binding ) ;
11881190 let hal_desc = hal:: BindGroupLayoutDescriptor {
11891191 label,
1192+ flags : bgl_flags,
11901193 entries : & hal_bindings,
11911194 } ;
11921195 let raw = unsafe {
@@ -1387,7 +1390,7 @@ impl<A: HalApi> Device<A> {
13871390 . entries
13881391 . get ( & binding)
13891392 . ok_or ( Error :: MissingBindingDeclaration ( binding) ) ?;
1390- let res_index = match entry. resource {
1393+ let ( res_index, count ) = match entry. resource {
13911394 Br :: Buffer ( ref bb) => {
13921395 let bb = Self :: create_buffer_binding (
13931396 bb,
@@ -1402,21 +1405,11 @@ impl<A: HalApi> Device<A> {
14021405
14031406 let res_index = hal_buffers. len ( ) ;
14041407 hal_buffers. push ( bb) ;
1405- res_index
1408+ ( res_index, 1 )
14061409 }
14071410 Br :: BufferArray ( ref bindings_array) => {
1408- if let Some ( count) = decl. count {
1409- let count = count. get ( ) as usize ;
1410- let num_bindings = bindings_array. len ( ) ;
1411- if count != num_bindings {
1412- return Err ( Error :: BindingArrayLengthMismatch {
1413- actual : num_bindings,
1414- expected : count,
1415- } ) ;
1416- }
1417- } else {
1418- return Err ( Error :: SingleBindingExpected ) ;
1419- }
1411+ let num_bindings = bindings_array. len ( ) ;
1412+ Self :: check_array_binding ( self . features , decl. count , num_bindings) ?;
14201413
14211414 let res_index = hal_buffers. len ( ) ;
14221415 for bb in bindings_array. iter ( ) {
@@ -1432,7 +1425,7 @@ impl<A: HalApi> Device<A> {
14321425 ) ?;
14331426 hal_buffers. push ( bb) ;
14341427 }
1435- res_index
1428+ ( res_index, num_bindings )
14361429 }
14371430 Br :: Sampler ( id) => {
14381431 match decl. ty {
@@ -1464,7 +1457,7 @@ impl<A: HalApi> Device<A> {
14641457
14651458 let res_index = hal_samplers. len ( ) ;
14661459 hal_samplers. push ( & sampler. raw ) ;
1467- res_index
1460+ ( res_index, 1 )
14681461 }
14691462 _ => {
14701463 return Err ( Error :: WrongBindingType {
@@ -1505,21 +1498,11 @@ impl<A: HalApi> Device<A> {
15051498 view : & view. raw ,
15061499 usage : internal_use,
15071500 } ) ;
1508- res_index
1501+ ( res_index, 1 )
15091502 }
15101503 Br :: TextureViewArray ( ref bindings_array) => {
1511- if let Some ( count) = decl. count {
1512- let count = count. get ( ) as usize ;
1513- let num_bindings = bindings_array. len ( ) ;
1514- if count != num_bindings {
1515- return Err ( Error :: BindingArrayLengthMismatch {
1516- actual : num_bindings,
1517- expected : count,
1518- } ) ;
1519- }
1520- } else {
1521- return Err ( Error :: SingleBindingExpected ) ;
1522- }
1504+ let num_bindings = bindings_array. len ( ) ;
1505+ Self :: check_array_binding ( self . features , decl. count , num_bindings) ?;
15231506
15241507 let res_index = hal_textures. len ( ) ;
15251508 for & id in bindings_array. iter ( ) {
@@ -1551,13 +1534,14 @@ impl<A: HalApi> Device<A> {
15511534 } ) ;
15521535 }
15531536
1554- res_index
1537+ ( res_index, num_bindings )
15551538 }
15561539 } ;
15571540
15581541 hal_entries. push ( hal:: BindGroupEntry {
15591542 binding,
15601543 resource_index : res_index as u32 ,
1544+ count : count as u32 ,
15611545 } ) ;
15621546 }
15631547
@@ -1596,6 +1580,39 @@ impl<A: HalApi> Device<A> {
15961580 } )
15971581 }
15981582
1583+ fn check_array_binding (
1584+ features : wgt:: Features ,
1585+ count : Option < NonZeroU32 > ,
1586+ num_bindings : usize ,
1587+ ) -> Result < ( ) , super :: binding_model:: CreateBindGroupError > {
1588+ use super :: binding_model:: CreateBindGroupError as Error ;
1589+
1590+ if let Some ( count) = count {
1591+ let count = count. get ( ) as usize ;
1592+ if count < num_bindings {
1593+ return Err ( Error :: BindingArrayPartialLengthMismatch {
1594+ actual : num_bindings,
1595+ expected : count,
1596+ } ) ;
1597+ }
1598+ if count != num_bindings
1599+ && !features. contains ( wgt:: Features :: PARTIALLY_BOUND_BINDING_ARRAY )
1600+ {
1601+ return Err ( Error :: BindingArrayLengthMismatch {
1602+ actual : num_bindings,
1603+ expected : count,
1604+ } ) ;
1605+ }
1606+ if num_bindings == 0 {
1607+ return Err ( Error :: BindingArrayZeroLength ) ;
1608+ }
1609+ } else {
1610+ return Err ( Error :: SingleBindingExpected ) ;
1611+ } ;
1612+
1613+ Ok ( ( ) )
1614+ }
1615+
15991616 fn texture_use_parameters (
16001617 binding : u32 ,
16011618 decl : & wgt:: BindGroupLayoutEntry ,
0 commit comments