Skip to content

D3D12: MSAA gets disabled because it checks the wrong depth format #16124

Description

@tuzz

I'm writing a game with SDL_gpu and noticed MSAA was disabled on my Windows laptop under D3D12.

I pick a sample count by checking all my attachment formats support it:

SDL_GPUSampleCount msaa_counts[] = {SDL_GPU_SAMPLECOUNT_4, SDL_GPU_SAMPLECOUNT_2};
SDL_GPUTextureFormat msaa_formats[] = {SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT, SDL_GPU_TEXTUREFORMAT_R16_FLOAT, depth_stencil_format};

for (SDL_GPUSampleCount *c = msaa_counts; c < msaa_counts + SDL_arraysize(msaa_counts); c++) {
  bool supported = true;
  for (SDL_GPUTextureFormat *f = msaa_formats; f < msaa_formats + SDL_arraysize(msaa_formats); f++) supported &= SDL_GPUTextureSupportsSampleCount(device, *f, *c);
  if (supported) { msaa_sample_count = *c; msaa_enabled = true; break; }
}

Both colour formats come back true. D24_UNORM_S8_UINT comes back false at 2x, 4x and 8x.

What I think is happening

SDL_gpu_d3d12.c has two format tables, and for depth they hold different things:

line 338   DXGI_FORMAT_R24_UNORM_X8_TYPELESS,    // D24_UNORM_S8_UINT   (SDLToD3D12_TextureFormat)
line 447   DXGI_FORMAT_D24_UNORM_S8_UINT,        // D24_UNORM_S8_UINT   (SDLToD3D12_DepthFormat)

The depth one is what actually ends up in the pipeline at line 3231 (psoDesc.DSVFormat). But both feature checks use the other table:

line 8250  DXGI_FORMAT dxgiFormat = SDLToD3D12_TextureFormat[format];    (D3D12_SupportsTextureFormat)
line 8334  featureData.Format = SDLToD3D12_TextureFormat[format];        (D3D12_SupportsSampleCount)

So it ends up asking the driver about R24_UNORM_X8_TYPELESS rather than D24_UNORM_S8_UINT.

D3D12_SupportsTextureFormat also takes a usage argument and doesn't look at it when picking the format, so a DEPTH_STENCIL_TARGET query has the same issue.

Vulkan and Metal don't seem affected. They use one format for both, so it doesn't occur.

I tried it

I patched both lines locally to use the depth table for depth formats and rebuilt SDL.

It correctly enabled MSAA at 4x for D3D12.

The image is the same apart from the MSAA — I dumped the same frame as raw RGBA8 and got 27 differing bytes, by a delta of 1 RGB value.

Machine

Intel Iris Xe (device 0x46A6), driver 32.0.101.7077, Windows 11

My depth texture is DEPTH_STENCIL_TARGET usage only, I never sample it.

Notes

Might date back to #12701, which moved depth textures to typeless resources with separate views but didn't change these two queries.

Disclaimer: I used Claude to help diagnose this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions