FIX: iOS Simulator not rendering due to missing CUBE_ARRAY_TEXTURES (#12052)

This PR closes #11978

# Objective

Fix rendering on iOS Simulators.

iOS Simulator doesn't support the capability CUBE_ARRAY_TEXTURES, since
0.13 this started to make iOS Simulator not render anything with the
following message being outputted:

```
2024-02-19T14:59:34.896266Z ERROR bevy_render::render_resource::pipeline_cache: failed to create shader module: Validation Error

Caused by:
    In Device::create_shader_module
    
Shader validation error: 


    Type [40] '' is invalid
    Capability Capabilities(CUBE_ARRAY_TEXTURES) is required
```

## Solution

- Split up NO_ARRAY_TEXTURES_SUPPORT into both NO_ARRAY_TEXTURES_SUPPORT
and NO_CUBE_ARRAY_TEXTURES_SUPPORT and correctly apply
NO_ARRAY_TEXTURES_SUPPORT for iOS Simulator using the cfg flag
introduced in #10178.

---

## Changelog

### Fixed
- Rendering on iOS Simulator due to missing CUBE_ARRAY_TEXTURES support.

---------

Co-authored-by: Sam Pettersson <sam.pettersson@geoguessr.com>
This commit is contained in:
Sam Pettersson 2024-02-23 02:24:59 +01:00 committed by GitHub
parent fa1740630c
commit caa7ec68d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 47 additions and 22 deletions

View file

@ -1210,16 +1210,20 @@ pub fn prepare_lights(
.create_view(&TextureViewDescriptor {
label: Some("point_light_shadow_map_array_texture_view"),
format: None,
#[cfg(any(
not(feature = "webgl"),
not(target_arch = "wasm32"),
feature = "webgpu"
// NOTE: iOS Simulator is missing CubeArray support so we use Cube instead.
// See https://github.com/bevyengine/bevy/pull/12052 - remove if support is added.
#[cfg(all(
not(ios_simulator),
any(
not(feature = "webgl"),
not(target_arch = "wasm32"),
feature = "webgpu"
)
))]
dimension: Some(TextureViewDimension::CubeArray),
#[cfg(all(
feature = "webgl",
target_arch = "wasm32",
not(feature = "webgpu")
#[cfg(any(
ios_simulator,
all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu"))
))]
dimension: Some(TextureViewDimension::Cube),
aspect: TextureAspect::DepthOnly,

View file

@ -191,13 +191,19 @@ fn layout_entries(
// Point Shadow Texture Cube Array
(
2,
#[cfg(any(
not(feature = "webgl"),
not(target_arch = "wasm32"),
feature = "webgpu"
#[cfg(all(
not(ios_simulator),
any(
not(feature = "webgl"),
not(target_arch = "wasm32"),
feature = "webgpu"
)
))]
texture_cube_array(TextureSampleType::Depth),
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
#[cfg(any(
ios_simulator,
all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu"))
))]
texture_cube(TextureSampleType::Depth),
),
// Point Shadow Texture Array Sampler

View file

@ -8,7 +8,7 @@
@group(0) @binding(0) var<uniform> view: View;
@group(0) @binding(1) var<uniform> lights: types::Lights;
#ifdef NO_ARRAY_TEXTURES_SUPPORT
#ifdef NO_CUBE_ARRAY_TEXTURES_SUPPORT
@group(0) @binding(2) var point_shadow_textures: texture_depth_cube;
#else
@group(0) @binding(2) var point_shadow_textures: texture_depth_cube_array;

View file

@ -44,7 +44,7 @@ fn fetch_point_shadow(light_id: u32, frag_position: vec4<f32>, surface_normal: v
// a quad (2x2 fragments) being processed not being sampled, and this messing with
// mip-mapping functionality. The shadow maps have no mipmaps so Level just samples
// from LOD 0.
#ifdef NO_ARRAY_TEXTURES_SUPPORT
#ifdef NO_CUBE_ARRAY_TEXTURES_SUPPORT
return textureSampleCompare(view_bindings::point_shadow_textures, view_bindings::point_shadow_textures_sampler, frag_ls * flip_z, depth);
#else
return textureSampleCompareLevel(view_bindings::point_shadow_textures, view_bindings::point_shadow_textures_sampler, frag_ls * flip_z, i32(light_id), depth);

View file

@ -363,6 +363,7 @@ impl Plugin for RenderPlugin {
.insert_resource(instance)
.insert_resource(PipelineCache::new(
device.clone(),
render_adapter.clone(),
self.synchronous_pipeline_compilation,
))
.insert_resource(device)

View file

@ -1,3 +1,4 @@
use crate::renderer::RenderAdapter;
use crate::{render_resource::*, renderer::RenderDevice, Extract};
use bevy_asset::{AssetEvent, AssetId, Assets};
use bevy_ecs::system::{Res, ResMut};
@ -21,7 +22,7 @@ use thiserror::Error;
#[cfg(feature = "shader_format_spirv")]
use wgpu::util::make_spirv;
use wgpu::{
Features, PipelineLayoutDescriptor, PushConstantRange, ShaderModuleDescriptor,
DownlevelFlags, Features, PipelineLayoutDescriptor, PushConstantRange, ShaderModuleDescriptor,
VertexBufferLayout as RawVertexBufferLayout,
};
@ -167,7 +168,7 @@ impl ShaderDefVal {
}
impl ShaderCache {
fn new(render_device: &RenderDevice) -> Self {
fn new(render_device: &RenderDevice, render_adapter: &RenderAdapter) -> Self {
const CAPABILITIES: &[(Features, Capabilities)] = &[
(Features::PUSH_CONSTANTS, Capabilities::PUSH_CONSTANT),
(Features::SHADER_F64, Capabilities::FLOAT64),
@ -196,9 +197,13 @@ impl ShaderCache {
}
}
// TODO: Check if this is supported, though I'm not sure if bevy works without this feature?
// We can't compile for native at least without it.
capabilities |= Capabilities::CUBE_ARRAY_TEXTURES;
if render_adapter
.get_downlevel_capabilities()
.flags
.contains(DownlevelFlags::CUBE_ARRAY_TEXTURES)
{
capabilities |= Capabilities::CUBE_ARRAY_TEXTURES;
}
#[cfg(debug_assertions)]
let composer = naga_oil::compose::Composer::default();
@ -279,9 +284,14 @@ impl ShaderCache {
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
{
shader_defs.push("NO_ARRAY_TEXTURES_SUPPORT".into());
shader_defs.push("NO_CUBE_ARRAY_TEXTURES_SUPPORT".into());
shader_defs.push("SIXTEEN_BYTE_ALIGNMENT".into());
}
if cfg!(ios_simulator) {
shader_defs.push("NO_CUBE_ARRAY_TEXTURES_SUPPORT".into());
}
shader_defs.push(ShaderDefVal::UInt(
String::from("AVAILABLE_STORAGE_BUFFER_BINDINGS"),
render_device.limits().max_storage_buffers_per_shader_stage,
@ -491,9 +501,13 @@ impl PipelineCache {
}
/// Create a new pipeline cache associated with the given render device.
pub fn new(device: RenderDevice, synchronous_pipeline_compilation: bool) -> Self {
pub fn new(
device: RenderDevice,
render_adapter: RenderAdapter,
synchronous_pipeline_compilation: bool,
) -> Self {
Self {
shader_cache: Arc::new(Mutex::new(ShaderCache::new(&device))),
shader_cache: Arc::new(Mutex::new(ShaderCache::new(&device, &render_adapter))),
device,
layout_cache: default(),
waiting_pipelines: default(),