llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.33k stars 12.12k forks source link

[HLSL] Calculate implicit resource binding information #110722

Open bogner opened 1 month ago

bogner commented 1 month ago

This is the implicit bindings part of the bindings approach originally described in #58051, and is a follow up to #110719.

We need to handle implicit bindings in step 3 of #110719's binding handling, as part of SemaHLSL::handleBindings.

There are two approaches to this:

  1. Mark the bindings as "implicit" and calculate their actual locations later in the compiler
  2. Fill out the bindings as we go.

Approach (2) would be a departure from DXC. There is some discussion of this starting in https://github.com/llvm/llvm-project/issues/58051#issuecomment-2239952237 but we need to discuss this in further detail if we want to pursue it. We would probably need to do some reachability analysis if we wanted to do this.

Some parts of approach (1) are probably necessary regardless of whether we adopt approach (2), because explicitly unbound resources exist in library shaders.

For example, in this case DXC assigns the implicit binding in codegen after optimizations based on which resources in Array are accessed: https://godbolt.org/z/hGYG4rcqb

struct MyBufs {
    RWBuffer<float> Array[4];
};

MyBufs Many : register(u0);
RWBuffer<float> JustOne : register(u0);
RWBuffer<float> SecondOne;

[numthreads(4,1,1)]
void main() {
  Many.Array[2][0] = 1.0; // gets u2
  JustOne[0] = 2.0;       // gets u0
  SecondOne[0] = 3.0;     // gets u1
}

However, when a resource array is a global variable, DXC assumes all values will be used and assigns a slot after the array no matter which values of the array are accessed: https://godbolt.org/z/sdTPh58hc

RWBuffer<float> JustOne : register(u10);
RWBuffer<float> SecondOne;
RWBuffer<float> ArrayHere[4] : register(u0);

[numthreads(4,1,1)]
void main() {
  ArrayHere[2][0] = 3.0;  // gets u0
  JustOne[0] = 2.0;       // gets u10
  SecondOne[0] = 2.0;     // gets u4 - after the array
}
damyanp commented 1 month ago

We need to find an owner for this who can drive taking it to a design meeting to get this task ready to be worked on.