Make #[bindless]
in ExtendedMaterial
actually enable bindless mode. (#16818)
I forgot to set `BINDLESS_SLOT_COUNT` in `ExtendedMaterial`'s implementation of `AsBindGroup`, so it didn't actually become bindless. In fact, it would usually crash with a shader/bind group layout mismatch, because some parts of Bevy's renderer thought that the resulting material was bindless while other parts didn't. This commit corrects the situation. I had to make `BINDLESS_SLOT_COUNT` a function instead of a constant because the `ExtendedMaterial` version needs some logic. Unfortunately, trait methods can't be `const fn`s, so it has to be a runtime function.
This commit is contained in:
parent
f360b88036
commit
3af0b29809
@ -150,6 +150,15 @@ impl<B: Material, E: MaterialExtension> AsBindGroup for ExtendedMaterial<B, E> {
|
|||||||
type Data = (<B as AsBindGroup>::Data, <E as AsBindGroup>::Data);
|
type Data = (<B as AsBindGroup>::Data, <E as AsBindGroup>::Data);
|
||||||
type Param = (<B as AsBindGroup>::Param, <E as AsBindGroup>::Param);
|
type Param = (<B as AsBindGroup>::Param, <E as AsBindGroup>::Param);
|
||||||
|
|
||||||
|
fn bindless_slot_count() -> Option<u32> {
|
||||||
|
match (B::bindless_slot_count(), E::bindless_slot_count()) {
|
||||||
|
(Some(base_bindless_slot_count), Some(extension_bindless_slot_count)) => {
|
||||||
|
Some(base_bindless_slot_count.min(extension_bindless_slot_count))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn unprepared_bind_group(
|
fn unprepared_bind_group(
|
||||||
&self,
|
&self,
|
||||||
layout: &BindGroupLayout,
|
layout: &BindGroupLayout,
|
||||||
@ -159,9 +168,7 @@ impl<B: Material, E: MaterialExtension> AsBindGroup for ExtendedMaterial<B, E> {
|
|||||||
) -> Result<UnpreparedBindGroup<Self::Data>, AsBindGroupError> {
|
) -> Result<UnpreparedBindGroup<Self::Data>, AsBindGroupError> {
|
||||||
// Only allow bindless mode if both the base material and the extension
|
// Only allow bindless mode if both the base material and the extension
|
||||||
// support it.
|
// support it.
|
||||||
force_no_bindless = force_no_bindless
|
force_no_bindless = force_no_bindless || Self::bindless_slot_count().is_none();
|
||||||
|| B::BINDLESS_SLOT_COUNT.is_none()
|
|
||||||
|| E::BINDLESS_SLOT_COUNT.is_none();
|
|
||||||
|
|
||||||
// add together the bindings of the base material and the user material
|
// add together the bindings of the base material and the user material
|
||||||
let UnpreparedBindGroup {
|
let UnpreparedBindGroup {
|
||||||
@ -199,9 +206,7 @@ impl<B: Material, E: MaterialExtension> AsBindGroup for ExtendedMaterial<B, E> {
|
|||||||
{
|
{
|
||||||
// Only allow bindless mode if both the base material and the extension
|
// Only allow bindless mode if both the base material and the extension
|
||||||
// support it.
|
// support it.
|
||||||
force_no_bindless = force_no_bindless
|
force_no_bindless = force_no_bindless || Self::bindless_slot_count().is_none();
|
||||||
|| B::BINDLESS_SLOT_COUNT.is_none()
|
|
||||||
|| E::BINDLESS_SLOT_COUNT.is_none();
|
|
||||||
|
|
||||||
// add together the bindings of the standard material and the user material
|
// add together the bindings of the standard material and the user material
|
||||||
let mut entries = B::bind_group_layout_entries(render_device, force_no_bindless);
|
let mut entries = B::bind_group_layout_entries(render_device, force_no_bindless);
|
||||||
|
@ -440,7 +440,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Returns a new bind group.
|
/// Returns a new bind group.
|
||||||
fn new() -> MaterialBindlessBindGroup<M> {
|
fn new() -> MaterialBindlessBindGroup<M> {
|
||||||
let count = M::BINDLESS_SLOT_COUNT.unwrap_or(1);
|
let count = M::bindless_slot_count().unwrap_or(1);
|
||||||
|
|
||||||
MaterialBindlessBindGroup {
|
MaterialBindlessBindGroup {
|
||||||
bind_group: None,
|
bind_group: None,
|
||||||
@ -789,7 +789,7 @@ pub fn material_uses_bindless_resources<M>(render_device: &RenderDevice) -> bool
|
|||||||
where
|
where
|
||||||
M: Material,
|
M: Material,
|
||||||
{
|
{
|
||||||
M::BINDLESS_SLOT_COUNT.is_some()
|
M::bindless_slot_count().is_some()
|
||||||
&& render_device
|
&& render_device
|
||||||
.features()
|
.features()
|
||||||
.contains(WgpuFeatures::BUFFER_BINDING_ARRAY | WgpuFeatures::TEXTURE_BINDING_ARRAY)
|
.contains(WgpuFeatures::BUFFER_BINDING_ARRAY | WgpuFeatures::TEXTURE_BINDING_ARRAY)
|
||||||
|
@ -567,7 +567,11 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result<TokenStream> {
|
|||||||
// limitations into account.
|
// limitations into account.
|
||||||
let (bindless_slot_count, actual_bindless_slot_count_declaration) = match attr_bindless_count {
|
let (bindless_slot_count, actual_bindless_slot_count_declaration) = match attr_bindless_count {
|
||||||
Some(bindless_count) => (
|
Some(bindless_count) => (
|
||||||
quote! { const BINDLESS_SLOT_COUNT: Option<u32> = Some(#bindless_count); },
|
quote! {
|
||||||
|
fn bindless_slot_count() -> Option<u32> {
|
||||||
|
Some(#bindless_count)
|
||||||
|
}
|
||||||
|
},
|
||||||
quote! {
|
quote! {
|
||||||
let #actual_bindless_slot_count = if render_device.features().contains(
|
let #actual_bindless_slot_count = if render_device.features().contains(
|
||||||
#render_path::settings::WgpuFeatures::BUFFER_BINDING_ARRAY |
|
#render_path::settings::WgpuFeatures::BUFFER_BINDING_ARRAY |
|
||||||
|
@ -337,7 +337,9 @@ pub trait AsBindGroup {
|
|||||||
/// Note that the *actual* slot count may be different from this value, due
|
/// Note that the *actual* slot count may be different from this value, due
|
||||||
/// to platform limitations. For example, if bindless resources aren't
|
/// to platform limitations. For example, if bindless resources aren't
|
||||||
/// supported on this platform, the actual slot count will be 1.
|
/// supported on this platform, the actual slot count will be 1.
|
||||||
const BINDLESS_SLOT_COUNT: Option<u32> = None;
|
fn bindless_slot_count() -> Option<u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// label
|
/// label
|
||||||
fn label() -> Option<&'static str> {
|
fn label() -> Option<&'static str> {
|
||||||
|
Loading…
Reference in New Issue
Block a user