Path: blob/main/crates/bevy_render/src/render_resource/bind_group_entries.rs
6596 views
use variadics_please::all_tuples_with_size;1use wgpu::{BindGroupEntry, BindingResource};23use super::{Sampler, TextureView};45/// Helper for constructing bindgroups.6///7/// Allows constructing the descriptor's entries as:8/// ```ignore (render_device cannot be easily accessed)9/// render_device.create_bind_group(10/// "my_bind_group",11/// &my_layout,12/// &BindGroupEntries::with_indices((13/// (2, &my_sampler),14/// (3, my_uniform),15/// )),16/// );17/// ```18///19/// instead of20///21/// ```ignore (render_device cannot be easily accessed)22/// render_device.create_bind_group(23/// "my_bind_group",24/// &my_layout,25/// &[26/// BindGroupEntry {27/// binding: 2,28/// resource: BindingResource::Sampler(&my_sampler),29/// },30/// BindGroupEntry {31/// binding: 3,32/// resource: my_uniform,33/// },34/// ],35/// );36/// ```37///38/// or39///40/// ```ignore (render_device cannot be easily accessed)41/// render_device.create_bind_group(42/// "my_bind_group",43/// &my_layout,44/// &BindGroupEntries::sequential((45/// &my_sampler,46/// my_uniform,47/// )),48/// );49/// ```50///51/// instead of52///53/// ```ignore (render_device cannot be easily accessed)54/// render_device.create_bind_group(55/// "my_bind_group",56/// &my_layout,57/// &[58/// BindGroupEntry {59/// binding: 0,60/// resource: BindingResource::Sampler(&my_sampler),61/// },62/// BindGroupEntry {63/// binding: 1,64/// resource: my_uniform,65/// },66/// ],67/// );68/// ```69///70/// or71///72/// ```ignore (render_device cannot be easily accessed)73/// render_device.create_bind_group(74/// "my_bind_group",75/// &my_layout,76/// &BindGroupEntries::single(my_uniform),77/// );78/// ```79///80/// instead of81///82/// ```ignore (render_device cannot be easily accessed)83/// render_device.create_bind_group(84/// "my_bind_group",85/// &my_layout,86/// &[87/// BindGroupEntry {88/// binding: 0,89/// resource: my_uniform,90/// },91/// ],92/// );93/// ```94pub struct BindGroupEntries<'b, const N: usize = 1> {95entries: [BindGroupEntry<'b>; N],96}9798impl<'b, const N: usize> BindGroupEntries<'b, N> {99#[inline]100pub fn sequential(resources: impl IntoBindingArray<'b, N>) -> Self {101let mut i = 0;102Self {103entries: resources.into_array().map(|resource| {104let binding = i;105i += 1;106BindGroupEntry { binding, resource }107}),108}109}110111#[inline]112pub fn with_indices(indexed_resources: impl IntoIndexedBindingArray<'b, N>) -> Self {113Self {114entries: indexed_resources115.into_array()116.map(|(binding, resource)| BindGroupEntry { binding, resource }),117}118}119}120121impl<'b> BindGroupEntries<'b, 1> {122pub fn single(resource: impl IntoBinding<'b>) -> [BindGroupEntry<'b>; 1] {123[BindGroupEntry {124binding: 0,125resource: resource.into_binding(),126}]127}128}129130impl<'b, const N: usize> core::ops::Deref for BindGroupEntries<'b, N> {131type Target = [BindGroupEntry<'b>];132133fn deref(&self) -> &[BindGroupEntry<'b>] {134&self.entries135}136}137138pub trait IntoBinding<'a> {139fn into_binding(self) -> BindingResource<'a>;140}141142impl<'a> IntoBinding<'a> for &'a TextureView {143#[inline]144fn into_binding(self) -> BindingResource<'a> {145BindingResource::TextureView(self)146}147}148149impl<'a> IntoBinding<'a> for &'a wgpu::TextureView {150#[inline]151fn into_binding(self) -> BindingResource<'a> {152BindingResource::TextureView(self)153}154}155156impl<'a> IntoBinding<'a> for &'a [&'a wgpu::TextureView] {157#[inline]158fn into_binding(self) -> BindingResource<'a> {159BindingResource::TextureViewArray(self)160}161}162163impl<'a> IntoBinding<'a> for &'a Sampler {164#[inline]165fn into_binding(self) -> BindingResource<'a> {166BindingResource::Sampler(self)167}168}169170impl<'a> IntoBinding<'a> for &'a [&'a wgpu::Sampler] {171#[inline]172fn into_binding(self) -> BindingResource<'a> {173BindingResource::SamplerArray(self)174}175}176177impl<'a> IntoBinding<'a> for BindingResource<'a> {178#[inline]179fn into_binding(self) -> BindingResource<'a> {180self181}182}183184impl<'a> IntoBinding<'a> for wgpu::BufferBinding<'a> {185#[inline]186fn into_binding(self) -> BindingResource<'a> {187BindingResource::Buffer(self)188}189}190191impl<'a> IntoBinding<'a> for &'a [wgpu::BufferBinding<'a>] {192#[inline]193fn into_binding(self) -> BindingResource<'a> {194BindingResource::BufferArray(self)195}196}197198pub trait IntoBindingArray<'b, const N: usize> {199fn into_array(self) -> [BindingResource<'b>; N];200}201202macro_rules! impl_to_binding_slice {203($N: expr, $(#[$meta:meta])* $(($T: ident, $I: ident)),*) => {204$(#[$meta])*205impl<'b, $($T: IntoBinding<'b>),*> IntoBindingArray<'b, $N> for ($($T,)*) {206#[inline]207fn into_array(self) -> [BindingResource<'b>; $N] {208let ($($I,)*) = self;209[$($I.into_binding(), )*]210}211}212}213}214215all_tuples_with_size!(216#[doc(fake_variadic)]217impl_to_binding_slice,2181,21932,220T,221s222);223224pub trait IntoIndexedBindingArray<'b, const N: usize> {225fn into_array(self) -> [(u32, BindingResource<'b>); N];226}227228macro_rules! impl_to_indexed_binding_slice {229($N: expr, $(($T: ident, $S: ident, $I: ident)),*) => {230impl<'b, $($T: IntoBinding<'b>),*> IntoIndexedBindingArray<'b, $N> for ($((u32, $T),)*) {231#[inline]232fn into_array(self) -> [(u32, BindingResource<'b>); $N] {233let ($(($S, $I),)*) = self;234[$(($S, $I.into_binding())), *]235}236}237}238}239240all_tuples_with_size!(impl_to_indexed_binding_slice, 1, 32, T, n, s);241242pub struct DynamicBindGroupEntries<'b> {243entries: Vec<BindGroupEntry<'b>>,244}245246impl<'b> Default for DynamicBindGroupEntries<'b> {247fn default() -> Self {248Self::new()249}250}251252impl<'b> DynamicBindGroupEntries<'b> {253pub fn sequential<const N: usize>(entries: impl IntoBindingArray<'b, N>) -> Self {254Self {255entries: entries256.into_array()257.into_iter()258.enumerate()259.map(|(ix, resource)| BindGroupEntry {260binding: ix as u32,261resource,262})263.collect(),264}265}266267pub fn extend_sequential<const N: usize>(268mut self,269entries: impl IntoBindingArray<'b, N>,270) -> Self {271let start = self.entries.last().unwrap().binding + 1;272self.entries.extend(273entries274.into_array()275.into_iter()276.enumerate()277.map(|(ix, resource)| BindGroupEntry {278binding: start + ix as u32,279resource,280}),281);282self283}284285pub fn new_with_indices<const N: usize>(entries: impl IntoIndexedBindingArray<'b, N>) -> Self {286Self {287entries: entries288.into_array()289.into_iter()290.map(|(binding, resource)| BindGroupEntry { binding, resource })291.collect(),292}293}294295pub fn new() -> Self {296Self {297entries: Vec::new(),298}299}300301pub fn extend_with_indices<const N: usize>(302mut self,303entries: impl IntoIndexedBindingArray<'b, N>,304) -> Self {305self.entries.extend(306entries307.into_array()308.into_iter()309.map(|(binding, resource)| BindGroupEntry { binding, resource }),310);311self312}313}314315impl<'b> core::ops::Deref for DynamicBindGroupEntries<'b> {316type Target = [BindGroupEntry<'b>];317318fn deref(&self) -> &[BindGroupEntry<'b>] {319&self.entries320}321}322323324