Skip to content

Commit

Permalink
initial changes for prototype of "AZSL evolution" according to RFC o3…
Browse files Browse the repository at this point in the history
…de#71 "concept idea 2"

Signed-off-by: Vivien Oddou <[email protected]>
  • Loading branch information
siliconvoodoo committed Nov 15, 2022
1 parent fe0de85 commit 6a35b94
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 103 deletions.
15 changes: 7 additions & 8 deletions src/AzslcEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace AZ::ShaderCompiler
const uint32_t numOf32bitConst = GetNumberOf32BitConstants(options, m_ir->m_rootConstantStructUID);
const RootSigDesc rootSig = BuildSignatureDescription(options, numOf32bitConst);

SetupScopeMigrations(options);
//SetupScopeMigrations(options);

// Emit global attributes
for (const auto& attr : m_ir->m_symbols.GetGlobalAttributeList())
Expand Down Expand Up @@ -951,7 +951,7 @@ namespace AZ::ShaderCompiler
}

const auto& bindInfo = rootSig.Get(srgId);
m_out << "ConstantBuffer " << srgInfo.m_declNode->Name->getText() << "_CBContainer : register(b" << bindInfo.m_registerBinding.m_pair[bindSet].m_registerIndex << ")\n{\n";
m_out << "ConstantBuffer " << "NONAME" /*srgInfo.m_declNode->Name->getText() TODO-AZSLC2 */ << "_CBContainer : register(b" << bindInfo.m_registerBinding.m_pair[bindSet].m_registerIndex << ")\n{\n";

for (const auto& cId : srgInfo.m_CBs)
{
Expand Down Expand Up @@ -1104,16 +1104,15 @@ namespace AZ::ShaderCompiler
uint32_t swizzle = keyOffsetBits / AZ::ShaderCompiler::kShaderVariantKeyElementSize;
keyOffsetBits -= swizzle * AZ::ShaderCompiler::kShaderVariantKeyElementSize;

// Intentional unnamed scope for error-checking
if (auto* varInfo = m_ir->GetSymbolSubAs<VarInfo>(shaderKeyUid.m_name))
{
auto& varInfo = *m_ir->GetSymbolSubAs<VarInfo>(shaderKeyUid.m_name);
auto dims = varInfo.m_typeInfoExt.GetDimensions();
auto dims = varInfo->m_typeInfoExt.GetDimensions();
assert(dims.m_dimensions.size() == 1); // This is generated variable, it must have exactly 1 array dimension
if (arraySlot >= dims.m_dimensions[0])
{
const string errorMessage = ConcatString("The option {", UnmangleTrimedName(getterUid.m_name), "} exceeds the number of bits (",
AZ::ShaderCompiler::kShaderVariantKeyRegisterSize * dims.m_dimensions[0], ") allowed by the ShaderVariantFallback.\n",
"Either increase the limit or remove some options!");
AZ::ShaderCompiler::kShaderVariantKeyRegisterSize * dims.m_dimensions[0], ") allowed by the ShaderVariantFallback.\n",
"Either increase the limit or remove some options!");
throw AzslcEmitterException(EMITTER_OPTION_EXCEEDING_BITS_COUNT, errorMessage);
}
}
Expand Down Expand Up @@ -1152,7 +1151,7 @@ namespace AZ::ShaderCompiler
m_out << "/* Generated code from ";
// We don't emit the SRG attributes (only as a comment), but they can be accessed by the srgId if needed
EmitAllAttachedAttributes(srgId);
m_out << " ShaderResourceGroup " << srgInfo.m_declNode->Name->getText() << "*/\n";
m_out << " ShaderResourceGroup " << "NONAME" /* srgInfo.m_declNode->Name->getText() // TODO-AZSLC2 */ << "*/\n";

for (const auto& t : srgInfo.m_srViews)
{
Expand Down
28 changes: 12 additions & 16 deletions src/AzslcIntermediateRepresentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,25 +147,21 @@ namespace AZ::ShaderCompiler
}

