Add Subobjects to compiler front end (#1645)

- Add HLSL subobject classes to clang and enable their initialization
  via initialization lists.
- Translate declared subobjects and add to DXIL module.
- Fix bugs in subobject metadata serialization and disasm.
- Preserve original input string in root signature subobject.
- Remove unused IsHlslObjectType method from CGHLSLRuntime.
- Remove unnecessary collection of global strings in CGHLSLRuntime
- Change type printer to report 'literal string' for constant char arrays.
This commit is contained in:
Helena Kotas 2018-11-01 11:43:57 -07:00 коммит произвёл GitHub
Родитель bc9ad948c8
Коммит 637e6d2d7b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
19 изменённых файлов: 540 добавлений и 126 удалений

Просмотреть файл

@ -42,16 +42,17 @@ public:
bool GetStateObjectConfig(uint32_t &Flags) const;
bool GetRootSignature(bool local, const void * &Data, uint32_t &Size) const;
bool GetRootSignature(bool local, const void * &Data, uint32_t &Size,
const char **pText = nullptr) const;
bool GetSubobjectToExportsAssociation(llvm::StringRef &Subobject,
const char * const * &Exports,
uint32_t &NumExports) const;
bool GetRaytracingShaderConfig(uint32_t &MaxPayloadSizeInBytes,
uint32_t &MaxAttributeSizeInBytes) const;
bool GetRaytracingPipelineConfig(uint32_t &MaxTraceRecursionDepth) const;
bool GetHitGroup(llvm::StringRef &Intersection,
llvm::StringRef &AnyHit,
llvm::StringRef &ClosestHit) const;
bool GetHitGroup(llvm::StringRef &AnyHit,
llvm::StringRef &ClosestHit,
llvm::StringRef &Intersection) const;
private:
DxilSubobject(DxilSubobjects &owner, Kind kind, llvm::StringRef name);
@ -71,6 +72,7 @@ private:
struct RootSignature_t {
uint32_t Size;
const void *Data;
const char *Text; // can be null
};
struct SubobjectToExportsAssociation_t {
const char *Subobject;
@ -84,9 +86,9 @@ private:
uint32_t MaxTraceRecursionDepth;
};
struct HitGroup_t {
const char *Intersection;
const char *AnyHit;
const char *ClosestHit;
const char *Intersection;
};
union {
@ -133,10 +135,11 @@ public:
DxilSubobject &CreateRootSignature(llvm::StringRef Name,
bool local,
const void *Data,
uint32_t Size);
uint32_t Size,
llvm::StringRef *pText = nullptr);
DxilSubobject &CreateSubobjectToExportsAssociation(
llvm::StringRef Name,
llvm::StringRef Subobject, const char * const *Exports, uint32_t NumExports);
llvm::StringRef Subobject, llvm::StringRef *Exports, uint32_t NumExports);
DxilSubobject &CreateRaytracingShaderConfig(
llvm::StringRef Name,
uint32_t MaxPayloadSizeInBytes,
@ -145,9 +148,9 @@ public:
llvm::StringRef Name,
uint32_t MaxTraceRecursionDepth);
DxilSubobject &CreateHitGroup(llvm::StringRef Name,
llvm::StringRef Intersection,
llvm::StringRef AnyHit,
llvm::StringRef ClosestHit);
llvm::StringRef ClosestHit,
llvm::StringRef Intersection);
private:
DxilSubobject &CreateSubobject(Kind kind, llvm::StringRef Name);

Просмотреть файл

