microsoft / microsoft/DirectXShaderCompiler

DXC doesn't report an error when placing a resource in a ConstantBuffer

Open
#4,763 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

fxc-disagrees
Dominant language
C++
Stars
3.7k
Forks
900
Avg merge
2d 11h
Merged PRs (30d)
44

Description

DXC doesn't report an error when placing a resource in a ConstantBuffer and for StructuredBuffers, it generates bad sizes and offsets for the cbuffers. It seems that this is apparently unsupported behavior despite it's complete support in FXC? I've included an exchange I had on Discord for context of this issue. It also includes a code example.

Kyle — Today at 1:17 PM
So here's a pretty gnarly bug in DXC. If you have a StructuredBuffer in a cbuffer, DXC treats that as an element of that type within the buffer. This generates all sorts of illegal sizes and alignments. Here's an example

// The entry point and target profile are needed to compile this example:
// -T ps_6_6 -E PSMain -Fh test.h test.hlsl
struct ModelData // Size: 4 Bytes
{
    uint myInt; // Offset: 0 Bytes
};
struct ModelData2 // Size: 16 Bytes
{
    StructuredBuffer<float3> bufferData;
    uint myInt; // Offset: 12 Bytes
};
struct ModelData3 // Size: 68 Bytes
{
    StructuredBuffer<float4x4> bufferData;
    uint myInt; // Offset: 64 Bytes
};
struct ModelData4 // Size: 4 Bytes
{
    Buffer<float4> bufferData;
    uint myInt; // Offset: 0 Bytes
};
cbuffer __cbModelData  { ModelData  cbModelData;  };
cbuffer __cbModelData2 { ModelData2 cbModelData2; };
cbuffer __cbModelData3 { ModelData3 cbModelData3; };
cbuffer __cbModelData4 { ModelData4 cbModelData4; };
struct PSInput
{
    float4 position : SV_Position;
    float4 color    : COLOR0;
};
float4 PSMain(PSInput input) : SV_Target0
{
    return input.color * cbModelData.myInt * cbModelData2.myInt * cbModelData3.myInt * cbModelData4.myInt;
}

This is just the latest in a litany of issues related to having resources in structs used in cbuffers. What's the deal here, is this use case on the way out?

Jesse Natalie — Today at 1:19 PM
Resources in structs doesn't make any sense... resources are globals

MJP — Today at 1:38 PM
Yeah you can't put resources in constant buffers or other resources like that.

Kyle — Today at 1:38 PM
Hey Jesse, I actually 100% agree with this sentiment. However we have a legacy codebase with a significant amount of dependance on the behavior that existed in FXC.

Jesse Natalie — Today at 1:39 PM
... and what was that behavior? I can't imagine what that would ever do that was sane

MJP — Today at 1:40 PM
I believe you can put a resource in a struct and then have a global variable of that struct, but that's about it.

Kyle — Today at 1:42 PM
So in FXC all resources in constant blocks we're hoisted out and assigned registers I believe just top to bottom as it recursed through the cbuffer structs and various other bind points.

Jesse Natalie — Today at 1:43 PM
You can try filing a DXC issue on GitHub but... I'll be honest, I don't think that's a case that's going to have its behavior reverted
If anything, I'd expect an entirely new behavior which is a hard failure to compile

Kyle — Today at 1:44 PM
I mean it would be awesome to just have an error stating that a resource in a constant buffer is invalid

Devaniti — Today at 1:44 PM
I'd expect it just to be a compile error, I'd say the bug that it compiles and not throws an error

Kyle — Today at 1:44 PM
Agreed

Devaniti — Today at 1:45 PM
Being able to easily fix such things in legacy codebase sounds even better than getting legacy behaviour in dxc

Kyle — Today at 1:46 PM
I did ask if this use case was on the way out

MJP — Today at 1:46 PM
I can't believe that worked in FXC

Devaniti — Today at 1:46 PM
https://shader-playground.timjones.io/d4757e74e6f557d62f50c459f933a53f

Kyle — Today at 1:46 PM
Like I shipped a high profile AAA port this year relying on this

Devaniti — Today at 1:46 PM
I think I even saw that somewhere
But yep, having resources in constant buffer just worked as if those resources are globals
And I faintly remember something about FXC bugs with that, something with zero sized arrays

MJP — Today at 1:47 PM
FXC can still surprise me after all of these years
Jesse Natalie — Today at 1:48 PM
Same

Kyle — Today at 1:49 PM
@ Devaniti yeah your shader playground example with a Texture2D has the correct behavioir
only structuredbuffers seem to be boned
Devaniti — Today at 1:50 PM
because it's fxc

Kyle — Today at 1:50 PM
DXC as well, only structurebuffers cause this alignment/padding issue

Maraneshi — Today at 1:50 PM
I'm so confused how anyone could even write code like that and say "oh yeah it totally makes sense to have a struct member that's not actually in the struct"

Devaniti — Today at 1:51 PM
in 2022 nobody gonna write that
it's just something that you may see in legacy codebase

Kyle — Today at 1:52 PM
Or a port from PS4 where the descriptor is a known size and in fact just mem copied into constants

Devaniti — Today at 1:52 PM
also, after my colleague accidentally discovered undocumented functionality in FXC, it'll be hard to surprise me 😂
I'm referring to this https://discord.com/channels/590611987420020747/596046911010504754/869899974098427914 if anyone's curious

Kyle — Today at 2:12 PM
Well, thanks for the support...

Jesse Natalie — Today at 2:13 PM
Yeah unfortunately this likely isn't going to be fixed on the compiler side, though if you'd like the compiler to produce an error, that sounds like an issue worth filing on the DXC GitHub

Kyle — Today at 2:17 PM
I'll submit something, thanks.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the supplied HLSL repro with DXC using -T ps_6_6 -E PSMain -Fh test.h test.hlsl, then compare its handling of resources nested in constant-buffer structs with the stated FXC behavior. Done means the unsupported resource placement produces a clear compiler error rather than invalid sizes and offsets; no source files or tests are named in the issue.

Written by the indexing model from the issue text.

Assessment

Domain
compilers, computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.