Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsDirectX.td
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def int_dx_resource_updatecounter
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_i8_ty],
[IntrInaccessibleMemOrArgMemOnly]>;

def int_dx_resource_getdimensions_x
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_any_ty], [IntrReadMem]>;

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

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsSPIRV.td
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_i8_ty],
[IntrInaccessibleMemOrArgMemOnly]>;

def int_spv_resource_getdimensions_x
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_any_ty], [IntrReadMem]>;

def int_spv_resource_getpointer
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_i32_ty],
[IntrNoMem]>;
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/DirectX/DXIL.td
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def ResBindTy : DXILOpParamType;
def ResPropsTy : DXILOpParamType;
def SplitDoubleTy : DXILOpParamType;
def BinaryWithCarryTy : DXILOpParamType;
def DimensionsTy : DXILOpParamType;

class DXILOpClass;

Expand Down Expand Up @@ -901,6 +902,13 @@ def CheckAccessFullyMapped : DXILOp<71, checkAccessFullyMapped> {
let attributes = [Attributes<DXIL1_0, [ReadOnly]>];
}

def GetDimensions : DXILOp<72, getDimensions> {
let Doc = "gets the dimensions of a buffer or texture";
let arguments = [HandleTy, Int32Ty];
let result = DimensionsTy;
let stages = [Stages<DXIL1_0, [all_stages]>];
}

def Barrier : DXILOp<80, barrier> {
let Doc = "inserts a memory barrier in the shader";
let intrinsics = [
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/DirectX/DXILOpBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@ static StructType *getBinaryWithCarryType(LLVMContext &Context) {
return StructType::create({Int32Ty, Int1Ty}, "dx.types.i32c");
}

static StructType *getDimensionsType(LLVMContext &Ctx) {
Type *Int32Ty = Type::getInt32Ty(Ctx);
return getOrCreateStructType("dx.types.Dimensions",
{Int32Ty, Int32Ty, Int32Ty, Int32Ty}, Ctx);
}

static Type *getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx,
Type *OverloadTy) {
switch (Kind) {
Expand Down Expand Up @@ -318,6 +324,8 @@ static Type *getTypeFromOpParamType(OpParamType Kind, LLVMContext &Ctx,
return getSplitDoubleType(Ctx);
case OpParamType::BinaryWithCarryTy:
return getBinaryWithCarryType(Ctx);
case OpParamType::DimensionsTy:
return getDimensionsType(Ctx);
}
llvm_unreachable("Invalid parameter kind");
return nullptr;
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/DirectX/DXILOpLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,28 @@ class OpLowerer {
});
}

[[nodiscard]] bool lowerGetDimensionsX(Function &F) {
IRBuilder<> &IRB = OpBuilder.getIRB();
Type *Int32Ty = IRB.getInt32Ty();

return replaceFunction(F, [&](CallInst *CI) -> Error {
IRB.SetInsertPoint(CI);
Value *Handle =
createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
Value *Undef = UndefValue::get(Int32Ty);

Expected<CallInst *> OpCall = OpBuilder.tryCreateOp(
OpCode::GetDimensions, {Handle, Undef}, CI->getName(), Int32Ty);
if (Error E = OpCall.takeError())
return E;
Value *Dim = IRB.CreateExtractValue(*OpCall, 0);

CI->replaceAllUsesWith(Dim);
CI->eraseFromParent();
return Error::success();
});
}

[[nodiscard]] bool lowerGetPointer(Function &F) {
// These should have already been handled in DXILResourceAccess, so we can
// just clean up the dead prototype.
Expand Down Expand Up @@ -934,6 +956,9 @@ class OpLowerer {
case Intrinsic::dx_resource_updatecounter:
HasErrors |= lowerUpdateCounter(F);
break;
case Intrinsic::dx_resource_getdimensions_x:
HasErrors |= lowerGetDimensionsX(F);
break;
case Intrinsic::ctpop:
HasErrors |= lowerCtpopToCountBits(F);
break;
Expand Down
16 changes: 16 additions & 0 deletions llvm/test/CodeGen/DirectX/bufferGetDimensions.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: opt -S -dxil-op-lower %s | FileCheck %s

target triple = "dxil-pc-shadermodel6.6-compute"

define i32 @test_getdimensions_no_mips() {
; CHECK: %[[HANDLE:.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217,
; CHECK-NEXT: %[[ANNOT_HANDLE:.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %[[HANDLE]]
%handle = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0) @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null)

; CHECK-NEXT: %[[RETVAL:.*]] = call %dx.types.Dimensions @dx.op.getDimensions(i32 72, %dx.types.Handle %[[ANNOT_HANDLE]], i32 undef)
; CHECK-NEXT: %[[DIM:.*]] = extractvalue %dx.types.Dimensions %[[RETVAL]], 0
%1 = call i32 @llvm.dx.resource.getdimensions.x(target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %handle)

; CHECK-NEXT: ret i32 %[[DIM]]
ret i32 %1
}
Loading