Skip to content
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

[SER] Patch 1: HitObject type lowering and SM 6.9 enablement #7097

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions include/dxc/DXIL/DxilUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ GetHLSLResourceProperties(llvm::Type *Ty);
bool IsHLSLResourceType(llvm::Type *Ty);
bool IsHLSLObjectType(llvm::Type *Ty);
bool IsHLSLRayQueryType(llvm::Type *Ty);
llvm::Type *GetHLSLHitObjectType(llvm::Module *M);
bool IsHLSLHitObjectType(llvm::Type *Ty);
bool IsHLSLResourceDescType(llvm::Type *Ty);
bool IsResourceSingleComponent(llvm::Type *Ty);
uint8_t GetResourceComponentCount(llvm::Type *Ty);
Expand Down
1 change: 1 addition & 0 deletions include/dxc/HlslIntrinsicOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ enum class IntrinsicOp {
MOP_TraceRayInline,
MOP_WorldRayDirection,
MOP_WorldRayOrigin,
MOP_HitObject_MakeNop,
MOP_Count,
MOP_FinishedCrossGroupSharing,
MOP_GetGroupNodeOutputRecords,
Expand Down
1 change: 1 addition & 0 deletions include/dxc/Support/HLSLOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class DxcOpts {
bool PrintAfterAll; // OPT_print_after_all
std::set<std::string> PrintAfter; // OPT_print_after
bool EnablePayloadQualifiers = false; // OPT_enable_payload_qualifiers
bool EnableShaderExecutionReordering = false;
bool HandleExceptions = false; // OPT_disable_exception_handling

// Rewriter Options
Expand Down
6 changes: 5 additions & 1 deletion include/dxc/dxcapi.internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ enum LEGAL_INTRINSIC_COMPTYPES {
LICOMPTYPE_GROUP_NODE_OUTPUT_RECORDS = 49,
LICOMPTYPE_THREAD_NODE_OUTPUT_RECORDS = 50,

LICOMPTYPE_COUNT = 51
LICOMPTYPE_RAY_QUERY = 51,
LICOMPTYPE_HIT_OBJECT = 52,

LICOMPTYPE_COUNT = 53
};

static const BYTE IA_SPECIAL_BASE = 0xf0;
Expand Down Expand Up @@ -165,6 +168,7 @@ struct HLSL_INTRINSIC {
BOOL bReadOnly; // Only read memory
BOOL bReadNone; // Not read memory
BOOL bIsWave; // Is a wave-sensitive op
BOOL bStaticMember; // HLSL static member function
INT iOverloadParamIndex; // Parameter decide the overload type, -1 means ret
// type
UINT uNumArgs; // Count of arguments in pArgs.
Expand Down
21 changes: 21 additions & 0 deletions lib/DXIL/DxilUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,9 @@ bool IsHLSLObjectType(llvm::Type *Ty) {
if (name.startswith("dx.types.wave_t"))
return true;

if (name == "dx.types.HitObject")
return true;

if (name.compare("dx.types.Handle") == 0)
return true;

Expand Down Expand Up @@ -587,6 +590,24 @@ bool IsHLSLRayQueryType(llvm::Type *Ty) {
return false;
}

llvm::Type *GetHLSLHitObjectType(llvm::Module *M) {
using namespace llvm;
StructType *HitObjectTy = M->getTypeByName("dx.types.HitObject");
if (!HitObjectTy)
HitObjectTy = StructType::create({Type::getInt8PtrTy(M->getContext(), 0)},
"dx.types.HitObject", false);
return HitObjectTy;
}

bool IsHLSLHitObjectType(llvm::Type *Ty) {
llvm::StructType *ST = dyn_cast<llvm::StructType>(Ty);
if (!ST)
return false;
if (!ST->hasName())
return false;
return ST->getName() == "dx.types.HitObject";
}

bool IsHLSLResourceDescType(llvm::Type *Ty) {
if (llvm::StructType *ST = dyn_cast<llvm::StructType>(Ty)) {
if (!ST->hasName())
Expand Down
3 changes: 3 additions & 0 deletions lib/DxcSupport/HLSLOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,9 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
return 1;
}

opts.EnableShaderExecutionReordering =
DXIL::CompareVersions(Major, Minor, 6, 9) >= 0;

opts.HandleExceptions =
!Args.hasFlag(OPT_disable_exception_handling, OPT_INVALID, false);

Expand Down
6 changes: 4 additions & 2 deletions lib/HLSL/HLLowerUDT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ StructType *hlsl::GetLoweredUDT(StructType *structTy,
} else if (HLMatrixType Mat = HLMatrixType::dyn_cast(EltTy)) {
NewTy = ArrayType::get(Mat.getElementType(/*MemRepr*/ true),
Mat.getNumElements());
} else if (dxilutil::IsHLSLObjectType(EltTy) ||
} else if ((dxilutil::IsHLSLObjectType(EltTy) &&
!dxilutil::IsHLSLHitObjectType(EltTy)) ||
dxilutil::IsHLSLRayQueryType(EltTy)) {
// We cannot lower a structure with an embedded object type
// We cannot lower a structure with an embedded object type, except for
// HitObject.
return nullptr;
} else if (StructType *ST = dyn_cast<StructType>(EltTy)) {
NewTy = GetLoweredUDT(ST);
Expand Down
10 changes: 10 additions & 0 deletions lib/HLSL/HLOperationLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6062,6 +6062,13 @@ Value *TranslateUnpack(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
return ResVec;
}

Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
HLOperationLowerHelper &helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
}

} // namespace

// Resource Handle.
Expand Down Expand Up @@ -6738,6 +6745,9 @@ IntrinsicLower gLowerTable[] = {
DXIL::OpCode::RayQuery_WorldRayDirection},
{IntrinsicOp::MOP_WorldRayOrigin, TranslateRayQueryFloat3Getter,
DXIL::OpCode::RayQuery_WorldRayOrigin},
{IntrinsicOp::MOP_HitObject_MakeNop, TranslateHitObjectMake,
DXIL::OpCode::NumOpCodes_Dxil_1_8}, // FIXME: Just a placeholder Dxil
// opcode
{IntrinsicOp::MOP_Count, TranslateNodeGetInputRecordCount,
DXIL::OpCode::GetInputRecordCount},
{IntrinsicOp::MOP_FinishedCrossGroupSharing,
Expand Down
3 changes: 3 additions & 0 deletions tools/clang/include/clang/AST/HlslTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ clang::CXXRecordDecl *DeclareUIntTemplatedTypeWithHandleInDeclContext(
clang::CXXRecordDecl *DeclareConstantBufferViewType(clang::ASTContext &context,
bool bTBuf);
clang::CXXRecordDecl *DeclareRayQueryType(clang::ASTContext &context);
clang::CXXRecordDecl *DeclareHitObjectType(clang::ASTContext &context);
clang::CXXRecordDecl *DeclareResourceType(clang::ASTContext &context,
bool bSampler);

Expand Down Expand Up @@ -469,6 +470,7 @@ bool IsHLSLNodeInputType(clang::QualType type);
bool IsHLSLDynamicResourceType(clang::QualType type);
bool IsHLSLDynamicSamplerType(clang::QualType type);
bool IsHLSLNodeType(clang::QualType type);
bool IsHLSLHitObjectType(clang::QualType type);

bool IsHLSLObjectWithImplicitMemberAccess(clang::QualType type);
bool IsHLSLObjectWithImplicitROMemberAccess(clang::QualType type);
Expand Down Expand Up @@ -542,6 +544,7 @@ clang::CXXMethodDecl *CreateObjectFunctionDeclarationWithParams(
clang::QualType resultType, llvm::ArrayRef<clang::QualType> paramTypes,
llvm::ArrayRef<clang::StringRef> paramNames,
clang::DeclarationName declarationName, bool isConst,
clang::StorageClass SC = clang::StorageClass::SC_None,
bool isTemplateFunction = false);

DXIL::ResourceClass GetResourceClassForType(const clang::ASTContext &context,
Expand Down
4 changes: 4 additions & 0 deletions tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7929,6 +7929,10 @@ def err_hlsl_node_record_type : Error<
"%0 is not valid as a node record type - struct/class required">;
def err_hlsl_node_record_object : Error<
"object %0 may not appear in a node record">;
def err_hlsl_ser_invalid_shader_kind : Error<
"Shader kind '%0' incompatible with shader execution reordering (has to be raygeneration, closesthit or miss)">;
def err_hlsl_ser_invalid_version : Error<
"Shader execution reordering requires target profile lib_6_9+ (was %0)">;
def err_hlsl_array_disallowed : Error<
"%select{entry parameter|declaration}1 of type %0 may not be an array">;
def err_hlsl_inputpatch_size: Error<
Expand Down
1 change: 1 addition & 0 deletions tools/clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ class LangOptions : public LangOptionsBase {
bool EnableDX9CompatMode = false;
bool EnableFXCCompatMode = false;
bool EnablePayloadAccessQualifiers = false;
bool EnableShaderExecutionReordering = false;
bool DumpImplicitTopLevelDecls = true;
bool ExportShadersOnly = false;
hlsl::DXIL::DefaultLinkage DefaultLinkage =
Expand Down
2 changes: 2 additions & 0 deletions tools/clang/include/clang/Frontend/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
bool HLSLEnableLifetimeMarkers = false;
/// Put shader sources and options in the module
bool HLSLEmbedSourcesInModule = false;
/// Enable Shader Execution Reordering.
bool HLSLEnableShaderExecutionReordering = false;
/// Enable generation of payload access qualifier metadata.
bool HLSLEnablePayloadAccessQualifiers = false;
/// Binding table for HLSL resources
Expand Down
4 changes: 4 additions & 0 deletions tools/clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3809,6 +3809,10 @@ class Sema {
SourceLocation Loc);
void CheckHLSLFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
const FunctionProtoType *Proto);
void DiagnoseShaderExecutionReordering(CallExpr *CE,
hlsl::DXIL::ShaderKind EntrySK,
const FunctionDecl *EntryDecl,
const hlsl::ShaderModel *SM);
void DiagnoseReachableHLSLCall(CallExpr *CE, const hlsl::ShaderModel *SM,
hlsl::DXIL::ShaderKind EntrySK,
hlsl::DXIL::NodeLaunchType NodeLaunchTy,
Expand Down
37 changes: 32 additions & 5 deletions tools/clang/lib/AST/ASTContextHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/HlslBuiltinTypeDeclBuilder.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Overload.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
Expand Down Expand Up @@ -1033,7 +1034,7 @@ static void CreateConstructorDeclaration(
static void CreateObjectFunctionDeclaration(
ASTContext &context, CXXRecordDecl *recordDecl, QualType resultType,
ArrayRef<QualType> args, DeclarationName declarationName, bool isConst,
CXXMethodDecl **functionDecl, TypeSourceInfo **tinfo) {
StorageClass SC, CXXMethodDecl **functionDecl, TypeSourceInfo **tinfo) {
DXASSERT_NOMSG(recordDecl != nullptr);
DXASSERT_NOMSG(functionDecl != nullptr);

Expand All @@ -1045,8 +1046,8 @@ static void CreateObjectFunctionDeclaration(
*tinfo = context.getTrivialTypeSourceInfo(functionQT, NoLoc);
DXASSERT_NOMSG(*tinfo != nullptr);
*functionDecl = CXXMethodDecl::Create(
context, recordDecl, NoLoc, declNameInfo, functionQT, *tinfo,
StorageClass::SC_None, InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
context, recordDecl, NoLoc, declNameInfo, functionQT, *tinfo, SC,
InlineSpecifiedFalse, IsConstexprFalse, NoLoc);
DXASSERT_NOMSG(*functionDecl != nullptr);
(*functionDecl)->setLexicalDeclContext(recordDecl);
(*functionDecl)->setAccess(AccessSpecifier::AS_public);
Expand All @@ -1055,15 +1056,16 @@ static void CreateObjectFunctionDeclaration(
CXXMethodDecl *hlsl::CreateObjectFunctionDeclarationWithParams(
ASTContext &context, CXXRecordDecl *recordDecl, QualType resultType,
ArrayRef<QualType> paramTypes, ArrayRef<StringRef> paramNames,
DeclarationName declarationName, bool isConst, bool isTemplateFunction) {
DeclarationName declarationName, bool isConst, StorageClass SC,
bool isTemplateFunction) {
DXASSERT_NOMSG(recordDecl != nullptr);
DXASSERT_NOMSG(!resultType.isNull());
DXASSERT_NOMSG(paramTypes.size() == paramNames.size());

TypeSourceInfo *tinfo;
CXXMethodDecl *functionDecl;
CreateObjectFunctionDeclaration(context, recordDecl, resultType, paramTypes,
declarationName, isConst, &functionDecl,
declarationName, isConst, SC, &functionDecl,
&tinfo);

// Create and associate parameters to method.
Expand Down Expand Up @@ -1161,6 +1163,31 @@ CXXRecordDecl *hlsl::DeclareRayQueryType(ASTContext &context) {
return typeDeclBuilder.getRecordDecl();
}

CXXRecordDecl *hlsl::DeclareHitObjectType(ASTContext &Context) {
// HitObject { ... }
BuiltinTypeDeclBuilder TypeDeclBuilder(Context.getTranslationUnitDecl(),
"HitObject");
TypeDeclBuilder.startDefinition();
CXXRecordDecl *RecordDecl = TypeDeclBuilder.getRecordDecl();

// Add constructor that will be lowered to the intrinsic that produces
// the HitObject handle for this object.
CanQualType canQualType = Context.getCanonicalType(
Context.getRecordType(TypeDeclBuilder.getRecordDecl()));

CXXConstructorDecl *pConstructorDecl = nullptr;
TypeSourceInfo *pTypeSourceInfo = nullptr;
CreateConstructorDeclaration(
Context, RecordDecl, Context.VoidTy, {},
Context.DeclarationNames.getCXXConstructorName(canQualType), false,
&pConstructorDecl, &pTypeSourceInfo);
RecordDecl->addDecl(pConstructorDecl);
// The 'implicit' lets us distinguish SER HitObject (SM6.9+) from a
// user-defined type named 'HitObject' (pre-SM6.9).
RecordDecl->setImplicit(true);
return RecordDecl;
}

CXXRecordDecl *hlsl::DeclareResourceType(ASTContext &context, bool bSampler) {
// struct ResourceDescriptor { uint8 desc; }
StringRef Name = bSampler ? ".Sampler" : ".Resource";
Expand Down
16 changes: 16 additions & 0 deletions tools/clang/lib/AST/HlslTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,22 @@ bool IsHLSLResourceType(clang::QualType type) {
return false;
}

bool IsHLSLHitObjectType(QualType type) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's already a IsHLSLHitObjectTy in DxilUtil.cpp. Though I know this functions differently, I would think getting the underlying Type object within QualType, and then calling IsHLSLHitObjectTy on that, would return a sensible result. Because that isn't the implementation, would you be able to update the function names so that they're different?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch uses the same naming and implementation approach for HitObject as was done for NodeOutput and RayQuery. The name IsHLSLHitObjectType says what the function does not how it is implemented, so i don't find that argument very convincing.
Do we really want to change this?

type = type.getCanonicalType();
const RecordType *RT = dyn_cast<RecordType>(type);
if (!RT)
return false;

const CXXRecordDecl *cxxRecordDecl = dyn_cast<CXXRecordDecl>(RT->getDecl());
// Only match the 'implicit' type generated by hlsl::DeclareHitObjectType(..).
// User-defined types named 'HitObject' pre-SM6.9 are never 'implicit' and
// will not be mistaken for the SER HitObject type.
if (!cxxRecordDecl || !cxxRecordDecl->isImplicit())
return false;

return RT->getDecl()->getName() == "HitObject";
}

static HLSLNodeObjectAttr *getNodeAttr(clang::QualType type) {
if (const RecordType *RT = type->getAs<RecordType>()) {
if (const auto *Spec =
Expand Down
8 changes: 5 additions & 3 deletions tools/clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
#include "CGCall.h"
#include "ABIInfo.h"
#include "CGCXXABI.h"
#include "CGHLSLRuntime.h" // HLSL Change
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "CGHLSLRuntime.h" // HLSL Change
#include "TargetInfo.h"
#include "dxc/DXIL/DxilUtil.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/HlslTypes.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/CodeGenOptions.h"
Expand All @@ -30,8 +32,8 @@
#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Transforms/Utils/Local.h"
using namespace clang;
using namespace CodeGen;
Expand Down Expand Up @@ -1902,7 +1904,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
case ABIArgInfo::Extend:
case ABIArgInfo::Direct: {
// HLSL Change Begins
if (hlsl::IsHLSLMatType(Ty)) {
if (hlsl::IsHLSLMatType(Ty) || hlsl::IsHLSLHitObjectType(Ty)) {
assert(NumIRArgs == 1);
auto AI = FnArgs[FirstIRArg];
llvm::Value *V = AI;
Expand Down
13 changes: 13 additions & 0 deletions tools/clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ class ScalarExprEmitter
Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
return EmitLoadOfLValue(E);
}
Value *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
Value *VisitCXXConstructExpr(CXXConstructExpr *E);

Value *VisitInitListExpr(InitListExpr *E);

Expand Down Expand Up @@ -1101,6 +1103,17 @@ void ScalarExprEmitter::EmitBinOpCheck(
// Visitor Methods
//===----------------------------------------------------------------------===//

Value *ScalarExprEmitter::VisitCXXConstructExpr(CXXConstructExpr *E) {
return CGF.CGM.getHLSLRuntime().EmitHLSLScalarObjectDefaultConstructor(CGF,
E);
}

Value *
ScalarExprEmitter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
return CGF.CGM.getHLSLRuntime().EmitHLSLScalarObjectDefaultConstructor(CGF,
E);
}

Value *ScalarExprEmitter::VisitExpr(Expr *E) {
CGF.ErrorUnsupported(E, "scalar expression");
if (E->getType()->isVoidType())
Expand Down
Loading