Skip to content

[DirectX] Lower @llvm.dx.handle.fromBinding to DXIL ops #104251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion llvm/docs/DirectX/DXILResources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ the subsequent ``dx.op.annotateHandle`` operation in. Note that we don't have
an analogue for `dx.op.createHandle`_, since ``dx.op.createHandleFromBinding``
subsumes it.

For simplicity of lowering, we match DXIL in using an index from the beginning
of the binding space rather than an index from the lower bound of the binding
itself.

.. _dx.op.createHandle: https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/DXIL.rst#resource-handles

.. list-table:: ``@llvm.dx.handle.fromBinding``
Expand Down Expand Up @@ -190,7 +194,7 @@ subsumes it.
* - ``%index``
- 4
- ``i32``
- Index of the resource to access.
- Index from the beginning of the binding space to access.
* - ``%non-uniform``
- 5
- i1
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def int_dx_handle_fromBinding
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty],
[IntrNoMem]>;

// Cast between target extension handle types and dxil-style opaque handles
def int_dx_cast_handle : Intrinsic<[llvm_any_ty], [llvm_any_ty]>;

def int_dx_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty]>;
def int_dx_clamp : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
Expand Down
24 changes: 24 additions & 0 deletions llvm/lib/Target/DirectX/DXIL.td
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def FloatTy : DXILOpParamType;
def DoubleTy : DXILOpParamType;
def ResRetTy : DXILOpParamType;
def HandleTy : DXILOpParamType;
def ResBindTy : DXILOpParamType;
def ResPropsTy : DXILOpParamType;

class DXILOpClass;

Expand Down Expand Up @@ -683,6 +685,14 @@ def Dot4 : DXILOp<56, dot4> {
let attributes = [Attributes<DXIL1_0, [ReadNone]>];
}

def CreateHandle : DXILOp<57, createHandle> {
let Doc = "creates the handle to a resource";
// ResourceClass, RangeID, Index, NonUniform
let arguments = [Int8Ty, Int32Ty, Int32Ty, Int1Ty];
let result = HandleTy;
let stages = [Stages<DXIL1_0, [all_stages]>, Stages<DXIL1_6, [removed]>];
}

def ThreadId : DXILOp<93, threadId> {
let Doc = "Reads the thread ID";
let LLVMIntrinsic = int_dx_thread_id;
Expand Down Expand Up @@ -722,3 +732,17 @@ def FlattenedThreadIdInGroup : DXILOp<96, flattenedThreadIdInGroup> {
let stages = [Stages<DXIL1_0, [compute, mesh, amplification, node]>];
let attributes = [Attributes<DXIL1_0, [ReadNone]>];
}

def AnnotateHandle : DXILOp<217, annotateHandle> {
let Doc = "annotate handle with resource properties";
let arguments = [HandleTy, ResPropsTy];
let result = HandleTy;
let stages = [Stages<DXIL1_6, [all_stages]>];
}

def CreateHandleFromBinding : DXILOp<218, createHandleFromBinding> {
let Doc = "create resource handle from binding";
let arguments = [ResBindTy, Int32Ty, Int1Ty];
let result = HandleTy;
let stages = [Stages<DXIL1_6, [all_stages]>];
}
44 changes: 44 additions & 0 deletions llvm/lib/Target/DirectX/DXILOpBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,23 @@ static StructType *getHandleType(LLVMContext &Ctx) {
Ctx);
}

static StructType *getResBindType(LLVMContext &Context) {
if (auto *ST = StructType::getTypeByName(Context, "dx.types.ResBind"))
return ST;
Type *Int32Ty = Type::getInt32Ty(Context);
Type *Int8Ty = Type::getInt8Ty(Context);
return StructType::create({Int32Ty, Int32Ty, Int32Ty, Int8Ty},
"dx.types.ResBind");
}

static StructType *getResPropsType(LLVMContext &Context) {
if (auto *ST =
StructType::getTypeByName(Context, "dx.types.ResourceProperties"))
return ST;
Type *Int32Ty = Type::getInt32Ty(Context);
return StructType::create({Int32Ty, Int32Ty}, "dx.types.ResourceProperties");
}

static Type *getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx,
Type *OverloadTy) {
switch (Kind) {
Expand Down Expand Up @@ -235,6 +252,10 @@ static Type *getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx,
return getResRetType(OverloadTy, Ctx);
case OpParamType::HandleTy:
return getHandleType(Ctx);
case OpParamType::ResBindTy:
return getResBindType(Ctx);
case OpParamType::ResPropsTy:
return getResPropsType(Ctx);
}
llvm_unreachable("Invalid parameter kind");
return nullptr;
Expand Down Expand Up @@ -430,6 +451,29 @@ CallInst *DXILOpBuilder::createOp(dxil::OpCode OpCode, ArrayRef<Value *> Args,
return *Result;
}

StructType *DXILOpBuilder::getHandleType() {
return ::getHandleType(IRB.getContext());
}

Constant *DXILOpBuilder::getResBind(uint32_t LowerBound, uint32_t UpperBound,
uint32_t SpaceID, dxil::ResourceClass RC) {
Type *Int32Ty = IRB.getInt32Ty();
Type *Int8Ty = IRB.getInt8Ty();
return ConstantStruct::get(
getResBindType(IRB.getContext()),
{ConstantInt::get(Int32Ty, LowerBound),
ConstantInt::get(Int32Ty, UpperBound),
ConstantInt::get(Int32Ty, SpaceID),
ConstantInt::get(Int8Ty, llvm::to_underlying(RC))});
}

Constant *DXILOpBuilder::getResProps(uint32_t Word0, uint32_t Word1) {
Type *Int32Ty = IRB.getInt32Ty();
return ConstantStruct::get(
getResPropsType(IRB.getContext()),
{ConstantInt::get(Int32Ty, Word0), ConstantInt::get(Int32Ty, Word1)});
}

const char *DXILOpBuilder::getOpCodeName(dxil::OpCode DXILOp) {
return ::getOpCodeName(DXILOp);
}
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/Target/DirectX/DXILOpBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "DXILConstants.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/DXILABI.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Triple.h"

namespace llvm {
class Module;
class IRBuilderBase;
class CallInst;
class Constant;
class Value;
class Type;
class FunctionType;
Expand All @@ -44,6 +46,15 @@ class DXILOpBuilder {
Expected<CallInst *> tryCreateOp(dxil::OpCode Op, ArrayRef<Value *> Args,
Type *RetTy = nullptr);

/// Get the `%dx.types.Handle` type.
StructType *getHandleType();

/// Get a constant `%dx.types.ResBind` value.
Constant *getResBind(uint32_t LowerBound, uint32_t UpperBound,
uint32_t SpaceID, dxil::ResourceClass RC);
/// Get a constant `%dx.types.ResourceProperties` value.
Constant *getResProps(uint32_t Word0, uint32_t Word1);

/// Return the name of the given opcode.
static const char *getOpCodeName(dxil::OpCode DXILOp);

Expand Down
Loading
Loading