auto variantFallbackGroups = 0;
for (auto srgInfo : GetOrderedSubInfosOfSubType<SRGInfo>())
for (auto classInfo : GetOrderedSubInfosOfSubType<ClassInfo>())
{
if (!srgInfo->m_semantic)
if (classInfo->m_kind == Kind::ShaderResourceGroupSemantic)
{
auto errorMsg = FormatString("Missing ShaderResourceGroupSemantic for ShaderResourceGroup [%s]", srgInfo->m_declNode->getText().c_str());
throw AzslcIrException(IR_SRG_WITHOUT_SEMANTIC, errorMsg);
}

auto* semanticAsClassInfo = GetSymbolSubAs<ClassInfo>(srgInfo->m_semantic->GetName());
optional<int64_t>& variantFallback = semanticAsClassInfo->Get<SRGSemanticInfo>()->m_variantFallback;
if (variantFallback)
{
variantFallbackGroups++;

if (!hasOptions)
optional<int64_t>& variantFallback = classInfo->Get<SRGSemanticInfo>()->m_variantFallback;
if (variantFallback)
{
PrintWarning(Warn::W1, semanticAsClassInfo->GetDeclNode()->start,
"If you have no options, SRG do not need a ShaderVariantFallback");
variantFallback = none;
variantFallbackGroups++;

if (!hasOptions)
{
PrintWarning(Warn::W1, classInfo->GetDeclNode()->start,
"If you have no options, SRG do not need a ShaderVariantFallback");
variantFallback = none;
}
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/AzslcKindInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,14 +816,15 @@ namespace AZ::ShaderCompiler
return none;
}

bool IsPartial() const { return m_declNode ? !!m_declNode->Partial() : false; }
//bool IsPartial() const { return m_declNode ? !!m_declNode->Partial() : false; }
bool IsPartial() const { return false; } // TODO-AZSLC2

size_t GetOriginalLineNumber() const
{
return m_declNode ? m_declNode->start->getLine() : 0;
}

AstSRGDeclNode* m_declNode = nullptr;
ParserRuleContext* m_declNode = nullptr;
ClassInfo m_implicitStruct; // Implicit holding struct for SRG Constants
optional< IdentifierUID > m_shaderVariantFallback;
optional< IdentifierUID > m_semantic;
Expand Down Expand Up @@ -1157,7 +1158,7 @@ namespace AZ::ShaderCompiler

const TokensLocation operator()(const SRGInfo& srgInfo) const
{
return MakeTokensLocation(srgInfo.m_declNode, srgInfo.m_declNode->Name);
return MakeTokensLocation(srgInfo.m_declNode->start); //srgInfo.m_declNode->Name
}

const TokensLocation operator()(const TypeAliasInfo taInfo) const
Expand Down
48 changes: 30 additions & 18 deletions src/AzslcListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,18 @@ namespace AZ::ShaderCompiler
m_ir->m_scope.ExitScope(ctx->RightBrace()->getSourceInterval().b);
}

void SemaCheckListener::enterSrgDefinition(azslParser::SrgDefinitionContext* ctx)
{
m_ir->m_sema.RegisterSRG(ctx);
m_ir->m_scope.EnterScope(ctx->Name->getText(), ctx->LeftBrace()->getSourceInterval().a);
}

void SemaCheckListener::exitSrgDefinition(azslParser::SrgDefinitionContext* ctx)
{
// Validate the content on scope exit
m_ir->m_sema.ValidateSrg(ctx);
m_ir->m_scope.ExitScope(ctx->RightBrace()->getSourceInterval().b);
}
//void SemaCheckListener::enterSrgDefinition(azslParser::SrgDefinitionContext* ctx)
//{
// m_ir->m_sema.RegisterSRG(ctx);
// m_ir->m_scope.EnterScope(ctx->Name->getText(), ctx->LeftBrace()->getSourceInterval().a);
//}

//void SemaCheckListener::exitSrgDefinition(azslParser::SrgDefinitionContext* ctx)
//{
// // Validate the content on scope exit
// m_ir->m_sema.ValidateSrg(ctx);
// m_ir->m_scope.ExitScope(ctx->RightBrace()->getSourceInterval().b);
//}

void SemaCheckListener::enterSrgSemanticMemberDeclaration(azslParser::SrgSemanticMemberDeclarationContext* ctx)
{
Expand Down Expand Up @@ -349,16 +349,16 @@ namespace AZ::ShaderCompiler
{
// Attributes can be filtered out by namespace.
// Attributes without a namespace are always valid and attributes in the 'void' namespace are always filtered out
auto Namespace = (ctx->Namespace) ? ctx->Namespace->getText() : "";
if (!Namespace.empty() && (Namespace == "void" || !ir->IsAttributeNamespaceActivated(Namespace)))
auto attrNamespace = (ctx->AttributeNamespace) ? ctx->AttributeNamespace->getText() : "";
if (!attrNamespace.empty() && (attrNamespace == "void" || !ir->IsAttributeNamespaceActivated(attrNamespace)))
{
return;
}

ir->RegisterAttributeSpecifier(scope,
GetAttributeCategory(ctx),
ctx->getStart()->getLine(),
Namespace,
attrNamespace,
ctx->Name->getText(),
ctx->attributeArgumentList());
}
Expand Down Expand Up @@ -398,7 +398,7 @@ namespace AZ::ShaderCompiler
{
// for (a;b;c) block is special, because it has a special power of symbol definition in the 'a' block.
// therefore we enter the anonymous scope right before 'a'
m_ir->m_sema.MakeAndEnterAnonymousScope("for", ctx->LeftParen()->getSymbol());
m_ir->m_sema.MakeAndEnterAnonymousScope("for", ctx->LeftParen()->getSymbol(), ctx);
}

void SemaCheckListener::exitForStatement(azslParser::ForStatementContext* ctx)
Expand All @@ -411,7 +411,7 @@ namespace AZ::ShaderCompiler
if (!Is< azslParser::HlslFunctionDefinitionContext >(ctx->parent) // not function because we already entered
&& !Is< azslParser::ForStatementContext >(ctx->parent)) // not for statement because we already entered
{
m_ir->m_sema.MakeAndEnterAnonymousScope("bk", ctx->start);
m_ir->m_sema.MakeAndEnterAnonymousScope("bk", ctx->start, ctx);
}
}

Expand All @@ -426,14 +426,26 @@ namespace AZ::ShaderCompiler

void SemaCheckListener::enterSwitchBlock(azslParser::SwitchBlockContext* ctx)
{
m_ir->m_sema.MakeAndEnterAnonymousScope("sw", ctx->start);
m_ir->m_sema.MakeAndEnterAnonymousScope("sw", ctx->start, ctx);
}

void SemaCheckListener::exitSwitchBlock(azslParser::SwitchBlockContext* ctx)
{
m_ir->m_scope.ExitScope(ctx->stop->getTokenIndex());
}

void SemaCheckListener::enterNamespaceStatement(azslParser::NamespaceStatementContext* ctx)
{
UnqualifiedName uqName = ExtractNameFromIdExpression(ctx->Name);
string decorator = "namespace_" + uqName;
m_ir->m_sema.MakeAndEnterAnonymousScope(decorator, ctx->start, ctx);
}

void SemaCheckListener::exitNamespaceStatement(azslParser::NamespaceStatementContext* ctx)
{
m_ir->m_scope.ExitScope(ctx->stop->getTokenIndex());
}

void SemaCheckListener::enterFunctionCallExpression(azslParser::FunctionCallExpressionContext* ctx)
{
if (m_functionCallMutator)
Expand Down
6 changes: 4 additions & 2 deletions src/AzslcListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ namespace AZ::ShaderCompiler
void enterEnumeratorDeclarator(azslParser::EnumeratorDeclaratorContext* ctx) override;
void enterSamplerBodyDeclaration(azslParser::SamplerBodyDeclarationContext* ctx) override;
void exitSamplerBodyDeclaration(azslParser::SamplerBodyDeclarationContext* ctx) override;
void enterSrgDefinition(azslParser::SrgDefinitionContext* ctx) override;
void exitSrgDefinition(azslParser::SrgDefinitionContext* ctx) override;
//void enterSrgDefinition(azslParser::SrgDefinitionContext* ctx) override;
//void exitSrgDefinition(azslParser::SrgDefinitionContext* ctx) override;
void enterSrgSemanticMemberDeclaration(azslParser::SrgSemanticMemberDeclarationContext* ctx) override;
void exitClassDefinition(azslParser::ClassDefinitionContext* ctx) override;
void exitSrgSemantic(azslParser::SrgSemanticContext* ctx) override;
Expand Down Expand Up @@ -58,6 +58,8 @@ namespace AZ::ShaderCompiler
void exitBlockStatement(azslParser::BlockStatementContext* ctx) override;
void enterSwitchBlock(azslParser::SwitchBlockContext* ctx) override;
void exitSwitchBlock(azslParser::SwitchBlockContext* ctx) override;
void enterNamespaceStatement(azslParser::NamespaceStatementContext* ctx) override;
void exitNamespaceStatement(azslParser::NamespaceStatementContext* ctx) override;
void enterFunctionCallExpression(azslParser::FunctionCallExpressionContext* ctx) override;

void visitTerminal(tree::TerminalNode* node) override;
Expand Down
6 changes: 3 additions & 3 deletions src/AzslcMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ namespace StdFs = std::filesystem;

// versioning
// Correspond to the supported version of the AZSL language.
#define AZSLC_MAJOR "1"
#define AZSLC_MAJOR "2" // evolution prototype
// For large features or milestones. Minor version allows for breaking changes. Existing tests can change.
#define AZSLC_MINOR "8" // last change: introduction of class inheritance
#define AZSLC_MINOR "0"
// For small features or bug fixes. They cannot introduce breaking changes. Existing tests shouldn't change.
#define AZSLC_REVISION "12" // last change: reduce useless sharp-line directives
#define AZSLC_REVISION "2"


namespace AZ::ShaderCompiler
Expand Down
2 changes: 1 addition & 1 deletion src/AzslcReflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ namespace AZ::ShaderCompiler
for (auto& [srgUid, srgInfo] : m_ir->GetOrderedSymbolsOfSubType_2<SRGInfo>())
{
Json::Value srgLayout(Json::objectValue);
srgLayout["id"] = srgInfo->m_declNode->Name->getText();
//srgLayout["id"] = srgInfo->m_declNode->Name->getText(); // TODO-AZSLC2

// Try to locate the original filename where this SRG is declared
size_t physical = srgInfo->m_declNode->getStart()->getLine();
Expand Down
46 changes: 39 additions & 7 deletions src/AzslcSemanticOrchestrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,8 @@ namespace AZ::ShaderCompiler
}
// get enclosing scope:
auto& [curScopeId, curScopeKind] = GetCurrentScopeIdAndKind();
bool enclosedBySRG = curScopeKind.GetKind() == Kind::ShaderResourceGroup;
bool enclosedBySRG = curScopeKind.GetKind() == Kind::ShaderResourceGroup
|| (curScopeKind.GetKind() == Kind::Namespace && m_symbols->GetAttribute(curScopeId, "SRG").has_value());

assert(!curScopeKind.IsKindOneOf(Kind::Enum)); // should use RegisterEnumerator

Expand Down Expand Up @@ -698,7 +699,10 @@ namespace AZ::ShaderCompiler
}

auto& [srgUid, srgKind] = GetCurrentScopeIdAndKind();
auto& srgInfo = srgKind.GetSubRefAs<SRGInfo>();
string srgInfoName = string{GetParentName(srgUid.m_name)} + "srginfo_" + srgUid.GetNameLeaf();
srgInfoName = Replace(srgInfoName, "$namespace_", "");
auto srgInfoUID = IdentifierUID{QualifiedName{srgInfoName}};
auto& srgInfo = *m_symbols->GetAsSub<SRGInfo>(srgInfoUID);

TypeClass typeClass = varInfo.GetTypeClass();
assert(typeClass != TypeClass::Alias);
Expand Down Expand Up @@ -889,8 +893,10 @@ namespace AZ::ShaderCompiler
return desc;
}