@ -214,9 +214,9 @@ struct RuntimeDataSubobjectInfo {
struct HitGroup_t {
// each is a string table offset for the shader name
// 0 points to empty name, indicating no shader.
uint32_t Intersection;
uint32_t AnyHit;
uint32_t ClosestHit;
uint32_t Intersection;
};
union {
@ -643,9 +643,9 @@ struct DxilSubobjectDesc {
uint32_t MaxTraceRecursionDepth;
};
struct HitGroup_t {
LPCWSTR Intersection;
LPCWSTR AnyHit;
LPCWSTR ClosestHit;
LPCWSTR Intersection;
};
union {

Просмотреть файл

@ -1359,7 +1359,7 @@ Metadata *DxilMDHelper::EmitSubobject(const DxilSubobject &obj) {
switch (obj.GetKind()) {
case DXIL::SubobjectKind::StateObjectConfig: {
uint32_t Flags;
IFTBOOL(!obj.GetStateObjectConfig(Flags),
IFTBOOL(obj.GetStateObjectConfig(Flags),
DXC_E_INCORRECT_DXIL_METADATA);
Args.emplace_back(Uint32ToConstMD((unsigned)Flags));
break;
@ -1368,20 +1368,22 @@ Metadata *DxilMDHelper::EmitSubobject(const DxilSubobject &obj) {
bLocalRS = true;
__fallthrough;
case DXIL::SubobjectKind::GlobalRootSignature: {
const char * Text;
const void * Data;
uint32_t Size;
IFTBOOL(!obj.GetRootSignature(bLocalRS, Data, Size),
IFTBOOL(obj.GetRootSignature(bLocalRS, Data, Size, &Text),
DXC_E_INCORRECT_DXIL_METADATA);
Constant *V = ConstantDataArray::get(m_Ctx,
ArrayRef<uint8_t>((const uint8_t *)Data, Size));
Args.emplace_back(MDNode::get(m_Ctx, { ConstantAsMetadata::get(V) }));
Args.emplace_back(MDString::get(m_Ctx, Text));
break;
}
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
StringRef Subobj;
const char * const * Exports;
uint32_t NumExports;
IFTBOOL(!obj.GetSubobjectToExportsAssociation(Subobj, Exports, NumExports),
IFTBOOL(obj.GetSubobjectToExportsAssociation(Subobj, Exports, NumExports),
DXC_E_INCORRECT_DXIL_METADATA);
SmallVector<Metadata *, 4> strArgs;
for (unsigned i = 0; i < NumExports; ++i) {
@ -1394,8 +1396,8 @@ Metadata *DxilMDHelper::EmitSubobject(const DxilSubobject &obj) {
case DXIL::SubobjectKind::RaytracingShaderConfig: {
uint32_t MaxPayloadSizeInBytes;
uint32_t MaxAttributeSizeInBytes;
IFTBOOL(!obj.GetRaytracingShaderConfig(MaxPayloadSizeInBytes,
MaxAttributeSizeInBytes),
IFTBOOL(obj.GetRaytracingShaderConfig(MaxPayloadSizeInBytes,
MaxAttributeSizeInBytes),
DXC_E_INCORRECT_DXIL_METADATA);
Args.emplace_back(Uint32ToConstMD(MaxPayloadSizeInBytes));
Args.emplace_back(Uint32ToConstMD(MaxAttributeSizeInBytes));
@ -1403,14 +1405,14 @@ Metadata *DxilMDHelper::EmitSubobject(const DxilSubobject &obj) {
}
case DXIL::SubobjectKind::RaytracingPipelineConfig: {
uint32_t MaxTraceRecursionDepth;
IFTBOOL(!obj.GetRaytracingPipelineConfig(MaxTraceRecursionDepth),
IFTBOOL(obj.GetRaytracingPipelineConfig(MaxTraceRecursionDepth),
DXC_E_INCORRECT_DXIL_METADATA);
Args.emplace_back(Uint32ToConstMD(MaxTraceRecursionDepth));
break;
}
case DXIL::SubobjectKind::HitGroup: {
llvm::StringRef Intersection, AnyHit, ClosestHit;
IFTBOOL(!obj.GetHitGroup(Intersection, AnyHit, ClosestHit),
IFTBOOL(obj.GetHitGroup(Intersection, AnyHit, ClosestHit),
DXC_E_INCORRECT_DXIL_METADATA);
Args.emplace_back(MDString::get(m_Ctx, Intersection));
Args.emplace_back(MDString::get(m_Ctx, AnyHit));
@ -1442,24 +1444,27 @@ void DxilMDHelper::LoadSubobject(const llvm::MDNode &MD, DxilSubobjects &Subobje
bLocalRS = true;
__fallthrough;
case DXIL::SubobjectKind::GlobalRootSignature: {
const ConstantAsMetadata *pMetaData = dyn_cast<ConstantAsMetadata>(MD.getOperand(i++));
IFTBOOL(pMetaData != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
const ConstantDataArray *pData = dyn_cast<ConstantDataArray>(pMetaData->getValue());
const MDNode *pDataMDWrapper = dyn_cast<MDNode>(MD.getOperand(i++));
IFTBOOL(pDataMDWrapper != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL(pDataMDWrapper->getNumOperands() == 1, DXC_E_INCORRECT_DXIL_METADATA);
const ConstantAsMetadata *pDataMD = dyn_cast<ConstantAsMetadata>(pDataMDWrapper->getOperand(0));
const ConstantDataArray *pData = dyn_cast<ConstantDataArray>(pDataMD->getValue());
IFTBOOL(pData != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL(pData->getElementType() == Type::getInt8Ty(m_Ctx), DXC_E_INCORRECT_DXIL_METADATA);
IFTBOOL(pData->getRawDataValues().size() < UINT_MAX &&
(pData->getRawDataValues().size() & 3) == 0, DXC_E_INCORRECT_DXIL_METADATA);
const void *Data = pData->getRawDataValues().begin();
uint32_t Size = pData->getRawDataValues().size();
Subobjects.CreateRootSignature(name, bLocalRS, Data, Size);
StringRef Text(StringMDToStringRef(MD.getOperand(i++)));
Subobjects.CreateRootSignature(name, bLocalRS, Data, Size, Text.size() ? &Text : nullptr);
break;
}
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
StringRef Subobj(StringMDToStringRef(MD.getOperand(i++)));
const MDNode *exportMD = dyn_cast<MDNode>(MD.getOperand(i++));
SmallVector<const char *, 4> Exports;
SmallVector<StringRef, 4> Exports;
for (unsigned iExport = 0; iExport < exportMD->getNumOperands(); iExport++) {
Exports.push_back(StringMDToStringRef(exportMD->getOperand(iExport)).data());
Exports.push_back(StringMDToStringRef(exportMD->getOperand(iExport)));
}
Subobjects.CreateSubobjectToExportsAssociation(name, Subobj, Exports.data(), Exports.size());
break;
@ -1479,7 +1484,7 @@ void DxilMDHelper::LoadSubobject(const llvm::MDNode &MD, DxilSubobjects &Subobje
StringRef Intersection(StringMDToStringRef(MD.getOperand(i++)));
StringRef AnyHit(StringMDToStringRef(MD.getOperand(i++)));
StringRef ClosestHit(StringMDToStringRef(MD.getOperand(i++)));
Subobjects.CreateHitGroup(name, Intersection, AnyHit, ClosestHit);
Subobjects.CreateHitGroup(name, AnyHit, ClosestHit, Intersection);
break;
}
default:

Просмотреть файл

@ -71,9 +71,9 @@ void DxilSubobject::CopyUnionedContents(const DxilSubobject &other) {
RaytracingPipelineConfig.MaxTraceRecursionDepth = other.RaytracingPipelineConfig.MaxTraceRecursionDepth;
break;
case Kind::HitGroup:
HitGroup.Intersection = other.HitGroup.Intersection;
HitGroup.AnyHit = other.HitGroup.AnyHit;
HitGroup.ClosestHit = other.HitGroup.ClosestHit;
HitGroup.Intersection = other.HitGroup.Intersection;
break;
}
}
@ -88,9 +88,9 @@ void DxilSubobject::InternStrings() {
ptr = m_Owner.GetSubobjectString(ptr).data();
break;
case Kind::HitGroup:
HitGroup.Intersection = m_Owner.GetSubobjectString(HitGroup.Intersection).data();
HitGroup.AnyHit = m_Owner.GetSubobjectString(HitGroup.AnyHit).data();
HitGroup.ClosestHit = m_Owner.GetSubobjectString(HitGroup.ClosestHit).data();
HitGroup.Intersection = m_Owner.GetSubobjectString(HitGroup.Intersection).data();
break;
default:
break;
@ -112,11 +112,13 @@ bool DxilSubobject::GetStateObjectConfig(uint32_t &Flags) const {
// Local/Global RootSignature
bool DxilSubobject::GetRootSignature(
bool local, const void * &Data, uint32_t &Size) const {
bool local, const void * &Data, uint32_t &Size, const char **pText) const {
Kind expected = local ? Kind::LocalRootSignature : Kind::GlobalRootSignature;
if (m_Kind == expected) {
Data = RootSignature.Data;
Size = RootSignature.Size;
if (pText)
*pText = RootSignature.Text;
return true;
}
return false;
@ -158,13 +160,13 @@ bool DxilSubobject::GetRaytracingPipelineConfig(
}
// HitGroup
bool DxilSubobject::GetHitGroup(llvm::StringRef &Intersection,
llvm::StringRef &AnyHit,
llvm::StringRef &ClosestHit) const {
bool DxilSubobject::GetHitGroup(llvm::StringRef &AnyHit,
llvm::StringRef &ClosestHit,
llvm::StringRef &Intersection) const {
if (m_Kind == Kind::HitGroup) {
Intersection = HitGroup.Intersection;
AnyHit = HitGroup.AnyHit;
ClosestHit = HitGroup.ClosestHit;
Intersection = HitGroup.Intersection;
return true;
}
return false;
@ -248,22 +250,25 @@ DxilSubobject &DxilSubobjects::CreateStateObjectConfig(
}
DxilSubobject &DxilSubobjects::CreateRootSignature(
llvm::StringRef Name, bool local, const void *Data, uint32_t Size) {
llvm::StringRef Name, bool local, const void *Data, uint32_t Size, llvm::StringRef *pText /*= nullptr*/) {
auto &obj = CreateSubobject(local ? Kind::LocalRootSignature : Kind::GlobalRootSignature, Name);
obj.RootSignature.Data = Data;
obj.RootSignature.Size = Size;
obj.RootSignature.Text = (pText ? GetSubobjectString(*pText).data() : nullptr);
return obj;
}
DxilSubobject &DxilSubobjects::CreateSubobjectToExportsAssociation(
llvm::StringRef Name,
llvm::StringRef Subobject,
const char * const *Exports,
llvm::StringRef *Exports,
uint32_t NumExports) {
auto &obj = CreateSubobject(Kind::SubobjectToExportsAssociation, Name);
Subobject = GetSubobjectString(Subobject);
obj.SubobjectToExportsAssociation.Subobject = Subobject.data();
obj.m_Exports.assign(Exports, Exports + NumExports);
for (unsigned i = 0; i < NumExports; i++) {
obj.m_Exports.emplace_back(GetSubobjectString(Exports[i]).data());
}
return obj;
}
@ -286,16 +291,16 @@ DxilSubobject &DxilSubobjects::CreateRaytracingPipelineConfig(
}
DxilSubobject &DxilSubobjects::CreateHitGroup(llvm::StringRef Name,
llvm::StringRef Intersection,
llvm::StringRef AnyHit,
llvm::StringRef ClosestHit) {
llvm::StringRef ClosestHit,
llvm::StringRef Intersection) {
auto &obj = CreateSubobject(Kind::HitGroup, Name);
Intersection = GetSubobjectString(Intersection);
AnyHit = GetSubobjectString(AnyHit);
ClosestHit = GetSubobjectString(ClosestHit);
obj.HitGroup.Intersection = Intersection.data();
Intersection = GetSubobjectString(Intersection);
obj.HitGroup.AnyHit = AnyHit.data();
obj.HitGroup.ClosestHit = ClosestHit.data();
obj.HitGroup.Intersection = Intersection.data();
return obj;
}

Просмотреть файл

@ -1243,13 +1243,13 @@ private:
info.RaytracingPipelineConfig.MaxTraceRecursionDepth);
break;
case DXIL::SubobjectKind::HitGroup:
StringRef Intersection;
StringRef AnyHit;
StringRef ClosestHit;
obj.GetHitGroup(Intersection, AnyHit, ClosestHit);
info.HitGroup.Intersection = m_pStringBufferPart->Insert(Intersection);
StringRef Intersection;
obj.GetHitGroup(AnyHit, ClosestHit, Intersection);
info.HitGroup.AnyHit = m_pStringBufferPart->Insert(AnyHit);
info.HitGroup.ClosestHit = m_pStringBufferPart->Insert(ClosestHit);
info.HitGroup.Intersection = m_pStringBufferPart->Insert(Intersection);
break;
}
m_pSubobjectTable->Insert(info);

Просмотреть файл

@ -41,7 +41,7 @@ void LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, RDAT::SubobjectTableRead
}
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
uint32_t NumExports = reader.GetSubobjectToExportsAssociation_NumExports();
std::vector<const char*> Exports;
std::vector<llvm::StringRef> Exports;
Exports.resize(NumExports);
for (unsigned i = 0; i < NumExports; ++i) {
Exports[i] = reader.GetSubobjectToExportsAssociation_Export(i);
@ -62,10 +62,10 @@ void LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, RDAT::SubobjectTableRead
break;
case DXIL::SubobjectKind::HitGroup:
subobjects.CreateHitGroup(reader.GetName(),
reader.GetHitGroup_Intersection(),
reader.GetHitGroup_AnyHit(),
reader.GetHitGroup_ClosestHit());
break;
reader.GetHitGroup_ClosestHit(),
reader.GetHitGroup_Intersection());
break;
}
}
}

Просмотреть файл

@ -315,6 +315,7 @@ void AddRecordTypeWithHandle(
void AddRayFlags(clang::ASTContext& context);
void AddHitKinds(clang::ASTContext& context);
void AddStateObjectFlags(clang::ASTContext& context);
/// <summary>Adds the implementation for std::is_equal.</summary>
void AddStdIsEqualImplementation(clang::ASTContext& context, clang::Sema& sema);
@ -388,6 +389,9 @@ unsigned GetHLSLInputPatchCount(clang::QualType type);
clang::QualType GetHLSLOutputPatchElementType(clang::QualType type);
unsigned GetHLSLOutputPatchCount(clang::QualType type);
bool IsHLSLSubobjectType(clang::QualType type);
bool GetHLSLSubobjectKind(clang::QualType type, DXIL::SubobjectKind &subobjectKind);
bool IsArrayConstantStringType(const clang::QualType type);
bool IsPointerStringType(const clang::QualType type);
bool IsStringType(const clang::QualType type);

Просмотреть файл

@ -7161,8 +7161,8 @@ def err_first_argument_to_cwsc_pdtor_call : Error<
def err_second_argument_to_cwsc_not_pointer : Error<
"second argument to __builtin_call_with_static_chain must be of pointer type">;
def err_vector_incorrect_num_initializers : Error<
"%select{too many|too few}0 elements in vector initialization (expected %1 element%s1, have %2)">;
def err_incorrect_num_initializers : Error<
"%select{too many|too few}0 elements in %select{vector|subobject}1 initialization (expected %2 element%s2, have %3)">;
def err_altivec_empty_initializer : Error<"expected initializer">;
def err_invalid_neon_type_code : Error<
@ -7650,8 +7650,12 @@ def warn_hlsl_effect_object : Warning <
def warn_hlsl_unused_call : Warning<
"ignoring return value of function that only reads data">,
InGroup<UnusedValue>;
def err_hlsl_string_not_global : Error<
"string declaration may only appear in global scope">;
def err_hlsl_object_not_global : Error<
"%select{subobject|string}0 declaration may only appear in global scope">;
def err_hlsl_object_extern_not_supported : Error<
"%select{subobject|string}0 cannot be declared with 'extern' storage specifier">;
def err_hlsl_object_missing_initializer : Error<
"%select{subobject|string}0 declaration needs to be initialized">;
def err_hlsl_func_in_func_decl : Error<
"function declaration is not allowed in function parameters">;
def err_hlsl_unsupported_keyword_for_version : Error<

Просмотреть файл

@ -556,6 +556,14 @@ void hlsl::AddHitKinds(ASTContext& context) {
AddConstUInt(context, curDC, StringRef("HIT_KIND_TRIANGLE_BACK_FACE"), (unsigned)DXIL::HitKind::TriangleBackFace);
}
/// <summary> Adds a constant integers for state object flags </summary>
void hlsl::AddStateObjectFlags(ASTContext& context) {
DeclContext *curDC = context.getTranslationUnitDecl();
AddConstUInt(context, curDC, StringRef("STATE_OBJECT_FLAGS_ALLOW_LOCAL_DEPENDENCIES_ON_EXTERNAL_DEFINITONS"), (unsigned)DXIL::StateObjectFlags::AllowLocalDependenciesOnExternalDefinitions);
AddConstUInt(context, curDC, StringRef("STATE_OBJECT_FLAGS_ALLOW_EXTERNAL_DEPENDENCIES_ON_LOCAL_DEFINITIONS"), (unsigned)DXIL::StateObjectFlags::AllowExternalDependenciesOnLocalDefinitions);
}
static
Expr* IntConstantAsBoolExpr(clang::Sema& sema, uint64_t value)
{

Просмотреть файл

@ -501,6 +501,35 @@ bool IsHLSLResourceType(clang::QualType type) {
return false;
}
bool IsHLSLSubobjectType(clang::QualType type) {
DXIL::SubobjectKind kind;
return GetHLSLSubobjectKind(type, kind);
}
bool GetHLSLSubobjectKind(clang::QualType type, DXIL::SubobjectKind &subobjectKind) {
type = type.getCanonicalType();
if (const RecordType *RT = type->getAs<RecordType>()) {
StringRef name = RT->getDecl()->getName();
switch (name.size()) {
case 17:
return name == "StateObjectConfig" ? (subobjectKind = DXIL::SubobjectKind::StateObjectConfig, true) : false;
case 18:
return name == "LocalRootSignature" ? (subobjectKind = DXIL::SubobjectKind::LocalRootSignature, true) : false;
case 19:
return name == "GlobalRootSignature" ? (subobjectKind = DXIL::SubobjectKind::GlobalRootSignature, true) : false;
case 29:
return name == "SubobjectToExportsAssociation" ? (subobjectKind = DXIL::SubobjectKind::SubobjectToExportsAssociation, true) : false;
case 22:
return name == "RaytracingShaderConfig" ? (subobjectKind = DXIL::SubobjectKind::RaytracingShaderConfig, true) : false;
case 24:
return name == "RaytracingPipelineConfig" ? (subobjectKind = DXIL::SubobjectKind::RaytracingPipelineConfig, true) : false;
case 8:
return name == "HitGroup" ? (subobjectKind = DXIL::SubobjectKind::HitGroup, true) : false;
}
}
return false;
}
QualType GetHLSLResourceResultType(QualType type) {
type = type.getCanonicalType();
const RecordType *RT = cast<RecordType>(type);

Просмотреть файл

@ -152,16 +152,23 @@ void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,
// HLSL Change Starts
// Print 'char *' as 'string' and 'const char *' as 'const string'
if (Policy.LangOpts.HLSL && T->isPointerType()) {
QualType Pointee = T->getPointeeType();
if (const BuiltinType* BIT = Pointee->getAs<BuiltinType>()) {
if (BIT->getKind() == BuiltinType::Char_S) {
if (Policy.LangOpts.HLSL) {
if (T->isPointerType()) {
QualType Pointee = T->getPointeeType();
if (Pointee->isSpecificBuiltinType(BuiltinType::Char_S)) {
Quals = Pointee.getQualifiers();
Quals.print(OS, Policy, /*appendSpaceIfNonEmpty=*/true);
OS << "string";
return;
}
}
else if (T->isConstantArrayType()) {
const Type *pElemType = T->getArrayElementTypeNoTypeQual();
if (pElemType->isSpecificBuiltinType(BuiltinType::Char_S)) {
OS << "literal string";
return;
}
}
}
// HLSL Change Ends

Просмотреть файл

@ -120,6 +120,12 @@ private:
uint32_t AddCBuffer(HLSLBufferDecl *D);
hlsl::DxilResourceBase::Class TypeToClass(clang::QualType Ty);
void CreateSubobject(DXIL::SubobjectKind kind, const StringRef name,
clang::Expr **args, unsigned int argCount);
bool GetAsConstantString(clang::Expr *expr, StringRef *value);
bool GetAsConstantUInt32(clang::Expr *expr, uint32_t *value);
std::vector<StringRef> ParseSubobjectExportsAssociations(StringRef exports);
// Save the entryFunc so don't need to find it with original name.
struct EntryFunctionInfo {
clang::SourceLocation SL = clang::SourceLocation();
@ -157,10 +163,6 @@ private:
DxilRootSignatureVersion rootSigVer;
// Strings
std::vector<GlobalVariable *> globalStringsDecls;
std::vector<GlobalVariable *> globalStringsConstants;
Value *EmitHLSLMatrixLoad(CGBuilderTy &Builder, Value *Ptr, QualType Ty);
void EmitHLSLMatrixStore(CGBuilderTy &Builder, Value *Val, Value *DestPtr,
QualType Ty);
@ -240,8 +242,6 @@ private:
public:
CGMSHLSLRuntime(CodeGenModule &CGM);
bool IsHlslObjectType(llvm::Type * Ty) override;
/// Add resouce to the program
void addResource(Decl *D) override;
void SetPatchConstantFunction(const EntryFunctionInfo &EntryFunc);
@ -249,9 +249,8 @@ public:
const EntryFunctionInfo &EntryFunc,
const clang::HLSLPatchConstantFuncAttr *PatchConstantFuncAttr);
void AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) override;
void AddGlobalStringConstant(llvm::GlobalVariable *GV) override;
void addSubobject(Decl *D) override;
void FinishCodeGen() override;
bool IsTrivalInitListExpr(CodeGenFunction &CGF, InitListExpr *E) override;
Value *EmitHLSLInitListExpr(CodeGenFunction &CGF, InitListExpr *E, Value *DestPtr) override;
@ -453,9 +452,6 @@ CGMSHLSLRuntime::CGMSHLSLRuntime(CodeGenModule &CGM)
}
}
bool CGMSHLSLRuntime::IsHlslObjectType(llvm::Type *Ty) {
return dxilutil::IsHLSLObjectType(Ty);
}
void CGMSHLSLRuntime::AddHLSLIntrinsicOpcodeToFunction(Function *F,
unsigned opcode) {
@ -2166,7 +2162,7 @@ hlsl::CompType CGMSHLSLRuntime::GetCompType(const BuiltinType *BT) {
return ElementType;
}
/// Add resouce to the program
/// Add resource to the program
void CGMSHLSLRuntime::addResource(Decl *D) {
if (HLSLBufferDecl *BD = dyn_cast<HLSLBufferDecl>(D))
GetOrCreateCBuffer(BD);
@ -2215,6 +2211,36 @@ void CGMSHLSLRuntime::addResource(Decl *D) {
}
}
/// Add subobject to the module
void CGMSHLSLRuntime::addSubobject(Decl *D) {
VarDecl *VD = dyn_cast<VarDecl>(D);
DXASSERT(VD != nullptr, "must be a global variable");
DXIL::SubobjectKind subobjKind;
if (!hlsl::GetHLSLSubobjectKind(VD->getType(), subobjKind)) {
DXASSERT(false, "not a valid subobject declaration");
return;
}
Expr *initExpr = const_cast<Expr*>(VD->getAnyInitializer());
if (!initExpr) {
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "subobject needs to be initialized");
Diags.Report(D->getLocStart(), DiagID);
return;
}
if (InitListExpr *initListExpr = dyn_cast<InitListExpr>(initExpr)) {
CreateSubobject(subobjKind, VD->getName(), initListExpr->getInits(), initListExpr->getNumInits());
}
else {
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "expected initialization list");
Diags.Report(initExpr->getLocStart(), DiagID);
return;
}
}
// TODO: collect such helper utility functions in one place.
static DxilResourceBase::Class KeywordToClass(const std::string &keyword) {
// TODO: refactor for faster search (switch by 1/2/3 first letters, then
@ -2366,6 +2392,147 @@ uint32_t CGMSHLSLRuntime::AddSampler(VarDecl *samplerDecl) {
return m_pHLModule->AddSampler(std::move(hlslRes));
}
bool CGMSHLSLRuntime::GetAsConstantUInt32(clang::Expr *expr, uint32_t *value) {
APSInt result;
if (!expr->EvaluateAsInt(result, CGM.getContext())) {
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot convert to constant unsigned int");
Diags.Report(expr->getLocStart(), DiagID);
return false;
}
*value = result.getLimitedValue(UINT32_MAX);
return true;
}
bool CGMSHLSLRuntime::GetAsConstantString(clang::Expr *expr, StringRef *value) {
Expr::EvalResult result;
if (expr->EvaluateAsRValue(result, CGM.getContext())) {
if (result.Val.isLValue()) {
DXASSERT_NOMSG(result.Val.getLValueOffset().isZero());
DXASSERT_NOMSG(result.Val.getLValueCallIndex() == 0);
const Expr *evExpr = result.Val.getLValueBase().get<const Expr *>();
if (const StringLiteral *strLit = dyn_cast<const StringLiteral>(evExpr)) {
*value = strLit->getBytes();
return true;
}
}
}
DiagnosticsEngine &Diags = CGM.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"cannot convert to constant string");
Diags.Report(expr->getLocStart(), DiagID);
return false;
}
std::vector<StringRef> CGMSHLSLRuntime::ParseSubobjectExportsAssociations(StringRef exports) {
std::vector<StringRef> parsedExports;
const char *pData = exports.data();
const char *pEnd = pData + exports.size();
const char *pLast = pData;
while (pData < pEnd) {
if (*pData == ';') {
if (pLast < pData) {
parsedExports.emplace_back(StringRef(pLast, pData - pLast));
}
pLast = pData + 1;
}
pData++;
}
if (pLast < pData) {
parsedExports.emplace_back(StringRef(pLast, pData - pLast));
}
return std::move(parsedExports);
}
void CGMSHLSLRuntime::CreateSubobject(DXIL::SubobjectKind kind, const StringRef name,
clang::Expr **args, unsigned int argCount) {
DxilSubobjects *subobjects = m_pHLModule->GetSubobjects();
if (!subobjects) {
subobjects = new DxilSubobjects();
m_pHLModule->ResetSubobjects(subobjects);
}
switch (kind) {
case DXIL::SubobjectKind::StateObjectConfig: {
uint32_t flags;
DXASSERT_NOMSG(argCount == 1);
if (GetAsConstantUInt32(args[0], &flags)) {
subobjects->CreateStateObjectConfig(name, flags);
}
break;
}
case DXIL::SubobjectKind::GlobalRootSignature:
case DXIL::SubobjectKind::LocalRootSignature: {
DXASSERT_NOMSG(argCount == 1);
StringRef signature;
if (!GetAsConstantString(args[0], &signature))
return;
RootSignatureHandle RootSigHandle;
CompileRootSignature(signature, CGM.getDiags(), args[0]->getLocStart(), rootSigVer, &RootSigHandle);
if (!RootSigHandle.IsEmpty()) {
RootSigHandle.EnsureSerializedAvailable();
subobjects->CreateRootSignature(name, kind == DXIL::SubobjectKind::LocalRootSignature,
RootSigHandle.GetSerializedBytes(), RootSigHandle.GetSerializedSize(), &signature);
}
break;
}
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
DXASSERT_NOMSG(argCount == 2);
StringRef subObjName, exports;
if (!GetAsConstantString(args[0], &subObjName) ||
!GetAsConstantString(args[1], &exports))
return;
std::vector<StringRef> exportList = ParseSubobjectExportsAssociations(exports);
subobjects->CreateSubobjectToExportsAssociation(name, subObjName, exportList.data(), exportList.size());
break;
}
case DXIL::SubobjectKind::RaytracingShaderConfig: {
DXASSERT_NOMSG(argCount == 2);
uint32_t maxPayloadSize;
uint32_t MaxAttributeSize;
if (!GetAsConstantUInt32(args[0], &maxPayloadSize) ||
!GetAsConstantUInt32(args[1], &MaxAttributeSize))
return;
subobjects->CreateRaytracingShaderConfig(name, maxPayloadSize, MaxAttributeSize);
break;
}
case DXIL::SubobjectKind::RaytracingPipelineConfig: {
DXASSERT_NOMSG(argCount == 1);
uint32_t maxTraceRecursionDepth;
if (!GetAsConstantUInt32(args[0], &maxTraceRecursionDepth))
return;
subobjects->CreateRaytracingPipelineConfig(name, maxTraceRecursionDepth);
break;
}
case DXIL::SubobjectKind::HitGroup: {
DXASSERT_NOMSG(argCount == 3);
StringRef anyhit, closesthit, intersection;
if (!GetAsConstantString(args[0], &anyhit) ||
!GetAsConstantString(args[1], &closesthit) ||
!GetAsConstantString(args[2], &intersection))
return;
subobjects->CreateHitGroup(name, anyhit, closesthit, intersection);
break;
}
default:
llvm_unreachable("unknown SubobjectKind");
break;
}
}
static void CollectScalarTypes(std::vector<QualType> &ScalarTys, QualType Ty) {
if (Ty->isRecordType()) {
if (hlsl::IsHLSLMatType(Ty)) {
@ -4581,19 +4748,7 @@ static void CreateWriteEnabledStaticGlobals(llvm::Module *M,
}
}
void CGMSHLSLRuntime::AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) {
DXASSERT_NOMSG(hlsl::IsStringType(D->getType()));
DXASSERT(D->getDeclContext()->isTranslationUnit(), "must be a global");
globalStringsDecls.emplace_back(GV);
}
void CGMSHLSLRuntime::AddGlobalStringConstant(llvm::GlobalVariable *GV) {
DXASSERT(GV->getType()->isPointerTy() &&
GV->getType()->getPointerElementType()->isArrayTy() &&
GV->getType()->getPointerElementType()->getArrayElementType() == llvm::Type::getInt8Ty(Context), "must be i8[]");
globalStringsConstants.emplace_back(GV);
}
void CGMSHLSLRuntime::FinishCodeGen() {
// Library don't have entry.

Просмотреть файл

@ -55,6 +55,7 @@ public:
virtual ~CGHLSLRuntime();
virtual void addResource(Decl *D) = 0;
virtual void addSubobject(Decl *D) = 0;
virtual void FinishCodeGen() = 0;
virtual RValue EmitHLSLBuiltinCallExpr(CodeGenFunction &CGF,
const FunctionDecl *FD,
@ -117,11 +118,7 @@ public:
virtual void AddHLSLFunctionInfo(llvm::Function *, const FunctionDecl *FD) = 0;
virtual void EmitHLSLFunctionProlog(llvm::Function *, const FunctionDecl *FD) = 0;
virtual void AddGlobalStringDecl(const clang::VarDecl *D, llvm::GlobalVariable *GV) = 0;
virtual void AddGlobalStringConstant(llvm::GlobalVariable *GV) = 0;
virtual bool IsHlslObjectType(llvm::Type *Ty) = 0;
virtual void AddControlFlowHint(CodeGenFunction &CGF, const Stmt &S, llvm::TerminatorInst *TI, llvm::ArrayRef<const Attr *> Attrs) = 0;
virtual void FinishAutoVar(CodeGenFunction &CGF, const VarDecl &D, llvm::Value *V) = 0;

Просмотреть файл

@ -1869,11 +1869,6 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
if (AddrSpace != Ty->getAddressSpace() && !LangOpts.HLSL) // HLSL Change -TODO: do we put address space in type?
return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty);
// HLSL Change start
if (hlsl::IsStringType(D->getType())) {
getHLSLRuntime().AddGlobalStringDecl(D, GV);
}
// HLSL Change end
return GV;
}
@ -3049,10 +3044,6 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
GV->setComdat(M.getOrInsertComdat(GV->getName()));
}
// HLSL Change Start
CGM.getHLSLRuntime().AddGlobalStringConstant(GV);
// HLSL CHange End
return GV;
}
@ -3395,7 +3386,14 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
return;
case Decl::VarTemplateSpecialization:
EmitGlobal(cast<VarDecl>(D));
getHLSLRuntime().addResource(D); // HLSL Change - add resource for global variables
// HLSL Change Start - add resource or subobject for global variables
if (hlsl::IsHLSLSubobjectType(cast<VarDecl>(D)->getType())) {
getHLSLRuntime().addSubobject(D);
}
else {
getHLSLRuntime().addResource(D);
}
// HLSL Change End
break;
// Indirect fields from global anonymous structs and unions can be

Просмотреть файл

@ -30,6 +30,7 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/SemaHLSL.h"
#include "clang/Sema/SemaHLSL.h"
#include "dxc/Support/Global.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/Support/WinAdapter.h"
@ -188,6 +189,15 @@ enum ArBasicKind {
AR_OBJECT_USER_DEFINED_TYPE,
AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES,
// subobjects
AR_OBJECT_STATE_OBJECT_CONFIG,
AR_OBJECT_GLOBAL_ROOT_SIGNATURE,
AR_OBJECT_LOCAL_ROOT_SIGNATURE,
AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC,
AR_OBJECT_RAYTRACING_SHADER_CONFIG,
AR_OBJECT_RAYTRACING_PIPELINE_CONFIG,
AR_OBJECT_HIT_GROUP,
AR_BASIC_MAXIMUM_COUNT
};
@ -454,6 +464,16 @@ const UINT g_uBasicKindProps[] =
LICOMPTYPE_ACCELERATION_STRUCT, // AR_OBJECT_ACCELARATION_STRUCT
LICOMPTYPE_USER_DEFINED_TYPE, // AR_OBJECT_USER_DEFINED_TYPE
0, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
// subobjects
0, //AR_OBJECT_STATE_OBJECT_CONFIG,
0, //AR_OBJECT_GLOBAL_ROOT_SIGNATURE,
0, //AR_OBJECT_LOCAL_ROOT_SIGNATURE,
0, //AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC,
0, //AR_OBJECT_RAYTRACING_SHADER_CONFIG,
0, //AR_OBJECT_RAYTRACING_PIPELINE_CONFIG,
0, //AR_OBJECT_HIT_GROUP,
// AR_BASIC_MAXIMUM_COUNT
};
@ -1255,6 +1275,15 @@ const ArBasicKind g_ArBasicKindsAsTypes[] =
AR_OBJECT_RAY_DESC,
AR_OBJECT_ACCELARATION_STRUCT,
AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES,
// subobjects
AR_OBJECT_STATE_OBJECT_CONFIG,
AR_OBJECT_GLOBAL_ROOT_SIGNATURE,
AR_OBJECT_LOCAL_ROOT_SIGNATURE,
AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC,
AR_OBJECT_RAYTRACING_SHADER_CONFIG,
AR_OBJECT_RAYTRACING_PIPELINE_CONFIG,
AR_OBJECT_HIT_GROUP,
};
// Count of template arguments for basic kind of objects that look like templates (one or more type arguments).
@ -1325,6 +1354,14 @@ const uint8_t g_ArBasicKindsTemplateCount[] =
0, // AR_OBJECT_RAY_DESC
0, // AR_OBJECT_ACCELARATION_STRUCT
0, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
0, // AR_OBJECT_STATE_OBJECT_CONFIG,
0, // AR_OBJECT_GLOBAL_ROOT_SIGNATURE,
0, // AR_OBJECT_LOCAL_ROOT_SIGNATURE,
0, // AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC,
0, // AR_OBJECT_RAYTRACING_SHADER_CONFIG,
0, // AR_OBJECT_RAYTRACING_PIPELINE_CONFIG,
0, // AR_OBJECT_HIT_GROUP,
};
C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsTemplateCount));
@ -1405,6 +1442,14 @@ const SubscriptOperatorRecord g_ArBasicKindsSubscripts[] =
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_RAY_DESC
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_ACCELARATION_STRUCT
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_STATE_OBJECT_CONFIG,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_GLOBAL_ROOT_SIGNATURE,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_LOCAL_ROOT_SIGNATURE,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_RAYTRACING_SHADER_CONFIG,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_RAYTRACING_PIPELINE_CONFIG,
{ 0, MipsFalse, SampleFalse }, // AR_OBJECT_HIT_GROUP,
};
C_ASSERT(_countof(g_ArBasicKindsAsTypes) == _countof(g_ArBasicKindsSubscripts));
@ -1507,7 +1552,16 @@ const char* g_ArBasicTypeNames[] =
"RayDesc",
"RaytracingAccelerationStructure",
"user defined type",
"BuiltInTriangleIntersectionAttributes"
"BuiltInTriangleIntersectionAttributes",
// subobjects
"StateObjectConfig",
"GlobalRootSignature",
"LocalRootSignature",
"SubobjectToExportsAssociation",
"RaytracingShaderConfig",
"RaytracingPipelineConfig",
"HitGroup",
};
C_ASSERT(_countof(g_ArBasicTypeNames) == AR_BASIC_MAXIMUM_COUNT);
@ -2327,9 +2381,8 @@ static void AddHLSLSubscriptAttr(Decl *D, ASTContext &context, HLSubscriptOpcode
D->addAttr(HLSLIntrinsicAttr::CreateImplicit(context, group, "", static_cast<unsigned>(opcode)));
}
static void CreateSimpleField(clang::ASTContext &context,
CXXRecordDecl *recordDecl, StringRef Name,
QualType Ty) {
static void CreateSimpleField(clang::ASTContext &context, CXXRecordDecl *recordDecl, StringRef Name,
QualType Ty, AccessSpecifier access = AccessSpecifier::AS_public) {
IdentifierInfo &fieldId =
context.Idents.get(Name, tok::TokenKind::identifier);
TypeSourceInfo *filedTypeSource = context.getTrivialTypeSourceInfo(Ty, NoLoc);
@ -2339,7 +2392,7 @@ static void CreateSimpleField(clang::ASTContext &context,
FieldDecl *fieldDecl =
FieldDecl::Create(context, recordDecl, NoLoc, NoLoc, &fieldId, Ty,
filedTypeSource, nullptr, MutableFalse, initStyle);
fieldDecl->setAccess(AccessSpecifier::AS_public);
fieldDecl->setAccess(access);
fieldDecl->setImplicit(true);
recordDecl->addDecl(fieldDecl);
@ -2400,6 +2453,97 @@ static CXXRecordDecl *AddBuiltInTriangleIntersectionAttributes(ASTContext& conte
return attributesDecl;
}
//
// Subobjects
static CXXRecordDecl *StartSubobjectDecl(ASTContext& context, const char *name) {
IdentifierInfo &id = context.Idents.get(StringRef(name), tok::TokenKind::identifier);
CXXRecordDecl *decl = CXXRecordDecl::Create( context, TagTypeKind::TTK_Struct,
context.getTranslationUnitDecl(), NoLoc, NoLoc, &id, nullptr, DelayTypeCreationTrue);
decl->startDefinition();
return decl;
}
void FinishSubobjectDecl(ASTContext& context, CXXRecordDecl *decl) {
decl->completeDefinition();
context.getTranslationUnitDecl()->addDecl(decl);
decl->setImplicit(true);
}
// struct StateObjectConfig
// {
// uint32_t Flags;
// };
static CXXRecordDecl *CreateSubobjectStateObjectConfig(ASTContext& context) {
CXXRecordDecl *decl = StartSubobjectDecl(context, "StateObjectConfig");
CreateSimpleField(context, decl, "Flags", context.UnsignedIntTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
// struct GlobalRootSignature
// {
// string signature;
// };
static CXXRecordDecl *CreateSubobjectRootSignature(ASTContext& context, bool global) {
CXXRecordDecl *decl = StartSubobjectDecl(context, global ? "GlobalRootSignature" : "LocalRootSignature");
CreateSimpleField(context, decl, "Data", context.HLSLStringTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
// struct SubobjectToExportsAssociation
// {
// string Subobject;
// string Exports;
// };
static CXXRecordDecl *CreateSubobjectSubobjectToExportsAssoc(ASTContext& context) {
CXXRecordDecl *decl = StartSubobjectDecl(context, "SubobjectToExportsAssociation");
CreateSimpleField(context, decl, "Subobject", context.HLSLStringTy, AccessSpecifier::AS_private);
CreateSimpleField(context, decl, "Exports", context.HLSLStringTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
// struct RaytracingShaderConfig
// {
// uint32_t MaxPayloadSizeInBytes;
// uint32_t MaxAttributeSizeInBytes;
// };
static CXXRecordDecl *CreateSubobjectRaytracingShaderConfig(ASTContext& context) {
CXXRecordDecl *decl = StartSubobjectDecl(context, "RaytracingShaderConfig");
CreateSimpleField(context, decl, "MaxPayloadSizeInBytes", context.UnsignedIntTy, AccessSpecifier::AS_private);
CreateSimpleField(context, decl, "MaxAttributeSizeInBytes", context.UnsignedIntTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
// struct RaytracingPipelineConfig
// {
// uint32_t MaxTraceRecursionDepth;
// };
static CXXRecordDecl *CreateSubobjectRaytracingPipelineConfig(ASTContext& context) {
CXXRecordDecl *decl = StartSubobjectDecl(context, "RaytracingPipelineConfig");
CreateSimpleField(context, decl, "MaxTraceRecursionDepth", context.UnsignedIntTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
// struct HitGroup
// {
// string anyhit;
// string closesthit;
// string intersection;
// };
static CXXRecordDecl *CreateSubobjectHitGroup(ASTContext& context) {
CXXRecordDecl *decl = StartSubobjectDecl(context, "HitGroup");
CreateSimpleField(context, decl, "AnyHit", context.HLSLStringTy, AccessSpecifier::AS_private);
CreateSimpleField(context, decl, "ClosestHit", context.HLSLStringTy, AccessSpecifier::AS_private);
CreateSimpleField(context, decl, "Intersection", context.HLSLStringTy, AccessSpecifier::AS_private);
FinishSubobjectDecl(context, decl);
return decl;
}
//
// This is similar to clang/Analysis/CallGraph, but the following differences
// motivate this:
@ -3024,8 +3168,33 @@ private:
} else if (kind == AR_OBJECT_TRIANGLE_INTERSECTION_ATTRIBUTES) {
QualType float2Type = LookupVectorType(HLSLScalarType::HLSLScalarType_float, 2);
recordDecl = AddBuiltInTriangleIntersectionAttributes(*m_context, float2Type);
} else
if (templateArgCount == 0)
} else if (IsSubobjectBasicKind(kind)) {
switch (kind) {
case AR_OBJECT_STATE_OBJECT_CONFIG:
recordDecl = CreateSubobjectStateObjectConfig(*m_context);
break;
case AR_OBJECT_GLOBAL_ROOT_SIGNATURE:
recordDecl = CreateSubobjectRootSignature(*m_context, true);
break;
case AR_OBJECT_LOCAL_ROOT_SIGNATURE:
recordDecl = CreateSubobjectRootSignature(*m_context, false);
break;
case AR_OBJECT_SUBOBJECT_TO_EXPORTS_ASSOC:
recordDecl = CreateSubobjectSubobjectToExportsAssoc(*m_context);
break;
break;
case AR_OBJECT_RAYTRACING_SHADER_CONFIG:
recordDecl = CreateSubobjectRaytracingShaderConfig(*m_context);
break;
case AR_OBJECT_RAYTRACING_PIPELINE_CONFIG:
recordDecl = CreateSubobjectRaytracingPipelineConfig(*m_context);
break;
case AR_OBJECT_HIT_GROUP:
recordDecl = CreateSubobjectHitGroup(*m_context);
break;
}
}
else if (templateArgCount == 0)
{
AddRecordTypeWithHandle(*m_context, &recordDecl, typeName);
DXASSERT(recordDecl != nullptr, "AddRecordTypeWithHandle failed to return the object declaration");
@ -3216,6 +3385,14 @@ public:
return m_hlslStringTypedef;
}
static bool IsSubobjectBasicKind(ArBasicKind kind) {
return kind >= AR_OBJECT_STATE_OBJECT_CONFIG && kind <= AR_OBJECT_HIT_GROUP;
}
bool IsSubobjectType(QualType type) {
return IsSubobjectBasicKind(GetTypeElementKind(type));
}
void WarnMinPrecision(HLSLScalarType type, SourceLocation loc) {
// TODO: enalbe this once we introduce precise master option
bool UseMinPrecision = m_context->getLangOpts().UseMinPrecision;
@ -3943,6 +4120,7 @@ public:
// Initializing built in integers for ray tracing
AddRayFlags(*m_context);
AddHitKinds(*m_context);
AddStateObjectFlags(*m_context);
return true;
}
@ -6568,8 +6746,9 @@ void HLSLExternalSource::InitializeInitSequenceForHLSL(
}
else {
m_sema->Diag(diagLocation,
diag::err_vector_incorrect_num_initializers)
diag::err_incorrect_num_initializers)
<< (comparisonResult.RightCount < comparisonResult.LeftCount)
<< IsSubobjectType(destType)
<< comparisonResult.LeftCount << comparisonResult.RightCount;
}
SilenceSequenceDiagnostics(initSequence);
@ -10066,10 +10245,22 @@ bool FlattenedTypeIterator::pushTrackerForType(QualType type, MultiExprArg::iter
GetHLSLVecSize(type), nullptr));
return true;
case ArTypeObjectKind::AR_TOBJ_OBJECT: {
// Object have no sub-types.
m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
if (m_source.IsSubobjectType(type)) {
// subobjects are initialized with initialization lists
recordType = type->getAsStructureType();
fi = recordType->getDecl()->field_begin();
fe = recordType->getDecl()->field_end();
m_typeTrackers.push_back(
FlattenedTypeIterator::FlattenedTypeTracker(type, fi, fe));
return true;
}
else {
// Object have no sub-types.
m_typeTrackers.push_back(FlattenedTypeIterator::FlattenedTypeTracker(
type.getCanonicalType(), 1, expression));
return true;
return true;
}
}
case ArTypeObjectKind::AR_TOBJ_STRING: {
// Strings have no sub-types.
@ -11193,6 +11384,7 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
// case of a function (or method).
QualType qt = TInfo->getType();
const Type* pType = qt.getTypePtrOrNull();
HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
// Early checks - these are not simple attribution errors, but constructs that
// are fundamentally unsupported,
@ -11214,14 +11406,18 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
}
}
// diagnose string declarations
if (hlsl::IsStringType(qt) && !D.isInvalidType()) {
// String and subobject declarations are supported only as top level global variables.
// Const and static modifiers are implied - add them if missing.
if ((hlsl::IsStringType(qt) || hlslSource->IsSubobjectType(qt)) && !D.isInvalidType()) {
// string are supported only as top level global variables
if (!DC->isTranslationUnit()) {
Diag(D.getLocStart(), diag::err_hlsl_string_not_global);
Diag(D.getLocStart(), diag::err_hlsl_object_not_global) << (int)hlsl::IsStringType(qt);
result = false;
}
if (isExtern) {
Diag(D.getLocStart(), diag::err_hlsl_object_extern_not_supported) << (int)hlsl::IsStringType(qt);
result = false;
}
// const and static modifiers are implied - add them if missing
const char *PrevSpec = nullptr;
unsigned DiagID = 0;
if (!isStatic) {
@ -11269,7 +11465,6 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
return false;
}
// Add methods if not ready.
HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
hlslSource->AddHLSLObjectMethodsIfNotReady(qt);
} else if (qt->isArrayType()) {
QualType eltQt(qt->getArrayElementTypeNoTypeQual(), 0);
@ -11278,7 +11473,6 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
if (hlsl::IsObjectType(this, eltQt, &bDeprecatedEffectObject)) {
// Add methods if not ready.
HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
hlslSource->AddHLSLObjectMethodsIfNotReady(eltQt);
}
}
@ -11315,7 +11509,6 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC,
}
}
HLSLExternalSource *hlslSource = HLSLExternalSource::FromSema(this);
ArBasicKind basicKind = hlslSource->GetTypeElementKind(qt);
if (hasSignSpec) {

Просмотреть файл

@ -1507,10 +1507,12 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity,
// OpenCL requires all elements to be initialized.
if (numEltsInit != maxElements && !extraElementsAllowed) { // HLSL Change
if (!VerifyOnly)
if (!VerifyOnly) {
static const unsigned selectVectorIdx = 0;
SemaRef.Diag(IList->getLocStart(),
diag::err_vector_incorrect_num_initializers)
<< (numEltsInit < maxElements) << maxElements << numEltsInit;
diag::err_incorrect_num_initializers)
<< (numEltsInit < maxElements) << selectVectorIdx << maxElements << numEltsInit;
}
hadError = true;
}
}

Просмотреть файл

@ -12,7 +12,7 @@ snorm bool sb; // expected-error {{snorm and unorm qualifier can only be
// Used to generate this undesirable error:
// cannot initialize a variable of type 'min16float' (aka 'half') with an lvalue of type 'const char [4]'
min16float foobar = "foo"; // expected-error {{cannot initialize a variable of type 'min16float' with an lvalue of type 'const char [4]'}} expected-warning {{min16float is promoted to float16_t}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'min16float'}}
min16float foobar = "foo"; // expected-error {{cannot initialize a variable of type 'min16float' with an lvalue of type 'literal string'}} expected-warning {{min16float is promoted to float16_t}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'min16float'}}
/*
(let (
@ -478,4 +478,4 @@ unorm min10float left1125; min10float right1125; left1125 = right1125; // expe
unorm min10float left1126; snorm min10float right1126; left1126 = right1126; // expected-warning {{min10float is promoted to float16_t}} expected-warning {{min10float is promoted to float16_t}} fxc-pass {{}} //
unorm min10float left1127; unorm min10float right1127; left1127 = right1127; // expected-warning {{min10float is promoted to float16_t}} expected-warning {{min10float is promoted to float16_t}} fxc-pass {{}} //
}
}

Просмотреть файл

@ -12,7 +12,7 @@ snorm bool sb; // expected-error {{snorm and unorm qualifier can only be
// Used to generate this undesirable error:
// cannot initialize a variable of type 'min16float' (aka 'half') with an lvalue of type 'const char [4]'
min16float foobar = "foo"; // expected-error {{cannot initialize a variable of type 'min16float' with an lvalue of type 'const char [4]'}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'min16float'}}
min16float foobar = "foo"; // expected-error {{cannot initialize a variable of type 'min16float' with an lvalue of type 'literal string'}} fxc-error {{X3017: cannot implicitly convert from 'const string' to 'min16float'}}
/*
(let (

Просмотреть файл

@ -650,14 +650,17 @@ void PrintSubobjects(const DxilSubobjects &subobjects,
bLocalRS = true;
__fallthrough;
case DXIL::SubobjectKind::GlobalRootSignature: {
const char *Text = nullptr;
const void *Data = nullptr;
uint32_t Size = 0;
if (!obj.GetRootSignature(bLocalRS, Data, Size)) {
if (!obj.GetRootSignature(bLocalRS, Data, Size, &Text)) {
OS << "<error getting subobject>";
break;
}
// TODO: Deserialize root signature?
OS << "<" << Size << " bytes>";
if (Text && Text[0]) {
OS << ", \"" << Text << "\"";
}
break;
}
case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
@ -671,7 +674,7 @@ void PrintSubobjects(const DxilSubobjects &subobjects,
OS << "\"" << Subobject << "\", { ";
if (Exports) {
for (unsigned i = 0; i < NumExports; ++i) {
OS << "\"" << Exports[i] << "\"" << (i ? ", " : "");
OS << (i ? ", " : "") << "\"" << Exports[i] << "\"";
}
}
OS << " } ";
@ -699,21 +702,22 @@ void PrintSubobjects(const DxilSubobjects &subobjects,
break;
}
case DXIL::SubobjectKind::HitGroup: {
StringRef Intersection;
StringRef AnyHit;
StringRef ClosestHit;
if (!obj.GetHitGroup(Intersection, AnyHit, ClosestHit)) {
StringRef Intersection;
if (!obj.GetHitGroup(AnyHit, ClosestHit, Intersection)) {
OS << "<error getting subobject>";
break;
}
OS << "intersection = \"" << Intersection
<< "\", anyhit = \"" << AnyHit
<< "\", closesthit = \"" << ClosestHit << "\"";
OS << "anyhit = \"" << AnyHit
<< "\", closesthit = \"" << ClosestHit
<< "\", intersection = \"" << Intersection << "\"";
break;
}
}
OS << " };\n";
}
OS << comment << "\n";
}
void PrintStructLayout(StructType *ST, DxilTypeSystem &typeSys,