google / google/filament

Uniform buffer loads fail on Metal backend on Intel GPUs

Open
#7,588 3 comments 0 reactions 1 assignee Claimed by @bejado View on GitHub
gpu specific macos
Dominant language
C++
Stars
20.5k
Forks
2.3k
Avg merge
2d 14h
Merged PRs (30d)
83

Description

**Describe the bug**
There are visible shadow artifacts when using the Metal backend with Intel GPUs. Based on our investigations the root cause is that uniform buffer loads sometimes fail. I could repro it on tag v1.49.0 but on current `main` too.

**To Reproduce**
Just run gltf_viewer sample with `FILAMENT_FORCE_INTEGRATED_GPU=1` on a device which has Intel GPU (default view settings).

**Expected behavior**
No visual artifacts.

**Screenshots**
https://github.com/google/filament/assets/12460850/8783e405-9dd4-4d4f-91c4-4a4cd0a91dfd

**Logs**
The actual log is spammed with warnings because SPIRV-Cross generates unused variables in Metal shaders. I hope this is enough:
```
FEngine (64 bits) created at 0x10c024c00 (threading is enabled)
FEngine resolved backend: Metal
2024-02-21 21:49:09.908852+0100 gltf_viewer[22812:97578] Metal GPU Frame Capture Enabled
2024-02-21 21:49:09.909171+0100 gltf_viewer[22812:97578] Metal API Validation Enabled
Selected physical device 'Intel(R) UHD Graphics 630'
Supported GPU families:
MTLGPUFamilyCommon3
MTLGPUFamilyMac2
Features:
readWriteTextureSupport: true
Backend feature level: 3
FEngine feature level: 3
```

**Desktop (please complete the following information):**

- OS: macOS (tested on 13.2 and 14.1)
- GPU: Intel UHD 630 and Intel Iris Plus Graphics 640
- Backend: Metal

**Additional context**
Here's a screenshot of an Xcode frame capture of gltf_viewer sample with the DamagedHelmet model. This is a draw call from the shadow pass. `initObjectUniforms()` can see the per-renderable UBO (see highlighted variables at the bottom) but the thread local variables (e.g. `object_uniforms_worldFromModelNormalMatrix`) contain zeros at the end of the function. This is not the only affected draw call, only the first of them. Here it's related to the **UBO containing an array**, so setting `FILAMENT_HAS_FEATURE_INSTANCING` to false fixes this particular draw call, but the issue reappears around SSAO.
![image](https://github.com/google/filament/assets/12460850/80a6d58d-b909-4dd2-871a-20f6e9c4626e)

The [currently accessible Metal Feature Set Tables](https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf) says Mac2 family GPUs use 32 byte alignment (see _Minimum constant buffer offset alignment_) but Apple originally recommended 256, they just changed it ~2 years ago (I can attach the old _Metal Feature Set Tables.pdf_, if interested). Filament uses 32 bytes too for Mac2 GPUs. We were suspecting UBO alignment issues but setting `METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT` to 256 doesn't help.

Any ideas what could this be?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.