IdAndKind& SemanticOrchestrator::RegisterSRG(AstSRGDeclNode* ctx)
IdAndKind& SemanticOrchestrator::RegisterSRG(ParserRuleContext* ctx)
{
// TODO-AZSLC2
/*
auto const& idText = ctx->Name->getText();
size_t line = ctx->Name->getLine();
verboseCout << line << ": srg decl: " << idText << "\n";
Expand Down Expand Up @@ -925,7 +931,9 @@ namespace AZ::ShaderCompiler
SRGInfo& srgInfo = info.GetSubAfterInitAs<Kind::ShaderResourceGroup>();
srgInfo.m_declNode = ctx;
srgInfo.m_implicitStruct.m_kind = Kind::Struct;
return symbol;
return symbol;*/
static IdAndKind z;
return z;
}

void SemanticOrchestrator::RegisterBases(azslParser::BaseListContext* ctx)
Expand Down Expand Up @@ -1482,8 +1490,10 @@ namespace AZ::ShaderCompiler
}
}

void SemanticOrchestrator::ValidateSrg(azslParser::SrgDefinitionContext* ctx) noexcept(false)
void SemanticOrchestrator::ValidateSrg(ParserRuleContext* ctx) noexcept(false)
{
// TODO-AZSLC2
/*
auto& srgInfo = GetCurrentScopeSubInfoAs<SRGInfo>();
if (ctx->Semantic)
Expand Down Expand Up @@ -1624,6 +1634,7 @@ namespace AZ::ShaderCompiler
" must be a struct, but seen as ", Kind::ToStr(kind.GetKind()).data())};
}
}
*/
}

