google / google/filament

Vulkan: isRenderTargetFormatSupported() returns false for every depth/stencil format

Closed Beginner friendly
#10,418 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
20.5k
Forks
2.3k
Avg merge
2d 14h
Merged PRs (30d)
83

Description

`VulkanDriver::isRenderTargetFormatSupported` tests the color attachment bit, which no depth or
stencil format ever has:

```cpp
// filament/backend/src/vulkan/VulkanDriver.cpp
bool VulkanDriver::isRenderTargetFormatSupported(TextureFormat format) {
...
vkGetPhysicalDeviceFormatProperties(mPlatform->getPhysicalDevice(), vkformat, &info);
return (info.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0;
}
```

So `DEPTH16`, `DEPTH24`, `DEPTH32F`, `DEPTH24_STENCIL8`, `DEPTH32F_STENCIL8` and `STENCIL8` all
answer false, whatever the device supports. The bit to test for those is
`VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT`.

The other backends disagree: OpenGL's implementation lists depth and stencil formats among the
supported ones, and Metal returns true for anything with a valid `MTLPixelFormat`. Vulkan is the
outlier.

### Why it matters

It makes the query unusable for picking a depth/stencil format, which is the one place a caller
would want it. `RendererUtils::colorPass` currently picks without asking:

```cpp
// filament/src/RendererUtils.cpp
TextureFormat const stencilFormat = isES2 ?
TextureFormat::DEPTH24_STENCIL8 : TextureFormat::DEPTH32F_STENCIL8;
```

Vulkan guarantees one of `VK_FORMAT_D32_SFLOAT_S8_UINT` / `VK_FORMAT_D24_UNORM_S8_UINT` and not
both, so a device can lack the one chosen. On a Raspberry Pi 5 (V3D 7.1.7.0, V3DV Mesa) it does:

```
D32_SFLOAT_S8_UINT optimalTilingFeatures = 0x0
D24_UNORM_S8_UINT optimalTilingFeatures = 0xce01 (DEPTH_STENCIL_ATTACHMENT_BIT set)
```

A view with `setStencilBufferEnabled(true)` allocates the first anyway, and V3DV segfaults inside
`vkCreateImageView` on the first attachment view over it -- `VulkanTexture::getAttachmentView` <-
`VulkanAttachment::getImageView` <- `VulkanRenderTarget`, three frames into the first pass, with
nothing in the log naming a format. Substituting `DEPTH24_STENCIL8` runs indefinitely.

Fixing the query is what lets the format be chosen by capability rather than by constant. Happy to
send a PR for the query alone if that is useful; the format selection is a separate call.

Filament 1.75.0, and unchanged on `main` as of today.

Contributor guide

Open the contributing guide

Research direction

Start in filament/backend/src/vulkan/VulkanDriver.cpp at VulkanDriver::isRenderTargetFormatSupported and compare the format-feature checks with the OpenGL and Metal implementations mentioned in the issue. Verify the listed depth and stencil formats against the appropriate Vulkan capability bit, including the Raspberry Pi 5 values described. Done means supported formats no longer all return false and unsupported formats remain rejected.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend, computer-graphics
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.