From 2b65c8386b6eabd87d9138b5de12d604e1749d70 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Tue, 20 Aug 2024 13:22:30 +0100 Subject: [PATCH] rebase --- crates/bevy_pbr/src/material.rs | 3 ++ .../bevy_render/macros/src/as_bind_group.rs | 35 ++++++++++++++++++- crates/bevy_render/src/render_asset.rs | 12 +++++-- .../src/render_resource/bind_group.rs | 2 ++ crates/bevy_sprite/src/mesh2d/material.rs | 3 ++ .../src/render/ui_material_pipeline.rs | 3 ++ 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index ce55b93d3ec68..dc062d60dd914 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -953,6 +953,9 @@ impl RenderAsset for PreparedMaterial { Err(AsBindGroupError::RetryNextUpdate) => { Err(PrepareAssetError::RetryNextUpdate(material)) } + Err(other) => { + Err(PrepareAssetError::AsBindGroupError(other)) + } } } } diff --git a/crates/bevy_render/macros/src/as_bind_group.rs b/crates/bevy_render/macros/src/as_bind_group.rs index 25887495f41bf..f253df8a32cfa 100644 --- a/crates/bevy_render/macros/src/as_bind_group.rs +++ b/crates/bevy_render/macros/src/as_bind_group.rs @@ -355,6 +355,20 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { let fallback_image = get_fallback_image(&render_path, *dimension); + let expected_samplers = match sampler_binding_type { + SamplerBindingType::Filtering => { + quote!( [#render_path::render_resource::TextureSampleType::Float { filterable: true }] ) + } + SamplerBindingType::NonFiltering => quote!([ + #render_path::render_resource::TextureSampleType::Float { filterable: false }, + #render_path::render_resource::TextureSampleType::Sint, + #render_path::render_resource::TextureSampleType::Uint, + ]), + SamplerBindingType::Comparison => { + quote!( [#render_path::render_resource::TextureSampleType::Depth] ) + } + }; + // insert fallible texture-based entries at 0 so that if we fail here, we exit before allocating any buffers binding_impls.insert(0, quote! { ( @@ -362,7 +376,26 @@ pub fn derive_as_bind_group(ast: syn::DeriveInput) -> Result { #render_path::render_resource::OwnedBindingResource::Sampler({ let handle: Option<&#asset_path::Handle<#render_path::texture::Image>> = (&self.#field_name).into(); if let Some(handle) = handle { - images.get(handle).ok_or_else(|| #render_path::render_resource::AsBindGroupError::RetryNextUpdate)?.sampler.clone() + let image = images.get(handle).ok_or_else(|| #render_path::render_resource::AsBindGroupError::RetryNextUpdate)?; + + let Some(sample_type) = image.texture_format.sample_type(None, None) else { + return Err(#render_path::render_resource::AsBindGroupError::InvalidSamplerType( + #binding_index, + "None".to_string(), + format!("{:?}", #expected_samplers), + )); + }; + + let valid = #expected_samplers.contains(&sample_type); + + if !valid { + return Err(#render_path::render_resource::AsBindGroupError::InvalidSamplerType( + #binding_index, + format!("{:?}", sample_type), + format!("{:?}", #expected_samplers), + )); + } + image.sampler.clone() } else { #fallback_image.sampler.clone() } diff --git a/crates/bevy_render/src/render_asset.rs b/crates/bevy_render/src/render_asset.rs index 5c9be59de3dd6..db5c007530ff8 100644 --- a/crates/bevy_render/src/render_asset.rs +++ b/crates/bevy_render/src/render_asset.rs @@ -1,4 +1,4 @@ -use crate::{ExtractSchedule, MainWorld, Render, RenderApp, RenderSet}; +use crate::{render_resource::AsBindGroupError, ExtractSchedule, MainWorld, Render, RenderApp, RenderSet}; use bevy_app::{App, Plugin, SubApp}; use bevy_asset::{Asset, AssetEvent, AssetId, Assets}; use bevy_ecs::{ @@ -9,7 +9,7 @@ use bevy_ecs::{ }; use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize}; use bevy_render_macros::ExtractResource; -use bevy_utils::{tracing::debug, HashMap, HashSet}; +use bevy_utils::{tracing::{debug, error}, HashMap, HashSet}; use serde::{Deserialize, Serialize}; use std::marker::PhantomData; use thiserror::Error; @@ -18,6 +18,8 @@ use thiserror::Error; pub enum PrepareAssetError { #[error("Failed to prepare asset")] RetryNextUpdate(E), + #[error("Failed to build bind group: {0}")] + AsBindGroupError(AsBindGroupError), } /// Describes how an asset gets extracted and prepared for rendering. @@ -359,6 +361,9 @@ pub fn prepare_assets( Err(PrepareAssetError::RetryNextUpdate(extracted_asset)) => { prepare_next_frame.assets.push((id, extracted_asset)); } + Err(PrepareAssetError::AsBindGroupError(e)) => { + error!("{} Bind group construction failed: {e}", std::any::type_name::()) ; + } } } @@ -391,6 +396,9 @@ pub fn prepare_assets( Err(PrepareAssetError::RetryNextUpdate(extracted_asset)) => { prepare_next_frame.assets.push((id, extracted_asset)); } + Err(PrepareAssetError::AsBindGroupError(e)) => { + error!("{} Bind group construction failed: {e}", std::any::type_name::()) ; + } } } diff --git a/crates/bevy_render/src/render_resource/bind_group.rs b/crates/bevy_render/src/render_resource/bind_group.rs index 39704525b780f..6371678e48b3d 100644 --- a/crates/bevy_render/src/render_resource/bind_group.rs +++ b/crates/bevy_render/src/render_resource/bind_group.rs @@ -352,6 +352,8 @@ pub enum AsBindGroupError { /// The bind group could not be generated. Try again next frame. #[error("The bind group could not be generated")] RetryNextUpdate, + #[error("At binding index{0}, the provided image sampler `{1}` does not match the required sampler type(s) `{2}`.")] + InvalidSamplerType(u32, String, String), } /// A prepared bind group returned as a result of [`AsBindGroup::as_bind_group`]. diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 58a02ba13048c..6d6f1865b3dbc 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -615,6 +615,9 @@ impl RenderAsset for PreparedMaterial2d { Err(AsBindGroupError::RetryNextUpdate) => { Err(PrepareAssetError::RetryNextUpdate(material)) } + Err(other) => { + Err(PrepareAssetError::AsBindGroupError(other)) + } } } } diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index e15dc4223e456..982b2ee67a01b 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -624,6 +624,9 @@ impl RenderAsset for PreparedUiMaterial { Err(AsBindGroupError::RetryNextUpdate) => { Err(PrepareAssetError::RetryNextUpdate(material)) } + Err(other) => { + Err(PrepareAssetError::AsBindGroupError(other)) + } } } }