[HLSL] Add GetDimensions to Texture2D. (#189991)
This commit add the GetDimensions methods to Texture2D. For DXIL, it requires intrinsics that are not yet available. They are added, but not implemented. Assisted-by: Gemini Co-authored-by: Helena Kotas <hekotas@microsoft.com>
This commit is contained in:
parent
e0e439ce9f
commit
6331bfa41a
@ -5138,6 +5138,36 @@ def HLSLResourceGetDimensionsX : LangBuiltin<"HLSL_LANG"> {
|
||||
let Prototype = "void(__hlsl_resource_t, uint32_t&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetDimensionsXY : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getdimensions_xy"];
|
||||
let Attributes = [NoThrow];
|
||||
let Prototype = "void(__hlsl_resource_t, uint32_t&, uint32_t&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetDimensionsLevelsXY : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getdimensions_levels_xy"];
|
||||
let Attributes = [NoThrow];
|
||||
let Prototype = "void(__hlsl_resource_t, uint32_t, uint32_t&, uint32_t&, uint32_t&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetDimensionsXFloat : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getdimensions_x_float"];
|
||||
let Attributes = [NoThrow];
|
||||
let Prototype = "void(__hlsl_resource_t, float&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetDimensionsXYFloat : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getdimensions_xy_float"];
|
||||
let Attributes = [NoThrow];
|
||||
let Prototype = "void(__hlsl_resource_t, float&, float&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetDimensionsLevelsXYFloat : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getdimensions_levels_xy_float"];
|
||||
let Attributes = [NoThrow];
|
||||
let Prototype = "void(__hlsl_resource_t, uint32_t, float&, float&, float&)";
|
||||
}
|
||||
|
||||
def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> {
|
||||
let Spellings = ["__builtin_hlsl_resource_getstride"];
|
||||
let Attributes = [NoThrow];
|
||||
|
||||
@ -475,6 +475,37 @@ static Value *emitHlslClamp(CodeGenFunction &CGF, const CallExpr *E,
|
||||
return Clamp;
|
||||
}
|
||||
|
||||
static Value *emitGetDimensions(CodeGenFunction &CGF, const CallExpr *E,
|
||||
unsigned IntrinsicID, unsigned NumRetComps,
|
||||
bool HasLod) {
|
||||
Value *Handle = CGF.EmitScalarExpr(E->getArg(0));
|
||||
|
||||
SmallVector<Value *> Args{Handle};
|
||||
if (HasLod)
|
||||
Args.push_back(CGF.EmitScalarExpr(E->getArg(1)));
|
||||
|
||||
Value *DimValue =
|
||||
CGF.Builder.CreateIntrinsic(IntrinsicID, {Handle->getType()}, Args);
|
||||
|
||||
Value *LastStore = nullptr;
|
||||
unsigned ArgIndex = HasLod ? 2 : 1;
|
||||
for (unsigned i = 0; i < NumRetComps; ++i) {
|
||||
const Expr *Arg = E->getArg(ArgIndex++);
|
||||
LValue DimOut = CGF.EmitLValue(Arg);
|
||||
Value *Elem = DimValue;
|
||||
if (NumRetComps > 1)
|
||||
Elem = CGF.Builder.CreateExtractElement(DimValue, i);
|
||||
|
||||
// Handle float casting if needed
|
||||
if (Arg->getType()->isFloatingType())
|
||||
Elem = CGF.Builder.CreateUIToFP(
|
||||
Elem, llvm::Type::getFloatTy(CGF.getLLVMContext()));
|
||||
|
||||
LastStore = CGF.Builder.CreateStore(Elem, DimOut.getAddress());
|
||||
}
|
||||
return LastStore;
|
||||
}
|
||||
|
||||
Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
|
||||
const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue) {
|
||||
@ -882,15 +913,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
|
||||
RetTy, CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
|
||||
ArrayRef<Value *>{IndexOp});
|
||||
}
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
|
||||
Value *Handle = EmitScalarExpr(E->getArg(0));
|
||||
LValue Dim = EmitLValue(E->getArg(1));
|
||||
llvm::Type *RetTy = llvm::Type::getInt32Ty(getLLVMContext());
|
||||
Value *DimValue = Builder.CreateIntrinsic(
|
||||
RetTy, CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
|
||||
ArrayRef<Value *>{Handle});
|
||||
return Builder.CreateStore(DimValue, Dim.getAddress());
|
||||
}
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_x:
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_x_float:
|
||||
return emitGetDimensions(*this, E,
|
||||
CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
|
||||
1, /*HasLod=*/false);
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_xy:
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_xy_float:
|
||||
return emitGetDimensions(*this, E,
|
||||
CGM.getHLSLRuntime().getGetDimensionsXYIntrinsic(),
|
||||
2, /*HasLod=*/false);
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy:
|
||||
case Builtin::BI__builtin_hlsl_resource_getdimensions_levels_xy_float:
|
||||
return emitGetDimensions(
|
||||
*this, E, CGM.getHLSLRuntime().getGetDimensionsLevelsXYIntrinsic(), 3,
|
||||
/*HasLod=*/true);
|
||||
case Builtin::BI__builtin_hlsl_resource_getstride: {
|
||||
LValue Stride = EmitLValue(E->getArg(1));
|
||||
return emitBufferStride(this, E->getArg(0), Stride);
|
||||
|
||||
@ -193,6 +193,9 @@ public:
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync,
|
||||
group_memory_barrier_with_group_sync)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsX, resource_getdimensions_x)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsXY, resource_getdimensions_xy)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsLevelsXY,
|
||||
resource_getdimensions_levels_xy)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(LoadLevel, resource_load_level)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(CalculateLod, resource_calculate_lod)
|
||||
GENERATE_HLSL_INTRINSIC_FUNCTION(CalculateLodUnclamped,
|
||||
|
||||
@ -1885,6 +1885,53 @@ BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim) {
|
||||
.finalize();
|
||||
}
|
||||
|
||||
BuiltinTypeDeclBuilder &
|
||||
BuiltinTypeDeclBuilder::addGetDimensionsMethods(ResourceDimension Dim) {
|
||||
assert(!Record->isCompleteDefinition() && "record is already complete");
|
||||
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
|
||||
ASTContext &AST = SemaRef.getASTContext();
|
||||
QualType UIntTy = AST.UnsignedIntTy;
|
||||
|
||||
assert(Dim != ResourceDimension::Unknown);
|
||||
|
||||
QualType FloatTy = AST.FloatTy;
|
||||
// Add overloads for uint and float.
|
||||
QualType Params[] = {UIntTy, FloatTy};
|
||||
|
||||
for (QualType OutTy : Params) {
|
||||
if (Dim == ResourceDimension::Dim2D) {
|
||||
StringRef XYName = "__builtin_hlsl_resource_getdimensions_xy";
|
||||
StringRef LevelsXYName =
|
||||
"__builtin_hlsl_resource_getdimensions_levels_xy";
|
||||
|
||||
if (OutTy == FloatTy) {
|
||||
XYName = "__builtin_hlsl_resource_getdimensions_xy_float";
|
||||
LevelsXYName = "__builtin_hlsl_resource_getdimensions_levels_xy_float";
|
||||
}
|
||||
|
||||
// void GetDimensions(out [uint|float] width, out [uint|float] height)
|
||||
BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
|
||||
.addParam("width", OutTy, HLSLParamModifierAttr::Keyword_out)
|
||||
.addParam("height", OutTy, HLSLParamModifierAttr::Keyword_out)
|
||||
.callBuiltin(XYName, QualType(), PH::Handle, PH::_0, PH::_1)
|
||||
.finalize();
|
||||
|
||||
// void GetDimensions(uint mipLevel, out [uint|float] width, out
|
||||
// [uint|float] height, out [uint|float] numberOfLevels)
|
||||
BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
|
||||
.addParam("mipLevel", UIntTy)
|
||||
.addParam("width", OutTy, HLSLParamModifierAttr::Keyword_out)
|
||||
.addParam("height", OutTy, HLSLParamModifierAttr::Keyword_out)
|
||||
.addParam("numberOfLevels", OutTy, HLSLParamModifierAttr::Keyword_out)
|
||||
.callBuiltin(LevelsXYName, QualType(), PH::Handle, PH::_0, PH::_1,
|
||||
PH::_2, PH::_3)
|
||||
.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BuiltinTypeDeclBuilder &
|
||||
BuiltinTypeDeclBuilder::addCalculateLodMethods(ResourceDimension Dim) {
|
||||
assert(!Record->isCompleteDefinition() && "record is already complete");
|
||||
|
||||
@ -126,6 +126,7 @@ public:
|
||||
BuiltinTypeDeclBuilder &addConsumeMethod();
|
||||
|
||||
BuiltinTypeDeclBuilder &addGetDimensionsMethodForBuffer();
|
||||
BuiltinTypeDeclBuilder &addGetDimensionsMethods(ResourceDimension Dim);
|
||||
BuiltinTypeDeclBuilder &addMipsMember(ResourceDimension Dim);
|
||||
|
||||
private:
|
||||
|
||||
@ -272,6 +272,7 @@ static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S,
|
||||
.addSampleCmpMethods(Dim)
|
||||
.addSampleCmpLevelZeroMethods(Dim)
|
||||
.addCalculateLodMethods(Dim)
|
||||
.addGetDimensionsMethods(Dim)
|
||||
.addGatherMethods(Dim)
|
||||
.addGatherCmpMethods(Dim);
|
||||
}
|
||||
|
||||
@ -508,6 +508,88 @@
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<element_type>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<element_type>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<element_type>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}} '<dependent type>'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<element_type>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 2>)' inline
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
|
||||
@ -814,4 +896,10 @@ void main(float2 loc, float cmp) {
|
||||
t.CalculateLevelOfDetail(s, loc);
|
||||
t.CalculateLevelOfDetailUnclamped(s, loc);
|
||||
t.Gather(s, loc);
|
||||
uint u_w, u_h, u_l;
|
||||
float f_w, f_h, f_l;
|
||||
t.GetDimensions(u_w, u_h);
|
||||
t.GetDimensions(0, u_w, u_h, u_l);
|
||||
t.GetDimensions(f_w, f_h);
|
||||
t.GetDimensions(0, f_w, f_h, f_l);
|
||||
}
|
||||
|
||||
@ -512,6 +512,84 @@
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'vector<float, 2>' lvalue ParmVar {{.*}} 'Location' 'vector<float, 2>'
|
||||
// CHECK-NEXT: AlwaysInlineAttr
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_xy' 'void (__hlsl_resource_t, unsigned int &, unsigned int &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<vector<element_type, element_count>>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out unsigned int, out unsigned int, out unsigned int)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy' 'void (__hlsl_resource_t, unsigned int, unsigned int &, unsigned int &, unsigned int &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<vector<element_type, element_count>>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'width' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'height' 'unsigned int &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'numberOfLevels' 'unsigned int &__restrict'
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out float, out float)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_xy_float' 'void (__hlsl_resource_t, float &, float &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<vector<element_type, element_count>>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, out float, out float, out float)'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} mipLevel 'unsigned int'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} width 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} height 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} numberOfLevels 'float &__restrict'
|
||||
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
// CHECK-NEXT: CallExpr {{.*}}
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} '__builtin_hlsl_resource_getdimensions_levels_xy_float' 'void (__hlsl_resource_t, unsigned int, float &, float &, float &) noexcept'
|
||||
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<element_type, element_count>)]]
|
||||
// CHECK-SAME{LITERAL}: [[hlsl::resource_dimension(2D)]]
|
||||
// CHECK-SAME: ' lvalue .__handle
|
||||
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::Texture2D<vector<element_type, element_count>>' lvalue implicit this
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'mipLevel' 'unsigned int'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'width' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'height' 'float &__restrict'
|
||||
// CHECK-NEXT: DeclRefExpr {{.*}} 'float' lvalue ParmVar {{.*}} 'numberOfLevels' 'float &__restrict'
|
||||
|
||||
// CHECK: CXXMethodDecl {{.*}} Gather 'vector<element_type, 4> (hlsl::SamplerState, vector<float, 2>)' inline
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} Sampler 'hlsl::SamplerState'
|
||||
// CHECK-NEXT: ParmVarDecl {{.*}} Location 'vector<float, 2>'
|
||||
@ -818,4 +896,10 @@ void main(float2 loc, float cmp) {
|
||||
t.CalculateLevelOfDetail(s, loc);
|
||||
t.CalculateLevelOfDetailUnclamped(s, loc);
|
||||
t.Gather(s, loc);
|
||||
uint u_w, u_h, u_l;
|
||||
float f_w, f_h, f_l;
|
||||
t.GetDimensions(u_w, u_h);
|
||||
t.GetDimensions(0, u_w, u_h, u_l);
|
||||
t.GetDimensions(f_w, f_h);
|
||||
t.GetDimensions(0, f_w, f_h, f_l);
|
||||
}
|
||||
|
||||
@ -188,16 +188,16 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::ByteAddressBuffer::GetDimensions(unsigned int&)(ptr {{.*}} %this, {{.*}} %dim)
|
||||
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 0, 0), ptr %[[HANDLE_PTR]]
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// DXIL-NEXT: %[[DIM:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_i8_0_0t(target("dx.RawBuffer", i8, 0, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// CHECK-NEXT: store i32 %[[DIM]], ptr %[[DIMPTR]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: define {{.*}} void @hlsl::RWByteAddressBuffer::GetDimensions(unsigned int&)(ptr {{.*}} %this, ptr noalias {{.*}} %dim)
|
||||
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", i8, 1, 0), ptr %[[HANDLE_PTR]]
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// DXIL-NEXT: %[[DIM:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_i8_1_0t(target("dx.RawBuffer", i8, 1, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// CHECK-NEXT: store i32 %[[DIM]], ptr %[[DIMPTR]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
||||
@ -159,8 +159,8 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::StructuredBuffer<float>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}}, ptr {{.*}} %numStructs, ptr {{.*}} %stride)
|
||||
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 0, 0), ptr %__handle
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// DXIL-NEXT: %[[NUMSTRUCTS:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// CHECK-NEXT: store i32 %[[NUMSTRUCTS]], ptr %[[NUMSTRUCTS_PTR]]
|
||||
// CHECK-NEXT: %[[STRIDEPTR:.*]] = load ptr, ptr %stride.addr
|
||||
// CHECK-NEXT: store i32 4, ptr %[[STRIDEPTR]]
|
||||
@ -169,8 +169,8 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::RWStructuredBuffer<unsigned int vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %this, {{.*}} %numStructs, {{.*}} %stride)
|
||||
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer.0", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <4 x i32>, 1, 0), ptr %__handle
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// DXIL-NEXT: %[[NUMSTRUCTS:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_v4i32_1_0t(target("dx.RawBuffer", <4 x i32>, 1, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// CHECK-NEXT: store i32 %[[NUMSTRUCTS]], ptr %[[NUMSTRUCTS_PTR]]
|
||||
// CHECK-NEXT: %[[STRIDEPTR:.*]] = load ptr, ptr %stride.addr
|
||||
// CHECK-NEXT: store i32 16, ptr %[[STRIDEPTR]]
|
||||
@ -179,8 +179,8 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::ConsumeStructuredBuffer<double>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %this, {{.*}} %numStructs, {{.*}} %stride)
|
||||
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ConsumeStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", double, 1, 0), ptr %__handle
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// DXIL-NEXT: %[[NUMSTRUCTS:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_f64_1_0t(target("dx.RawBuffer", double, 1, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// CHECK-NEXT: store i32 %[[NUMSTRUCTS]], ptr %[[NUMSTRUCTS_PTR]]
|
||||
// CHECK-NEXT: %[[STRIDEPTR:.*]] = load ptr, ptr %stride.addr
|
||||
// CHECK-NEXT: store i32 8, ptr %[[STRIDEPTR]]
|
||||
|
||||
@ -117,8 +117,8 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::RasterizerOrderedStructuredBuffer<float>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}}, ptr {{.*}} %numStructs, ptr {{.*}} %stride)
|
||||
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 1), ptr %__handle
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// DXIL-NEXT: %[[NUMSTRUCTS:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// CHECK-NEXT: store i32 %[[NUMSTRUCTS]], ptr %[[NUMSTRUCTS_PTR]]
|
||||
// CHECK-NEXT: %[[STRIDEPTR:.*]] = load ptr, ptr %stride.addr
|
||||
// CHECK-NEXT: store i32 4, ptr %[[STRIDEPTR]]
|
||||
@ -127,8 +127,8 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}}, ptr {{.*}} %numStructs, ptr {{.*}} %stride)
|
||||
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer.0", ptr %{{.*}}, i32 0, i32 0
|
||||
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <2 x i32>, 1, 1), ptr %__handle
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// DXIL-NEXT: %[[NUMSTRUCTS:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.RawBuffer_v2i32_1_1t(target("dx.RawBuffer", <2 x i32>, 1, 1) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[NUMSTRUCTS_PTR:.*]] = load ptr, ptr %numStructs.addr
|
||||
// CHECK-NEXT: store i32 %[[NUMSTRUCTS]], ptr %[[NUMSTRUCTS_PTR]]
|
||||
// CHECK-NEXT: %[[STRIDEPTR:.*]] = load ptr, ptr %stride.addr
|
||||
// CHECK-NEXT: store i32 8, ptr %[[STRIDEPTR]]
|
||||
|
||||
103
clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
Normal file
103
clang/test/CodeGenHLSL/resources/Texture2D-GetDimensions.hlsl
Normal file
@ -0,0 +1,103 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,DXIL
|
||||
// RUN: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -finclude-default-header -o - %s | llvm-cxxfilt | FileCheck %s --check-prefixes=CHECK,SPIRV
|
||||
|
||||
Texture2D<float4> Tex : register(t0);
|
||||
|
||||
// CHECK: define {{.*}} void @test_uint_dims()
|
||||
// CHECK: call void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
|
||||
void test_uint_dims() {
|
||||
uint w, h;
|
||||
Tex.GetDimensions(w, h);
|
||||
}
|
||||
|
||||
// TODO: The test will have to be updated because the return type for the getdimensions intrinsic will no longer a overloaded.
|
||||
|
||||
// CHECK: define linkonce_odr hidden void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
|
||||
// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
|
||||
// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
|
||||
// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]]
|
||||
// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]]
|
||||
// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]])
|
||||
// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]])
|
||||
// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
|
||||
// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0
|
||||
// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]]
|
||||
// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
|
||||
// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1
|
||||
// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]]
|
||||
|
||||
// CHECK: define {{.*}} void @test_uint_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]])
|
||||
// CHECK: call void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
|
||||
void test_uint_levels_dims(uint mipLevel) {
|
||||
uint w, h, l;
|
||||
Tex.GetDimensions(mipLevel, w, h, l);
|
||||
}
|
||||
|
||||
// CHECK: define linkonce_odr hidden void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int, unsigned int&, unsigned int&, unsigned int&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
|
||||
// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
|
||||
// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
|
||||
// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]]
|
||||
// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]]
|
||||
// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]]
|
||||
// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]])
|
||||
// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
|
||||
// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
|
||||
// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0
|
||||
// CHECK: store i32 %[[W_VAL]], ptr %[[W_PTR]]
|
||||
// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
|
||||
// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1
|
||||
// CHECK: store i32 %[[H_VAL]], ptr %[[H_PTR]]
|
||||
// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]]
|
||||
// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2
|
||||
// CHECK: store i32 %[[L_VAL]], ptr %[[L_PTR]]
|
||||
|
||||
// CHECK: define {{.*}} void @test_float_dims()
|
||||
// CHECK: call void @hlsl::Texture2D<float vector[4]>::GetDimensions(float&, float&)(ptr {{.*}} @Tex, ptr {{.*}}, ptr {{.*}})
|
||||
void test_float_dims() {
|
||||
float w, h;
|
||||
Tex.GetDimensions(w, h);
|
||||
}
|
||||
|
||||
// CHECK: define linkonce_odr hidden void @hlsl::Texture2D<float vector[4]>::GetDimensions(float&, float&)(ptr {{.*}} %[[THIS:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]])
|
||||
// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
|
||||
// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
|
||||
// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]]
|
||||
// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]]
|
||||
// DXIL: %[[RES:.*]] = call <2 x i32> @llvm.dx.resource.getdimensions.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]])
|
||||
// SPIRV: %[[RES:.*]] = call <2 x i32> @llvm.spv.resource.getdimensions.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]])
|
||||
// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
|
||||
// CHECK: %[[W_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 0
|
||||
// CHECK: %[[W_F:.*]] = uitofp i32 %[[W_VAL]] to float
|
||||
// CHECK: store float %[[W_F]], ptr %[[W_PTR]]
|
||||
// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
|
||||
// CHECK: %[[H_VAL:.*]] = extractelement <2 x i32> %[[RES]], i64 1
|
||||
// CHECK: %[[H_F:.*]] = uitofp i32 %[[H_VAL]] to float
|
||||
// CHECK: store float %[[H_F]], ptr %[[H_PTR]]
|
||||
|
||||
// CHECK: define {{.*}} void @test_float_levels_dims{{.*}}(i32 noundef %[[MIP_LEVEL:.*]])
|
||||
// CHECK: call void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} @Tex, i32 noundef %{{.*}}, ptr {{.*}}, ptr {{.*}}, ptr {{.*}})
|
||||
void test_float_levels_dims(uint mipLevel) {
|
||||
float w, h, l;
|
||||
Tex.GetDimensions(mipLevel, w, h, l);
|
||||
}
|
||||
|
||||
// CHECK: define linkonce_odr hidden void @hlsl::Texture2D<float vector[4]>::GetDimensions(unsigned int, float&, float&, float&)(ptr {{.*}} %[[THIS:.*]], i32 {{.*}} %[[MIP:.*]], ptr {{.*}} %[[WIDTH:.*]], ptr {{.*}} %[[HEIGHT:.*]], ptr {{.*}} %[[LEVELS:.*]])
|
||||
// CHECK: %[[THIS_VAL:.*]] = load ptr, ptr %[[THIS]]
|
||||
// CHECK: %[[HANDLE_GEP:.*]] = getelementptr inbounds nuw %"class.hlsl::Texture2D", ptr %[[THIS_VAL]], i32 0, i32 0
|
||||
// DXIL: %[[HANDLE:.*]] = load target("dx.Texture", <4 x float>, 0, 0, 0, 2), ptr %[[HANDLE_GEP]]
|
||||
// SPIRV: %[[HANDLE:.*]] = load target("spirv.Image", float, 1, 2, 0, 0, 1, 0), ptr %[[HANDLE_GEP]]
|
||||
// CHECK: %[[MIP_VAL:.*]] = load i32, ptr %[[MIP]]
|
||||
// DXIL: %[[RES:.*]] = call <3 x i32> @llvm.dx.resource.getdimensions.levels.xy.tdx.Texture_v4f32_0_0_0_2t(target("dx.Texture", <4 x float>, 0, 0, 0, 2) %[[HANDLE]], i32 %[[MIP_VAL]])
|
||||
// SPIRV: %[[RES:.*]] = call <3 x i32> @llvm.spv.resource.getdimensions.levels.xy.tspirv.Image_f32_1_2_0_0_1_0t(target("spirv.Image", float, 1, 2, 0, 0, 1, 0) %[[HANDLE]], i32 %[[MIP_VAL]])
|
||||
// CHECK: %[[W_PTR:.*]] = load ptr, ptr %[[WIDTH]]
|
||||
// CHECK: %[[W_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 0
|
||||
// CHECK: %[[W_F:.*]] = uitofp i32 %[[W_VAL]] to float
|
||||
// CHECK: store float %[[W_F]], ptr %[[W_PTR]]
|
||||
// CHECK: %[[H_PTR:.*]] = load ptr, ptr %[[HEIGHT]]
|
||||
// CHECK: %[[H_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 1
|
||||
// CHECK: %[[H_F:.*]] = uitofp i32 %[[H_VAL]] to float
|
||||
// CHECK: store float %[[H_F]], ptr %[[H_PTR]]
|
||||
// CHECK: %[[L_PTR:.*]] = load ptr, ptr %[[LEVELS]]
|
||||
// CHECK: %[[L_VAL:.*]] = extractelement <3 x i32> %[[RES]], i64 2
|
||||
// CHECK: %[[L_F:.*]] = uitofp i32 %[[L_VAL]] to float
|
||||
// CHECK: store float %[[L_F]], ptr %[[L_PTR]]
|
||||
@ -92,16 +92,16 @@ export uint TestGetDimensions() {
|
||||
// CHECK: define {{.*}} void @hlsl::Buffer<float>::GetDimensions(unsigned int&)(ptr {{.*}} %this, ptr noalias {{.*}} %dim)
|
||||
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::Buffer", ptr %this1, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", float, 0, 0, 0), ptr %[[HANDLE_PTR]]
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// DXIL-NEXT: %[[DIM:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// CHECK-NEXT: store i32 %[[DIM]], ptr %[[DIMPTR]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: define {{.*}} void @hlsl::RWBuffer<unsigned int vector[4]>::GetDimensions(unsigned int&)(ptr {{.*}} %this, {{.*}} %dim)
|
||||
// CHECK: %[[HANDLE_PTR:.*]] = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
|
||||
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", <4 x i32>, 1, 0, 0), ptr %[[HANDLE_PTR]]
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// DXIL-NEXT: %[[DIM:.*]] = call i32 @llvm.dx.resource.getdimensions.x.tdx.TypedBuffer_v4i32_1_0_0t(target("dx.TypedBuffer", <4 x i32>, 1, 0, 0) %[[HANDLE]])
|
||||
// CHECK-NEXT: %[[DIMPTR:.*]] = load ptr, ptr %dim.addr
|
||||
// CHECK-NEXT: store i32 %[[DIM]], ptr %[[DIMPTR]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
||||
80
clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl
Normal file
80
clang/test/SemaHLSL/Resources/Texture2D-GetDimensions.hlsl
Normal file
@ -0,0 +1,80 @@
|
||||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -finclude-default-header -fsyntax-only -verify %s
|
||||
|
||||
Texture2D<float4> tex;
|
||||
|
||||
void main() {
|
||||
uint u_w, u_h, u_l;
|
||||
float f_w, f_h, f_l;
|
||||
|
||||
// Valid calls
|
||||
tex.GetDimensions(u_w, u_h);
|
||||
tex.GetDimensions(0, u_w, u_h, u_l);
|
||||
tex.GetDimensions(f_w, f_h);
|
||||
tex.GetDimensions(0, f_w, f_h, f_l);
|
||||
|
||||
// Invalid number of arguments
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions();
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 0 were provided}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 0 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(u_w);
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 1 was provided}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 1 was provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(u_w, u_h, u_l);
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 3 were provided}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 3 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(0, u_w, u_h, u_l, 0);
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 5 were provided}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 5 were provided}}
|
||||
|
||||
// Invalid types
|
||||
int i_w, i_h;
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(i_w, i_h);
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'unsigned int &__restrict' for 1st argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'float &__restrict' for 1st argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(u_w, i_h);
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'int' to 'unsigned int &__restrict' for 2nd argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 1st argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
|
||||
|
||||
// Invalid lvalues
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(0u, u_h);
|
||||
// expected-note@*:* {{candidate function not viable: expects an lvalue for 1st argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'unsigned int' to 'float &__restrict' for 1st argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(u_w, 0u);
|
||||
// expected-note@*:* {{candidate function not viable: expects an lvalue for 2nd argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 1st argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 4 arguments, but 2 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(0, 0u, u_h, u_l);
|
||||
// expected-note@*:* {{candidate function not viable: expects an lvalue for 2nd argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'unsigned int' to 'float &__restrict' for 2nd argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(0, u_w, 0u, u_l);
|
||||
// expected-note@*:* {{candidate function not viable: expects an lvalue for 3rd argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 2nd argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
|
||||
|
||||
// expected-error@+1 {{no matching member function for call to 'GetDimensions'}}
|
||||
tex.GetDimensions(0, u_w, u_h, 0u);
|
||||
// expected-note@*:* {{candidate function not viable: expects an lvalue for 4th argument}}
|
||||
// expected-note@*:* {{candidate function not viable: no known conversion from 'uint' (aka 'unsigned int') to 'float &__restrict' for 2nd argument}}
|
||||
// expected-note@*:* 2 {{candidate function not viable: requires 2 arguments, but 4 were provided}}
|
||||
}
|
||||
@ -79,6 +79,10 @@ def int_dx_resource_updatecounter
|
||||
|
||||
def int_dx_resource_getdimensions_x
|
||||
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_any_ty], [IntrReadMem]>;
|
||||
def int_dx_resource_getdimensions_xy
|
||||
: DefaultAttrsIntrinsic<[llvm_v2i32_ty], [llvm_any_ty], [IntrReadMem]>;
|
||||
def int_dx_resource_getdimensions_levels_xy
|
||||
: DefaultAttrsIntrinsic<[llvm_v3i32_ty], [llvm_any_ty, llvm_i32_ty], [IntrReadMem]>;
|
||||
|
||||
def int_dx_resource_sample
|
||||
: DefaultAttrsIntrinsic<
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user