Skip to content
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
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -5172,6 +5172,14 @@ def HLSLVkConstantId : InheritableAttr {
let Documentation = [VkConstantIdDocs];
}

def HLSLVkLocation : HLSLAnnotationAttr {
let Spellings = [CXX11<"vk", "location">];
let Args = [IntArgument<"Location">];
let Subjects = SubjectList<[ParmVar, Field, Function], ErrorDiag>;
let LangOpts = [HLSL];
let Documentation = [HLSLVkLocationDocs];
}

def RandomizeLayout : InheritableAttr {
let Spellings = [GCC<"randomize_layout">];
let Subjects = SubjectList<[Record]>;
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -8981,6 +8981,18 @@ The descriptor set is optional and defaults to 0 if not provided.
}];
}

def HLSLVkLocationDocs : Documentation {
let Category = DocCatVariable;
let Content = [{
Attribute used for specifying the location number for the stage input/output
variables. Allowed on function parameters, function returns, and struct
fields. This parameter has no effect when used outside of an entrypoint
parameter/parameter field/return value.

This attribute maps to the 'Location' SPIR-V decoration.
}];
}

def WebAssemblyFuncrefDocs : Documentation {
let Category = DocCatType;
let Content = [{
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -13231,6 +13231,12 @@ def err_hlsl_semantic_indexing_not_supported
def err_hlsl_init_priority_unsupported : Error<
"initializer priorities are not supported in HLSL">;
def err_hlsl_semantic_index_overlap : Error<"semantic index overlap %0">;
def err_hlsl_semantic_unsupported_iotype_for_stage
: Error<"semantic %0 is unsupported in %2 shaders as %1, requires one of "
"the following: %3">;
def err_hlsl_semantic_partial_explicit_indexing
: Error<"partial explicit stage input location assignment via "
"vk::location(X) unsupported">;

def warn_hlsl_user_defined_type_missing_member: Warning<"binding type '%select{t|u|b|s|c}0' only applies to types containing %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric types}0">, InGroup<LegacyConstantRegisterBinding>;
def err_hlsl_binding_type_mismatch: Error<"binding type '%select{t|u|b|s|c}0' only applies to %select{SRV resources|UAV resources|constant buffer resources|sampler state|numeric variables in the global scope}0">;
Expand Down
49 changes: 40 additions & 9 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ class SemaHLSL : public SemaBase {
void CheckEntryPoint(FunctionDecl *FD);
bool CheckResourceBinOp(BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr,
SourceLocation Loc);
void DiagnoseAttrStageMismatch(
const Attr *A, llvm::Triple::EnvironmentType Stage,
std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages);

QualType handleVectorBinOpConversion(ExprResult &LHS, ExprResult &RHS,
QualType LHSType, QualType RHSType,
Expand Down Expand Up @@ -171,6 +168,7 @@ class SemaHLSL : public SemaBase {
void handleWaveSizeAttr(Decl *D, const ParsedAttr &AL);
void handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL);
void handleVkBindingAttr(Decl *D, const ParsedAttr &AL);
void handleVkLocationAttr(Decl *D, const ParsedAttr &AL);
void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL);
void handleShaderAttr(Decl *D, const ParsedAttr &AL);
void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL);
Expand Down Expand Up @@ -239,9 +237,36 @@ class SemaHLSL : public SemaBase {

IdentifierInfo *RootSigOverrideIdent = nullptr;

// Information about the current subtree being flattened.
struct SemanticInfo {
HLSLParsedSemanticAttr *Semantic;
std::optional<uint32_t> Index;
std::optional<uint32_t> Index = std::nullopt;
};

// Bitmask used to recall if the current semantic subtree is
// input, output or inout.
enum IOType {
In = 0b01,
Out = 0b10,
InOut = 0b11,
};

// The context shared by all semantics with the same IOType during
// flattening.
struct SemanticContext {
// Present if any semantic sharing the same IO type has an explicit or
// implicit SPIR-V location index assigned.
std::optional<bool> UsesExplicitVkLocations = std::nullopt;
// The set of semantics found to be active during flattening. Used to detect
// index collisions.
llvm::StringSet<> ActiveSemantics = {};
// The IOType of this semantic set.
IOType CurrentIOType;
};

struct SemanticStageInfo {
llvm::Triple::EnvironmentType Stage;
IOType AllowedIOTypesMask;
};

private:
Expand All @@ -251,24 +276,30 @@ class SemaHLSL : public SemaBase {

void checkSemanticAnnotation(FunctionDecl *EntryPoint, const Decl *Param,
const HLSLAppliedSemanticAttr *SemanticAttr,
bool IsInput);
const SemanticContext &SC);

bool determineActiveSemanticOnScalar(FunctionDecl *FD,
DeclaratorDecl *OutputDecl,
DeclaratorDecl *D,
SemanticInfo &ActiveSemantic,
llvm::StringSet<> &ActiveSemantics,
bool IsInput);
SemanticContext &SC);

bool determineActiveSemantic(FunctionDecl *FD, DeclaratorDecl *OutputDecl,
DeclaratorDecl *D, SemanticInfo &ActiveSemantic,
llvm::StringSet<> &ActiveSemantics,
bool IsInput);
SemanticContext &SC);

void processExplicitBindingsOnDecl(VarDecl *D);

void diagnoseAvailabilityViolations(TranslationUnitDecl *TU);

void diagnoseAttrStageMismatch(
const Attr *A, llvm::Triple::EnvironmentType Stage,
std::initializer_list<llvm::Triple::EnvironmentType> AllowedStages);

void diagnoseSemanticStageMismatch(
const Attr *A, llvm::Triple::EnvironmentType Stage, IOType CurrentIOType,
std::initializer_list<SemanticStageInfo> AllowedStages);

uint32_t getNextImplicitBindingOrderID() {
return ImplicitBindingNextOrderID++;
}
Expand Down
40 changes: 28 additions & 12 deletions clang/lib/CodeGen/CGHLSLRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,20 +582,22 @@ static llvm::Value *createSPIRVLocationLoad(IRBuilder<> &B, llvm::Module &M,
return B.CreateLoad(Ty, GV);
}

llvm::Value *
CGHLSLRuntime::emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
llvm::Value *CGHLSLRuntime::emitSPIRVUserSemanticLoad(
llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) {
Twine BaseName = Twine(Semantic->getAttrName()->getName());
Twine VariableName = BaseName.concat(Twine(Index.value_or(0)));

unsigned Location = SPIRVLastAssignedInputSemanticLocation;
if (auto *L = Decl->getAttr<HLSLVkLocationAttr>())
Location = L->getLocation();

// DXC completely ignores the semantic/index pair. Location are assigned from
// the first semantic to the last.
llvm::ArrayType *AT = dyn_cast<llvm::ArrayType>(Type);
unsigned ElementCount = AT ? AT->getNumElements() : 1;
SPIRVLastAssignedInputSemanticLocation += ElementCount;

return createSPIRVLocationLoad(B, CGM.getModule(), Type, Location,
VariableName.str());
}
Expand All @@ -616,10 +618,14 @@ static void createSPIRVLocationStore(IRBuilder<> &B, llvm::Module &M,

void CGHLSLRuntime::emitSPIRVUserSemanticStore(
llvm::IRBuilder<> &B, llvm::Value *Source,
HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) {
const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
Twine BaseName = Twine(Semantic->getAttrName()->getName());
Twine VariableName = BaseName.concat(Twine(Index.value_or(0)));

unsigned Location = SPIRVLastAssignedOutputSemanticLocation;
if (auto *L = Decl->getAttr<HLSLVkLocationAttr>())
Location = L->getLocation();

// DXC completely ignores the semantic/index pair. Location are assigned from
// the first semantic to the last.
Expand Down Expand Up @@ -671,7 +677,7 @@ llvm::Value *CGHLSLRuntime::emitUserSemanticLoad(
IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) {
if (CGM.getTarget().getTriple().isSPIRV())
return emitSPIRVUserSemanticLoad(B, Type, Semantic, Index);
return emitSPIRVUserSemanticLoad(B, Type, Decl, Semantic, Index);

if (CGM.getTarget().getTriple().isDXIL())
return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
Expand All @@ -684,7 +690,7 @@ void CGHLSLRuntime::emitUserSemanticStore(IRBuilder<> &B, llvm::Value *Source,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {
if (CGM.getTarget().getTriple().isSPIRV())
return emitSPIRVUserSemanticStore(B, Source, Semantic, Index);
return emitSPIRVUserSemanticStore(B, Source, Decl, Semantic, Index);

if (CGM.getTarget().getTriple().isDXIL())
return emitDXILUserSemanticStore(B, Source, Semantic, Index);
Expand All @@ -693,8 +699,9 @@ void CGHLSLRuntime::emitUserSemanticStore(IRBuilder<> &B, llvm::Value *Source,
}

llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic, std::optional<unsigned> Index) {
IRBuilder<> &B, const FunctionDecl *FD, llvm::Type *Type,
const clang::DeclaratorDecl *Decl, HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index) {

std::string SemanticName = Semantic->getAttrName()->getName().upper();
if (SemanticName == "SV_GROUPINDEX") {
Expand Down Expand Up @@ -730,8 +737,12 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
return buildVectorInput(B, GroupIDIntrinsic, Type);
}

const auto *ShaderAttr = FD->getAttr<HLSLShaderAttr>();
assert(ShaderAttr && "Entry point has no shader attribute");
llvm::Triple::EnvironmentType ST = ShaderAttr->getType();

if (SemanticName == "SV_POSITION") {
if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) {
if (ST == Triple::EnvironmentType::Pixel) {
if (CGM.getTarget().getTriple().isSPIRV())
return createSPIRVBuiltinLoad(B, CGM.getModule(), Type,
Semantic->getAttrName()->getName(),
Expand All @@ -740,7 +751,7 @@ llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad(
return emitDXILUserSemanticLoad(B, Type, Semantic, Index);
}

if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Vertex) {
if (ST == Triple::EnvironmentType::Vertex) {
return emitUserSemanticLoad(B, Type, Decl, Semantic, Index);
}
}
Expand Down Expand Up @@ -783,6 +794,11 @@ void CGHLSLRuntime::emitSystemSemanticStore(IRBuilder<> &B, llvm::Value *Source,
}
}

if (SemanticName == "SV_TARGET") {
emitUserSemanticStore(B, Source, Decl, Semantic, Index);
return;
}

llvm_unreachable(
"Store hasn't been implemented yet for this system semantic. FIXME");
}
Expand All @@ -793,7 +809,7 @@ llvm::Value *CGHLSLRuntime::handleScalarSemanticLoad(

std::optional<unsigned> Index = Semantic->getSemanticIndex();
if (Semantic->getAttrName()->getName().starts_with_insensitive("SV_"))
return emitSystemSemanticLoad(B, Type, Decl, Semantic, Index);
return emitSystemSemanticLoad(B, FD, Type, Decl, Semantic, Index);
return emitUserSemanticLoad(B, Type, Decl, Semantic, Index);
}

Expand Down
5 changes: 4 additions & 1 deletion clang/lib/CodeGen/CGHLSLRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ class CGHLSLRuntime {
protected:
CodeGenModule &CGM;

llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B,
const FunctionDecl *FD, llvm::Type *Type,
const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
Expand Down Expand Up @@ -278,6 +279,7 @@ class CGHLSLRuntime {
HLSLResourceBindingAttr *RBA);

llvm::Value *emitSPIRVUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
llvm::Value *emitDXILUserSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type,
Expand All @@ -289,6 +291,7 @@ class CGHLSLRuntime {
std::optional<unsigned> Index);

void emitSPIRVUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source,
const clang::DeclaratorDecl *Decl,
HLSLAppliedSemanticAttr *Semantic,
std::optional<unsigned> Index);
void emitDXILUserSemanticStore(llvm::IRBuilder<> &B, llvm::Value *Source,
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7703,6 +7703,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_HLSLUnparsedSemantic:
S.HLSL().handleSemanticAttr(D, AL);
break;
case ParsedAttr::AT_HLSLVkLocation:
S.HLSL().handleVkLocationAttr(D, AL);
break;

case ParsedAttr::AT_AbiTag:
handleAbiTagAttr(S, D, AL);
Expand Down
Loading
Loading