llvm / llvm-project

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

[HLSL] Use constructors for resource handle initialization #111566

Open hekota opened 2 days ago

hekota commented 2 days ago

This needs design / planning work before we can estimate it.

Resource handle initialization should be done via resource class constructors. If a resource is declared in a global variable, the compiler should make sure to call a constructor that takes binding information, which will later be translated to dx.handle.fromBinding.

Resources declared as local variables would use a default constructor that will initialize the handle to 'empty' or 'null', or simply leave it undefined. Another resource can be assigned to these local variables and a copy constructor and/or assignment operator will take care of copying the resource handle.

This should greatly simplify handling of resources, including when they are dynamically bound, used as function in/out parameters, declared in unbounded arrays or used defined types.

Resource classes should look like this:

struct Binding;

template <typename T> struct RWBuffer {
private:
  using handle_t = __hlsl_resource_t
      [[hlsl::contained_type(T)]] [[hlsl::resource_class(UAV)]];
  handle_t h;

public:
  // For uninitialized handles
  RWBuffer() { h = __builtin_hlsl_create_poison_handle(); }

  // Resources are copyable.
  RWBuffer(RWBuffer &LHS) = default;

  // For handles constructed as globals with binding information, or from the
  // descriptor heap.
  RWBuffer(Binding &B) { h = __builtin_create_handle_from_binding(B); }

  ~RWBuffer() = default;

  RWBuffer &operator=(RWBuffer &LHS) {
    h = LHS.h;
    return *this
  }
...  
}

Follow-up from #105076.

llvm-beanz commented 2 days ago

We've also defined inout parameters as initializing in with the copy constructor and assigning back with the assignment operator, so having those both defined for resources will make everything work as expected. They can both be = default.