optional<int64_t> SemanticOrchestrator::TryFoldSRGSemantic(azslParser::SrgSemanticContext* ctx, size_t semanticTokenType, bool required)
Expand Down Expand Up @@ -1981,10 +1992,31 @@ namespace AZ::ShaderCompiler
return scopeKind.IsKindOneOf(Kind::Struct, Kind::Class, Kind::Interface);
}

void SemanticOrchestrator::MakeAndEnterAnonymousScope(string_view decorationPrefix, Token* scopeFirstToken)
void SemanticOrchestrator::MakeAndEnterAnonymousScope(string_view decorationPrefix, Token* scopeFirstToken, ParserRuleContext* ctx)
{
UnqualifiedName unnamedBlockCode{ConcatString("$", decorationPrefix, m_anonymousCounter)};
AddIdentifier(unnamedBlockCode, Kind::Namespace, scopeFirstToken->getLine());
auto& [id, kind] = AddIdentifier(unnamedBlockCode, Kind::Namespace, scopeFirstToken->getLine());
if (optional<AttributeInfo> attr = m_symbols->GetAttribute(id, "SRG"))
{
string semantic = std::get<string>(attr->m_argList.front());

// register a fake SRG

string idText = Replace(string{decorationPrefix}, "namespace_", "srginfo_") + ToString(m_anonymousCounter);
size_t line = scopeFirstToken->getLine();
verboseCout << line << ": fake srg decl: " << idText << "\n";
auto uqNameView = UnqualifiedNameView{ idText };
IdAndKind* srgSym = LookupSymbol(uqNameView);
if (!srgSym) // already exists (case of partial)
{
auto& symbol = AddIdentifier(uqNameView, Kind::ShaderResourceGroup, line);
// now fillup what we can about the kindinfo:
auto& [uid, info] = symbol;
SRGInfo& srgInfo = info.GetSubAfterInitAs<Kind::ShaderResourceGroup>();
srgInfo.m_declNode = ctx;
srgInfo.m_implicitStruct.m_kind = Kind::Struct;
}
}
m_scope->EnterScope(unnamedBlockCode, scopeFirstToken->getTokenIndex());
++m_anonymousCounter;
}
Expand Down
6 changes: 3 additions & 3 deletions src/AzslcSemanticOrchestrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ namespace AZ::ShaderCompiler

