diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 94e153d664..e218fdd9db 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -2426,6 +2426,7 @@ ID Name Description 309 VectorReduceAnd Bitwise AND reduction of the vector returning a scalar 310 VectorReduceOr Bitwise OR reduction of the vector returning a scalar 311 FDot computes the n-dimensional vector dot-product +312 CreateMatrix creates the handle to a matrix === ===================================================== ======================================================================================================================================================================================================================= diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index d66f14a1e9..593ab9a9e7 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -754,6 +754,7 @@ enum class OpCode : unsigned { 160, // create resource handle from resource struct for library // Linear Algebra Operations + CreateMatrix = 312, // creates the handle to a matrix MatVecMul = 305, // Multiplies a MxK dimension matrix and a K sized input vector MatVecMulAdd = 306, // multiplies a MxK dimension matrix and a K sized input @@ -1089,7 +1090,7 @@ enum class OpCode : unsigned { NumOpCodes_Dxil_1_8 = 258, NumOpCodes_Dxil_1_9 = 312, - NumOpCodes = 312 // exclusive last value of enumeration + NumOpCodes = 313 // exclusive last value of enumeration }; // OPCODE-ENUM:END @@ -1232,6 +1233,7 @@ enum class OpCodeClass : unsigned { CreateHandleForLib, // Linear Algebra Operations + CreateMatrix, MatVecMul, MatVecMulAdd, OuterProductAccumulate, @@ -1425,7 +1427,7 @@ enum class OpCodeClass : unsigned { NumOpClasses_Dxil_1_8 = 174, NumOpClasses_Dxil_1_9 = 196, - NumOpClasses = 196 // exclusive last value of enumeration + NumOpClasses = 197 // exclusive last value of enumeration }; // OPCODECLASS-ENUM:END diff --git a/include/dxc/DXIL/DxilInstructions.h b/include/dxc/DXIL/DxilInstructions.h index 726d9615ac..438e402726 100644 --- a/include/dxc/DXIL/DxilInstructions.h +++ b/include/dxc/DXIL/DxilInstructions.h @@ -10231,5 +10231,25 @@ struct DxilInst_FDot { llvm::Value *get_b() const { return Instr->getOperand(2); } void set_b(llvm::Value *val) { Instr->setOperand(2, val); } }; + +/// This instruction creates the handle to a matrix +struct DxilInst_CreateMatrix { + llvm::Instruction *Instr; + // Construction and identification + DxilInst_CreateMatrix(llvm::Instruction *pInstr) : Instr(pInstr) {} + operator bool() const { + return hlsl::OP::IsDxilOpFuncCallInst(Instr, + hlsl::OP::OpCode::CreateMatrix); + } + // Validation support + bool isAllowed() const { return true; } + bool isArgumentListValid() const { + if (1 != llvm::dyn_cast(Instr)->getNumArgOperands()) + return false; + return true; + } + // Metadata + bool requiresUniformInputs() const { return false; } +}; // INSTR-HELPER:END } // namespace hlsl diff --git a/include/dxc/DXIL/DxilOperations.h b/include/dxc/DXIL/DxilOperations.h index c8b6762b3f..1ecff96f71 100644 --- a/include/dxc/DXIL/DxilOperations.h +++ b/include/dxc/DXIL/DxilOperations.h @@ -83,6 +83,7 @@ class OP { llvm::LLVMContext &GetCtx() { return m_Ctx; } llvm::Module *GetModule() { return m_pModule; } llvm::Type *GetHandleType() const; + llvm::Type *GetMatrixRefType() const; llvm::Type *GetHitObjectType() const; llvm::Type *GetNodeHandleType() const; llvm::Type *GetNodeRecordHandleType() const; @@ -188,6 +189,7 @@ class OP { llvm::Type *m_pSplitDoubleType; llvm::Type *m_pFourI32Type; llvm::Type *m_pFourI16Type; + llvm::Type *m_pMatrixRefType; DXIL::LowPrecisionMode m_LowPrecisionMode; diff --git a/include/dxc/DXIL/DxilUtil.h b/include/dxc/DXIL/DxilUtil.h index ca8f2ac755..4ead0cea68 100644 --- a/include/dxc/DXIL/DxilUtil.h +++ b/include/dxc/DXIL/DxilUtil.h @@ -164,6 +164,8 @@ bool IsHLSLObjectType(llvm::Type *Ty); bool IsHLSLRayQueryType(llvm::Type *Ty); llvm::Type *GetHLSLHitObjectType(llvm::Module *M); bool IsHLSLHitObjectType(llvm::Type *Ty); +llvm::Type *GetHLSLMatrixRefType(llvm::Module *M); +bool IsHLSLMatrixRefType(llvm::Type *Ty); bool IsHLSLResourceDescType(llvm::Type *Ty); bool IsResourceSingleComponent(llvm::Type *Ty); uint8_t GetResourceComponentCount(llvm::Type *Ty); diff --git a/include/dxc/HlslIntrinsicOp.h b/include/dxc/HlslIntrinsicOp.h index e1c1b3e7f5..9b199b19f2 100644 --- a/include/dxc/HlslIntrinsicOp.h +++ b/include/dxc/HlslIntrinsicOp.h @@ -111,6 +111,7 @@ enum class IntrinsicOp { IOP___builtin_MatVecMulAdd = 391, IOP___builtin_OuterProductAccumulate = 392, IOP___builtin_VectorAccumulate = 393, + IOP___builtin_la_CreateMatrix = 395, IOP_abort = 102, IOP_abs = 103, IOP_acos = 104, @@ -401,7 +402,7 @@ enum class IntrinsicOp { IOP_usign = 355, MOP_InterlockedUMax = 356, MOP_InterlockedUMin = 357, - Num_Intrinsics = 395, + Num_Intrinsics = 396, }; inline bool HasUnsignedIntrinsicOpcode(IntrinsicOp opcode) { switch (opcode) { diff --git a/include/dxc/dxcapi.internal.h b/include/dxc/dxcapi.internal.h index 46a485206e..1db4002770 100644 --- a/include/dxc/dxcapi.internal.h +++ b/include/dxc/dxcapi.internal.h @@ -130,15 +130,17 @@ enum LEGAL_INTRINSIC_COMPTYPES { LICOMPTYPE_HIT_OBJECT = 51, LICOMPTYPE_RAY_QUERY = 52, - LICOMPTYPE_LINALG = 53, // f32, partial-precision-f32, f16, + LICOMPTYPE_MATRIX_REF = 53, + + LICOMPTYPE_LINALG = 54, // f32, partial-precision-f32, f16, // i32, i16, u32, u16, // int8_4packed, uint8_4packed #ifdef ENABLE_SPIRV_CODEGEN - LICOMPTYPE_VK_BUFFER_POINTER = 54, - LICOMPTYPE_COUNT = 55 + LICOMPTYPE_VK_BUFFER_POINTER = 55, + LICOMPTYPE_COUNT = 56 #else - LICOMPTYPE_COUNT = 54 + LICOMPTYPE_COUNT = 55 #endif }; diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index 9902ef8d14..89e75ad243 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -2714,6 +2714,16 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = { 1, {{0x400}}, {{0x3}}}, // Overloads: getName() == "dx.types.HitObject"; } +llvm::Type *GetHLSLMatrixRefType(llvm::Module *M) { + using namespace llvm; + StructType *MatrixRefTy = M->getTypeByName("dx.types.MatrixRef"); + if (!MatrixRefTy) + MatrixRefTy = StructType::create({Type::getInt8PtrTy(M->getContext(), 0)}, + "dx.types.MatrixRef", false); + return MatrixRefTy; +} + +bool IsHLSLMatrixRefType(llvm::Type *Ty) { + llvm::StructType *ST = dyn_cast(Ty); + if (!ST) + return false; + if (!ST->hasName()) + return false; + return ST->getName() == "dx.types.MatrixRef"; +} + bool IsHLSLResourceDescType(llvm::Type *Ty) { if (llvm::StructType *ST = dyn_cast(Ty)) { if (!ST->hasName()) diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index c9c9bb4c88..ff6b0ae36c 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -6598,7 +6598,10 @@ Value *TranslateSelect(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode, return Builder.CreateSelect(cond, t, f); } +} // namespace +// Translate linear algebra intrinsics +namespace { Value *TranslateMatVecMul(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, @@ -6792,6 +6795,22 @@ Value *TranslateVectorAccumulate(CallInst *CI, IntrinsicOp IOP, {OpArg, InputVector, MatrixBuffer, MatrixOffset}); } +Value *TranslateLACreateMatrix(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + + hlsl::OP *HlslOP = &Helper.hlslOP; + IRBuilder<> Builder(CI); + Value *MatrixRefPtr = CI->getArgOperand(1); + Value *MatrixRef = TrivialDxilOperation( + OpCode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, HlslOP); + Builder.CreateStore(MatrixRef, MatrixRefPtr); + DXASSERT( + CI->use_empty(), + "Default ctor return type is a Clang artifact. Value must not be used"); + return nullptr; +} } // namespace // Lower table. @@ -7513,6 +7532,9 @@ IntrinsicLower gLowerTable[] = { {IntrinsicOp::IOP___builtin_VectorAccumulate, TranslateVectorAccumulate, DXIL::OpCode::VectorAccumulate}, {IntrinsicOp::IOP_isnormal, TrivialIsSpecialFloat, DXIL::OpCode::IsNormal}, + + {IntrinsicOp::IOP___builtin_la_CreateMatrix, TranslateLACreateMatrix, + DXIL::OpCode::CreateMatrix}, }; } // namespace static_assert( diff --git a/tools/clang/include/clang/AST/HlslTypes.h b/tools/clang/include/clang/AST/HlslTypes.h index 43c1effdb8..00522079fd 100644 --- a/tools/clang/include/clang/AST/HlslTypes.h +++ b/tools/clang/include/clang/AST/HlslTypes.h @@ -393,6 +393,7 @@ DeclareConstantBufferViewType(clang::ASTContext &context, clang::InheritableAttr *Attr); clang::CXXRecordDecl *DeclareRayQueryType(clang::ASTContext &context); clang::CXXRecordDecl *DeclareHitObjectType(clang::NamespaceDecl &NSDecl); +clang::CXXRecordDecl *DeclareMatrixRefType(clang::ASTContext &context); clang::CXXRecordDecl *DeclareResourceType(clang::ASTContext &context, bool bSampler); @@ -480,6 +481,7 @@ bool IsHLSLDynamicResourceType(clang::QualType type); bool IsHLSLDynamicSamplerType(clang::QualType type); bool IsHLSLNodeType(clang::QualType type); bool IsHLSLHitObjectType(clang::QualType type); +bool IsHLSLMatrixRefType(clang::QualType type); bool IsHLSLObjectWithImplicitMemberAccess(clang::QualType type); bool IsHLSLObjectWithImplicitROMemberAccess(clang::QualType type); diff --git a/tools/clang/include/clang/Basic/Attr.td b/tools/clang/include/clang/Basic/Attr.td index 83137dbc3a..4536a982f5 100644 --- a/tools/clang/include/clang/Basic/Attr.td +++ b/tools/clang/include/clang/Basic/Attr.td @@ -1190,6 +1190,14 @@ def HLSLHitObject : InheritableAttr { let Documentation = [Undocumented]; } +// HLSL MatrixRef Attribute + +def HLSLMatrixRef : InheritableAttr { + let Spellings = []; // No spellings! + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [Undocumented]; +} + // HLSL Parameter Attributes def HLSLMaxRecords : InheritableAttr { diff --git a/tools/clang/lib/AST/ASTContextHLSL.cpp b/tools/clang/lib/AST/ASTContextHLSL.cpp index 913b28ced8..f72987add7 100644 --- a/tools/clang/lib/AST/ASTContextHLSL.cpp +++ b/tools/clang/lib/AST/ASTContextHLSL.cpp @@ -1306,6 +1306,48 @@ CXXRecordDecl *hlsl::DeclareHitObjectType(NamespaceDecl &NSDecl) { return RecordDecl; } +CXXRecordDecl *hlsl::DeclareMatrixRefType(ASTContext &Context) { + // MatrixRef { ... } + BuiltinTypeDeclBuilder TypeDeclBuilder(Context.getTranslationUnitDecl(), + "__builtin_la_MatrixRef"); + TypeDeclBuilder.startDefinition(); + + // Add handle to mark as HLSL object. + TypeDeclBuilder.addField("h", GetHLSLObjectHandleType(Context)); + CXXRecordDecl *RecordDecl = TypeDeclBuilder.getRecordDecl(); + + CanQualType canQualType = Context.getCanonicalType( + Context.getRecordType(TypeDeclBuilder.getRecordDecl())); + + // Add constructor that will be lowered to IOP___builtin_la_CreateMatrix. + CXXConstructorDecl *pConstructorDecl = nullptr; + TypeSourceInfo *pTypeSourceInfo = nullptr; + CreateConstructorDeclaration( + Context, RecordDecl, Context.VoidTy, {}, + Context.DeclarationNames.getCXXConstructorName(canQualType), false, + &pConstructorDecl, &pTypeSourceInfo); + RecordDecl->addDecl(pConstructorDecl); + pConstructorDecl->addAttr(HLSLIntrinsicAttr::CreateImplicit( + Context, "op", "", + static_cast(hlsl::IntrinsicOp::IOP___builtin_la_CreateMatrix))); + pConstructorDecl->addAttr(HLSLCXXOverloadAttr::CreateImplicit(Context)); + + // Add AvailabilityAttribute for SM6.10+ + VersionTuple VT610 = VersionTuple(6, 10); + AvailabilityAttr *AAttr = AvailabilityAttr::CreateImplicit( + Context, &Context.Idents.get(""), clang::VersionTuple(6, 10), + clang::VersionTuple(), clang::VersionTuple(), false, ""); + RecordDecl->addAttr(AAttr); + + // Add the implicit HLSLMatrixRefAttr attribute to unambiguously recognize the + // builtin HitObject type. + RecordDecl->addAttr(HLSLMatrixRefAttr::CreateImplicit(Context)); + RecordDecl->setImplicit(true); + + // Add to namespace + return RecordDecl; +} + CXXRecordDecl *hlsl::DeclareResourceType(ASTContext &context, bool bSampler) { // struct ResourceDescriptor { uint8 desc; } StringRef Name = bSampler ? ".Sampler" : ".Resource"; diff --git a/tools/clang/lib/AST/HlslTypes.cpp b/tools/clang/lib/AST/HlslTypes.cpp index 00c18a81a9..e9c582557f 100644 --- a/tools/clang/lib/AST/HlslTypes.cpp +++ b/tools/clang/lib/AST/HlslTypes.cpp @@ -528,6 +528,10 @@ bool IsHLSLHitObjectType(QualType type) { return nullptr != getAttr(type); } +bool IsHLSLMatrixRefType(QualType type) { + return nullptr != getAttr(type); +} + DXIL::NodeIOKind GetNodeIOType(clang::QualType type) { if (const HLSLNodeObjectAttr *Attr = getAttr(type)) return Attr->getNodeIOType(); diff --git a/tools/clang/lib/CodeGen/CodeGenTypes.cpp b/tools/clang/lib/CodeGen/CodeGenTypes.cpp index 82328c8fb5..e32f6ce54d 100644 --- a/tools/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/tools/clang/lib/CodeGen/CodeGenTypes.cpp @@ -369,6 +369,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { .getTypePtr(); } else if (hlsl::IsHLSLHitObjectType(T)) // HLSL Change return hlsl::dxilutil::GetHLSLHitObjectType(&TheModule); + else if (hlsl::IsHLSLMatrixRefType(T)) // HLSL Change + return hlsl::dxilutil::GetHLSLMatrixRefType(&TheModule); else return ConvertRecordDeclType(RT->getDecl()); } diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index e9c8c90a2d..d7cc268f57 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -253,6 +253,9 @@ enum ArBasicKind { // Shader Execution Reordering AR_OBJECT_HIT_OBJECT, + // Linear Algebrea + AR_OBJECT_MATRIX_REF, + AR_BASIC_MAXIMUM_COUNT }; @@ -607,6 +610,9 @@ const UINT g_uBasicKindProps[] = { // Shader Execution Reordering LICOMPTYPE_HIT_OBJECT, // AR_OBJECT_HIT_OBJECT, + // Linear Algebrea + LICOMPTYPE_MATRIX_REF, // AR_OBJECT_MATRIX_REF, + // AR_BASIC_MAXIMUM_COUNT }; @@ -1247,6 +1253,10 @@ static const ArBasicKind g_AnyOutputRecordCT[] = { static const ArBasicKind g_DxHitObjectCT[] = {AR_OBJECT_HIT_OBJECT, AR_BASIC_UNKNOWN}; +// Linear Algebra +static const ArBasicKind g_MatrixRefCT[] = {AR_OBJECT_MATRIX_REF, + AR_BASIC_UNKNOWN}; + #ifdef ENABLE_SPIRV_CODEGEN static const ArBasicKind g_VKBufferPointerCT[] = {AR_OBJECT_VK_BUFFER_POINTER, AR_BASIC_UNKNOWN}; @@ -1308,6 +1318,7 @@ const ArBasicKind *g_LegalIntrinsicCompTypes[] = { g_ThreadNodeOutputRecordsCT, // LICOMPTYPE_THREAD_NODE_OUTPUT_RECORDS g_DxHitObjectCT, // LICOMPTYPE_HIT_OBJECT g_RayQueryCT, // LICOMPTYPE_RAY_QUERY + g_MatrixRefCT, // LICOMPTYPE_MATRIX_REF g_LinAlgCT, // LICOMPTYPE_LINALG #ifdef ENABLE_SPIRV_CODEGEN g_VKBufferPointerCT, // LICOMPTYPE_VK_BUFFER_POINTER @@ -1404,7 +1415,10 @@ static const ArBasicKind g_ArBasicKindsAsTypes[] = { AR_OBJECT_THREAD_NODE_OUTPUT_RECORDS, AR_OBJECT_GROUP_NODE_OUTPUT_RECORDS, // Shader Execution Reordering - AR_OBJECT_HIT_OBJECT}; + AR_OBJECT_HIT_OBJECT, + + // Linear Algebra + AR_OBJECT_MATRIX_REF}; // Count of template arguments for basic kind of objects that look like // templates (one or more type arguments). @@ -1524,6 +1538,9 @@ static const uint8_t g_ArBasicKindsTemplateCount[] = { // Shader Execution Reordering 0, // AR_OBJECT_HIT_OBJECT, + + // Linear Algebra + 0, // AR_OBJECT_MATRIX_REF, }; C_ASSERT(_countof(g_ArBasicKindsAsTypes) == @@ -1674,6 +1691,9 @@ static const SubscriptOperatorRecord g_ArBasicKindsSubscripts[] = { // Shader Execution Reordering {0, MipsFalse, SampleFalse}, // AR_OBJECT_HIT_OBJECT, + + // Linear Algebra + {0, MipsFalse, SampleFalse}, // AR_OBJECT_MATRIX_REF, }; C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsSubscripts)); @@ -1841,6 +1861,9 @@ static const char *g_ArBasicTypeNames[] = { // Shader Execution Reordering "HitObject", + + // Linear Algebra + "__builtin_la_MatrixRef", }; C_ASSERT(_countof(g_ArBasicTypeNames) == AR_BASIC_MAXIMUM_COUNT); @@ -3605,6 +3628,9 @@ class HLSLExternalSource : public ExternalSemaSource { case LICOMPTYPE_HIT_OBJECT: paramTypes.push_back(GetBasicKindType(AR_OBJECT_HIT_OBJECT)); break; + case LICOMPTYPE_MATRIX_REF: + paramTypes.push_back(GetBasicKindType(AR_OBJECT_MATRIX_REF)); + break; #ifdef ENABLE_SPIRV_CODEGEN case LICOMPTYPE_VK_BUFFER_POINTER: { const ArBasicKind *match = @@ -3864,6 +3890,8 @@ class HLSLExternalSource : public ExternalSemaSource { // Declare 'HitObject' in '::dx' extension namespace. DXASSERT(m_dxNSDecl, "namespace ::dx must be declared in SM6.9+"); recordDecl = DeclareHitObjectType(*m_dxNSDecl); + } else if (kind == AR_OBJECT_MATRIX_REF) { + recordDecl = DeclareMatrixRefType(*m_context); } else if (kind == AR_OBJECT_HEAP_RESOURCE) { recordDecl = DeclareResourceType(*m_context, /*bSampler*/ false); if (SM->IsSM66Plus()) { @@ -4860,6 +4888,7 @@ class HLSLExternalSource : public ExternalSemaSource { case AR_OBJECT_ACCELERATION_STRUCT: case AR_OBJECT_RAY_DESC: case AR_OBJECT_HIT_OBJECT: + case AR_OBJECT_MATRIX_REF: case AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES: case AR_OBJECT_RWTEXTURE2DMS: case AR_OBJECT_RWTEXTURE2DMS_ARRAY: diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_make_ast.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_make_ast.hlsl index ab604b9213..df84f538b7 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_make_ast.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_make_ast.hlsl @@ -58,4 +58,4 @@ void main() { dx::HitObject miss3 = dx::HitObject::MakeMiss(0, 2, ray); Use(miss3); -} \ No newline at end of file +} diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_in_buffer.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_in_buffer.hlsl new file mode 100644 index 0000000000..b5b7e664e6 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_in_buffer.hlsl @@ -0,0 +1,5 @@ +// REQUIRES dxil-1-10 +// RUN: %dxc -T lib_6_10 %s -verify + +// expected-error@+1{{object '__builtin_la_MatrixRef' is not allowed in builtin template parameters}} +RWStructuredBuffer<__builtin_la_MatrixRef> InvalidBuffer; diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_make.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_make.hlsl new file mode 100644 index 0000000000..4855e3e7fa --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_make.hlsl @@ -0,0 +1,25 @@ +// REQUIRES: dxil-1-10 +// RUN: %dxc -T cs_6_10 -E main %s -ast-dump-implicit | FileCheck %s --check-prefix AST +// RUN: %dxc -T cs_6_10 -E main %s | FileCheck %s --check-prefix DXIL + +// AST: |-CXXRecordDecl {{[^ ]+}} <> implicit referenced class __builtin_la_MatrixRef definition +// AST-NEXT: | |-FinalAttr {{[^ ]+}} <> Implicit final +// AST-NEXT: | |-AvailabilityAttr {{[^ ]+}} <> Implicit 6.10 0 0 "" +// AST-NEXT: | |-HLSLMatrixRefAttr {{[^ ]+}} <> Implicit +// AST-NEXT: | |-FieldDecl {{[^ ]+}} <> implicit h 'int' +// AST-NEXT: | |-CXXConstructorDecl {{[^ ]+}} <> __builtin_la_MatrixRef 'void ()' +// AST-NEXT: | | |-HLSLIntrinsicAttr {{[^ ]+}} <> Implicit "op" "" 395 +// AST-NEXT: | | `-HLSLCXXOverloadAttr {{[^ ]+}} <> Implicit +// AST-NEXT: | `-CXXDestructorDecl {{[^ ]+}} <> implicit referenced ~__builtin_la_MatrixRef 'void () noexcept' inline + + +// AST: `-FunctionDecl {{[^ ]+}} <> implicit used __builtin_la_CreateMatrix '__builtin_la_MatrixRef ()' extern +// AST-NEXT: |-HLSLIntrinsicAttr {{[^ ]+}} <> Implicit "op" "" 395 +// AST-NEXT: |-AvailabilityAttr {{[^ ]+}} <> Implicit 6.10 0 0 "" + +// DXIL-LABEL: define void @main() +[numthreads(4,1,1)] +void main() { + // DXIL: call %dx.types.MatrixRef @dx.op.createMatrix(i32 312) ; CreateMatrix() + __builtin_la_MatrixRef mat = __builtin_la_CreateMatrix(); +} diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_unavailable_pre_sm610.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_unavailable_pre_sm610.hlsl new file mode 100644 index 0000000000..c419eac378 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/objects/MatrixRef/matrixref_unavailable_pre_sm610.hlsl @@ -0,0 +1,8 @@ +// RUN: %dxc -T cs_6_9 -E main %s -verify + +[numthreads(4,1,1)] +void main() { + // expected-error@+2{{intrinsic __builtin_la_CreateMatrix potentially used by ''main'' requires shader model 6.10 or greater}} + // expected-error@+1{{potential misuse of built-in type '__builtin_la_MatrixRef' in shader model cs_6_9; introduced in shader model 6.10}} + __builtin_la_MatrixRef mat = __builtin_la_CreateMatrix(); +} diff --git a/utils/hct/gen_intrin_main.txt b/utils/hct/gen_intrin_main.txt index 3fb30781b0..a62f36397f 100644 --- a/utils/hct/gen_intrin_main.txt +++ b/utils/hct/gen_intrin_main.txt @@ -389,6 +389,9 @@ void [[min_sm=6.10]] __builtin_OuterProductAccumulate(in LinAlg InputVector1, void [[min_sm=6.10]] __builtin_VectorAccumulate(in LinAlg InputVector, in RWByteAddressBuffer MatrixBuffer, in uint MatrixOffset); + +MatrixRef [[min_sm=6.10]] __builtin_la_CreateMatrix(); + } namespace diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 5d86d1a3e9..8117811dc6 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -874,7 +874,7 @@ def populate_categories_and_models(self): "raygeneration", ) for i in ( - "MatVecMul,MatVecMulAdd,OuterProductAccumulate,VectorAccumulate" + "MatVecMul,MatVecMulAdd,OuterProductAccumulate,VectorAccumulate,CreateMatrix" ).split(","): self.name_idx[i].category = "Linear Algebra Operations" self.name_idx[i].shader_model = 6, 10 @@ -6384,6 +6384,19 @@ def UFI(name, **mappings): % next_op_idx ) + self.add_dxil_op( + "CreateMatrix", + next_op_idx, + "CreateMatrix", + "creates the handle to a matrix", + "v", + "", + [ + db_dxil_param(0, "matrixref", "", "the handle to the matrix"), + ], + ) + next_op_idx += 1 + # Set interesting properties. self.build_indices() for ( @@ -9293,6 +9306,7 @@ def __init__(self, intrinsic_defs, opcode_data): "GroupNodeOutputRecords": "LICOMPTYPE_GROUP_NODE_OUTPUT_RECORDS", "ThreadNodeOutputRecords": "LICOMPTYPE_THREAD_NODE_OUTPUT_RECORDS", "DxHitObject": "LICOMPTYPE_HIT_OBJECT", + "MatrixRef": "LICOMPTYPE_MATRIX_REF", "VkBufferPointer": "LICOMPTYPE_VK_BUFFER_POINTER", "RayQuery": "LICOMPTYPE_RAY_QUERY", "LinAlg": "LICOMPTYPE_LINALG", @@ -9355,7 +9369,7 @@ def load_intrinsics(self, intrinsic_defs): r"""( sampler\w* | string | (?:RW)?(?:Texture\w*|ByteAddressBuffer) | - acceleration_struct | ray_desc | RayQuery | DxHitObject | + acceleration_struct | ray_desc | RayQuery | DxHitObject | MatrixRef | Node\w* | RWNode\w* | EmptyNode\w* | AnyNodeOutput\w* | NodeOutputRecord\w* | GroupShared\w* | VkBufferPointer diff --git a/utils/hct/hctdb_instrhelp.py b/utils/hct/hctdb_instrhelp.py index 9debd6e07f..d7ba4d53c1 100644 --- a/utils/hct/hctdb_instrhelp.py +++ b/utils/hct/hctdb_instrhelp.py @@ -631,6 +631,7 @@ def print_opfunc_table(self): "nodeproperty": "A(nodeProperty);", "noderecordproperty": "A(nodeRecordProperty);", "hit_object": "A(pHit);", + "matrixref": "A(pMatrixRef);", # Extended overload slots, extend as needed: "$x0": "EXT(0);", "$x1": "EXT(1);", diff --git a/utils/hct/hlsl_intrinsic_opcodes.json b/utils/hct/hlsl_intrinsic_opcodes.json index eb22fd7464..a56e01d4be 100644 --- a/utils/hct/hlsl_intrinsic_opcodes.json +++ b/utils/hct/hlsl_intrinsic_opcodes.json @@ -1,6 +1,6 @@ { "IntrinsicOpCodes": { - "Num_Intrinsics": 395, + "Num_Intrinsics": 396, "IOP_AcceptHitAndEndSearch": 0, "IOP_AddUint64": 1, "IOP_AllMemoryBarrier": 2, @@ -395,6 +395,7 @@ "IOP___builtin_MatVecMulAdd": 391, "IOP___builtin_OuterProductAccumulate": 392, "IOP___builtin_VectorAccumulate": 393, - "IOP_isnormal": 394 + "IOP_isnormal": 394, + "IOP___builtin_la_CreateMatrix": 395 } }