auto ExtractSamplerState(AstVarInitializer* ctx) -> SamplerStateDesc;

auto RegisterSRG(AstSRGDeclNode* ctx) -> IdAndKind&;
auto RegisterSRG(ParserRuleContext* ctx) -> IdAndKind&;

void RegisterSRGSemanticMember(AstSRGSemanticMemberDeclNode* ctx);

Expand Down Expand Up @@ -237,7 +237,7 @@ namespace AZ::ShaderCompiler
// Will diagnose-throw if multiple bases have the candidate symbol's name.
auto GetSymbolHiddenInBase(IdentifierUID hidingCandidate) -> IdAndKind*;

void ValidateSrg(azslParser::SrgDefinitionContext* ctx) noexcept(false);
void ValidateSrg(ParserRuleContext* ctx) noexcept(false);

void ValidateSrgSemantic(azslParser::SrgSemanticContext* ctx) noexcept(false);

Expand Down Expand Up @@ -361,7 +361,7 @@ namespace AZ::ShaderCompiler
auto ResolveOverload(IdAndKind* maybeOverloadSet, azslParser::ArgumentListContext* argumentListCtx) const -> IdAndKind*;

//! Generate a unique name, create a corresponding namespace symbol, and enter its scope
void MakeAndEnterAnonymousScope(string_view decorationPrefix, Token* scopeFirstToken);
void MakeAndEnterAnonymousScope(string_view decorationPrefix, Token* scopeFirstToken, ParserRuleContext* ctx);

private:
//! for internal use when encountering unresolved symbols by lookup.
Expand Down
4 changes: 2 additions & 2 deletions src/AzslcUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ namespace AZ::ShaderCompiler
using AstInterfaceDeclNode = azslParser::InterfaceDefinitionContext;
using AstSRGSemanticDeclNode = azslParser::SrgSemanticContext;
using AstSRGSemanticMemberDeclNode = azslParser::SrgSemanticMemberDeclarationContext;
using AstSRGDeclNode = azslParser::SrgDefinitionContext;
using AstSRGMemberNode = azslParser::SrgMemberDeclarationContext;
//using AstSRGDeclNode = azslParser::SrgDefinitionContext;
//using AstSRGMemberNode = azslParser::SrgMemberDeclarationContext;
using AstNamedVarDecl = azslParser::NamedVariableDeclaratorContext;
using AstUnnamedVarDecl = azslParser::UnnamedVariableDeclaratorContext;
using AstFuncSig = azslParser::LeadingTypeFunctionSignatureContext;
Expand Down
Loading

0 comments on commit 6a35b94

Please sign in to comment.