From f230e82d4b00c59a802480e138ceb5ea18a98699 Mon Sep 17 00:00:00 2001 From: Akio Gaule <10719597+akioCL@users.noreply.github.com> Date: Thu, 30 May 2024 18:47:20 -0400 Subject: [PATCH 1/5] Add support for specialization constants Signed-off-by: Akio Gaule <10719597+akioCL@users.noreply.github.com> --- .../Windows/src/DirectX12PlatformEmitter.cpp | 30 ++++++++++++++++ .../Windows/src/DirectX12PlatformEmitter.h | 2 ++ .../Windows/src/VulkanPlatformEmitter.cpp | 35 ++++++++++++++++++- Platform/Windows/src/VulkanPlatformEmitter.h | 3 ++ src/AzslcBackend.cpp | 18 ++++++++++ src/AzslcBackend.h | 8 +++-- src/AzslcEmitter.cpp | 24 ++++++++----- src/AzslcKindInfo.h | 1 + src/AzslcMain.cpp | 4 +++ src/AzslcPlatformEmitter.cpp | 5 +++ src/AzslcPlatformEmitter.h | 3 ++ src/AzslcReflection.cpp | 1 + 12 files changed, 123 insertions(+), 11 deletions(-) diff --git a/Platform/Windows/src/DirectX12PlatformEmitter.cpp b/Platform/Windows/src/DirectX12PlatformEmitter.cpp index 5e4d4a8..c7367ab 100644 --- a/Platform/Windows/src/DirectX12PlatformEmitter.cpp +++ b/Platform/Windows/src/DirectX12PlatformEmitter.cpp @@ -126,4 +126,34 @@ namespace AZ::ShaderCompiler return Decorate("#define sig ", Join(rootAttrList, ", \" \\\n"), "\"\n\n"); } + + string DirectX12PlatformEmitter::GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbolUid, const Options& options) const + { + // Specialization constants will be represented by a volatile variable that will be patched later. + std::stringstream stream; + auto* ir = codeEmitter.GetIR(); + auto* varInfo = ir->GetSymbolSubAs(symbolUid.GetName()); + auto retInfo = varInfo->GetTypeRefInfo(); + + // Volatile is not allowed for global variables, so we create a function to wrap it. + std:string varName = "sc_" + JoinAllNestedNamesWithUnderscore(symbolUid.m_name); + std::string retType = codeEmitter.GetTranslatedName(retInfo, UsageContext::ReferenceSite); + std::string functionName = "GetSpecializationConstant_" + JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "()"; + + // Emit the function + assert(varInfo->m_specializationId >= 0); + stream << retType << " " << functionName; + stream << "\n{\n"; + stream << " volatile int " << varName; + stream << " = " << varInfo->m_specializationId << ";\n"; + stream << " return (" << retType << ") " << varName << ";\n"; + stream << "}\n\n"; + + // Emit the global variable that is going to be the shader option. It's default value will be the return value + // of the function we just created. + stream << codeEmitter.GetTranslatedName(varInfo->m_typeInfoExt, UsageContext::ReferenceSite, options) + " "; + stream << codeEmitter.GetTranslatedName(symbolUid.m_name, UsageContext::DeclarationSite); + stream << " = " << functionName << ";\n"; + return stream.str(); + } } diff --git a/Platform/Windows/src/DirectX12PlatformEmitter.h b/Platform/Windows/src/DirectX12PlatformEmitter.h index c1fd1cd..10094cc 100644 --- a/Platform/Windows/src/DirectX12PlatformEmitter.h +++ b/Platform/Windows/src/DirectX12PlatformEmitter.h @@ -24,6 +24,8 @@ namespace AZ::ShaderCompiler bool RequiresUniqueSpaceForUnboundedArrays() const override {return true;} + [[nodiscard]] + string GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const override; private: DirectX12PlatformEmitter() : PlatformEmitter {} {}; diff --git a/Platform/Windows/src/VulkanPlatformEmitter.cpp b/Platform/Windows/src/VulkanPlatformEmitter.cpp index 7c13b6d..636f76a 100644 --- a/Platform/Windows/src/VulkanPlatformEmitter.cpp +++ b/Platform/Windows/src/VulkanPlatformEmitter.cpp @@ -79,5 +79,38 @@ namespace AZ::ShaderCompiler } return { stream.str(), registerString }; } - + + string VulkanPlatformEmitter::GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbolUid, const Options& options) const + { + std::stringstream stream; + auto* ir = codeEmitter.GetIR(); + auto* varInfo = ir->GetSymbolSubAs(symbolUid.GetName()); + auto retInfo = varInfo->GetTypeRefInfo(); + string typeAsStr = codeEmitter.GetTranslatedName(retInfo, UsageContext::ReferenceSite); + string defaultValue = codeEmitter.GetInitializerClause(varInfo); + Modifiers forbidden = StorageFlag::Static; + assert(varInfo->m_specializationId >= 0); + stream << "[[vk::constant_id(" << varInfo->m_specializationId << ")]]\n"; + if (retInfo.m_typeClass == TypeClass::Enum) + { + // Enums are not a valid type for specialization constant, so we use the underlaying scalar type. + // The we add a global static variable with the enum type that cast from the specialization constant. + auto* enumClassInfo = ir->GetSymbolSubAs(retInfo.m_typeId.GetName()); + auto& enumerators = enumClassInfo->GetOrderedMembers(); + auto scalarType = enumClassInfo->Get()->m_underlyingType.m_arithmeticInfo.UnderlyingScalarToStr(); + string scName = JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "_SC_OPTION"; + stream << "const " << scalarType << " " << scName; + // TODO: if using a default value, emit it as the underlying scalar type, since enums are not valid default values for + // specialization constants (casting is also not allowed). We set default values for shader options at runtime so it's not + // a problem. + stream << " = (" << scalarType << ")" << "0;\n"; + // Set the default value for the global static variable as the value of the specialization constant. + defaultValue = std::move(scName); + forbidden = Modifiers{}; + } + stream << codeEmitter.GetTranslatedName(varInfo->m_typeInfoExt, UsageContext::ReferenceSite, options, forbidden) + " "; + stream << codeEmitter.GetTranslatedName(symbolUid.m_name, UsageContext::DeclarationSite) + " = "; + stream << "(" << typeAsStr << ")" << (defaultValue.empty() ? "0" : defaultValue) << "; \n"; + return stream.str(); + } } diff --git a/Platform/Windows/src/VulkanPlatformEmitter.h b/Platform/Windows/src/VulkanPlatformEmitter.h index c91a7b1..15d15de 100644 --- a/Platform/Windows/src/VulkanPlatformEmitter.h +++ b/Platform/Windows/src/VulkanPlatformEmitter.h @@ -25,6 +25,9 @@ namespace AZ::ShaderCompiler [[nodiscard]] std::pair GetDataViewHeaderFooter(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, uint32_t bindInfoRegisterIndex, string_view registerTypeLetter, optional stringifiedLogicalSpace) const override final; + [[nodiscard]] + string GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const override; + private: VulkanPlatformEmitter() : PlatformEmitter {} {}; }; diff --git a/src/AzslcBackend.cpp b/src/AzslcBackend.cpp index b1e6e45..b90a5f2 100644 --- a/src/AzslcBackend.cpp +++ b/src/AzslcBackend.cpp @@ -428,6 +428,8 @@ namespace AZ::ShaderCompiler Json::Value varRoot(Json::objectValue); varRoot["meta"] = "Variant options list exported by AZSLc"; + bool useSpecializationConstants = false; + Json::Value shaderOptions(Json::arrayValue); uint32_t keyOffsetBits = 0; @@ -454,6 +456,8 @@ namespace AZ::ShaderCompiler bool isUdt = IsUserDefined(varInfo->GetTypeClass()); assert(isUdt || IsPredefinedType(varInfo->GetTypeClass())); shaderOption["kind"] = isUdt ? "user-defined" : "predefined"; + shaderOption["specializationId"] = varInfo->m_specializationId; + useSpecializationConstants |= varInfo->m_specializationId >= 0; AppendOptionRange(shaderOption, uid, varInfo, options); @@ -482,11 +486,25 @@ namespace AZ::ShaderCompiler } } + varRoot["specializationConstants"] = options.m_useSpecializationConstantsForOptions && useSpecializationConstants; varRoot["ShaderOptions"] = shaderOptions; return varRoot; } + void Backend::SetupOptionsSpecializationId(const Options& options) const + { + uint32_t specializationId = 0; + for (auto& [uid, varInfo, kindInfo] : m_ir->m_symbols.GetOrderedSymbolsOfSubType_3()) + { + if (varInfo->CheckHasStorageFlag(StorageFlag::Option) && + !m_ir->m_symbols.GetAttribute(uid, "no_specialization")) + { + varInfo->m_specializationId = specializationId++; + } + } + } + // little check utility static void CheckHasOneFoldedDimensionOrThrow(const ArrayDimensions& dims, string_view callSite) { diff --git a/src/AzslcBackend.h b/src/AzslcBackend.h index 09c4925..bddef49 100644 --- a/src/AzslcBackend.h +++ b/src/AzslcBackend.h @@ -41,6 +41,7 @@ namespace AZ::ShaderCompiler int m_rootConstantsMaxSize = std::numeric_limits::max(); //!< Indicates the number of root constants to be allowed, 0 means root constants not enabled Packing::Layout m_packConstantBuffers = Packing::Layout::DirectXPacking; //!< Packing standard for constant buffers (uniform) Packing::Layout m_packDataBuffers = Packing::Layout::CStylePacking; //!< Packing standard for data buffer views + bool m_useSpecializationConstantsForOptions = false; //!< Use specialization constants for shader options }; struct Binding @@ -148,6 +149,9 @@ namespace AZ::ShaderCompiler //! Get HLSL form of in/out modifiers static const char* GetInputModifier(const TypeQualifiers& typeQualifier); + //! Get the initialization clause as a string. Returns an empty string if it doesn't have any initialization. + string GetInitializerClause(const AZ::ShaderCompiler::VarInfo* varInfo) const; + //! Fabricate a HLSL snippet that represents the type stored in typeInfo. Relevant options relate to matrix qualifiers. //! \param banned is the Flag you can setup to list a collection of type qualifiers you don't want to reproduce. string GetExtendedTypeInfo(const ExtendedTypeInfo& extTypeInfo, const Options& options, Modifiers banned, std::function translator) const; @@ -163,8 +167,6 @@ namespace AZ::ShaderCompiler string GetTranspiledTokens(misc::Interval interval) const; - string GetInitializerClause(const AZ::ShaderCompiler::VarInfo* varInfo) const; - uint32_t GetNumberOf32BitConstants(const Options& options, const IdentifierUID& uid) const; RootSigDesc BuildSignatureDescription(const Options& options, int num32BitConst) const; @@ -177,6 +179,8 @@ namespace AZ::ShaderCompiler Json::Value GetVariantList(const Options& options, bool includeEmpty = false) const; + void SetupOptionsSpecializationId(const Options& options) const; + IntermediateRepresentation* m_ir; TokenStream* m_tokens; diff --git a/src/AzslcEmitter.cpp b/src/AzslcEmitter.cpp index 605728d..b31d55e 100644 --- a/src/AzslcEmitter.cpp +++ b/src/AzslcEmitter.cpp @@ -97,6 +97,7 @@ namespace AZ::ShaderCompiler const RootSigDesc rootSig = BuildSignatureDescription(options, numOf32bitConst); SetupScopeMigrations(options); + SetupOptionsSpecializationId(options); // Emit global attributes for (const auto& attr : m_ir->m_symbols.GetGlobalAttributeList()) @@ -379,17 +380,24 @@ namespace AZ::ShaderCompiler { assert(m_ir->GetKind(symbolUid) == Kind::Variable); assert(IsTopLevelThroughTranslation(symbolUid)); - auto* varInfo = m_ir->GetSymbolSubAs(symbolUid.GetName()); - EmitGetShaderKeyFunctionDeclaration(symbolUid, varInfo->GetTypeRefInfo()); - m_out << ";\n\n"; + if (options.m_useSpecializationConstantsForOptions && varInfo->m_specializationId >= 0) + { + m_out << GetPlatformEmitter().GetSpecializationConstant(*this, symbolUid, options); + } + else + { - m_out << "#if defined(" + JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "_OPTION_DEF)\n"; - EmitVariableDeclaration(*varInfo, symbolUid, options, VarDeclHasFlag(VarDeclHas::OptionDefine)); - m_out << "_OPTION_DEF ;\n#else\n"; - EmitVariableDeclaration(*varInfo, symbolUid, options, VarDeclHasFlag(VarDeclHas::OptionDefine) | VarDeclHas::Initializer); - m_out << ";\n#endif\n"; + EmitGetShaderKeyFunctionDeclaration(symbolUid, varInfo->GetTypeRefInfo()); + m_out << ";\n\n"; + + m_out << "#if defined(" + JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "_OPTION_DEF)\n"; + EmitVariableDeclaration(*varInfo, symbolUid, options, VarDeclHasFlag(VarDeclHas::OptionDefine)); + m_out << "_OPTION_DEF ;\n#else\n"; + EmitVariableDeclaration(*varInfo, symbolUid, options, VarDeclHasFlag(VarDeclHas::OptionDefine) | VarDeclHas::Initializer); + m_out << ";\n#endif\n"; + } } void CodeEmitter::EmitShaderVariantOptionGetters(const Options& options) const diff --git a/src/AzslcKindInfo.h b/src/AzslcKindInfo.h index bbcec04..a0cb52a 100644 --- a/src/AzslcKindInfo.h +++ b/src/AzslcKindInfo.h @@ -400,6 +400,7 @@ namespace AZ::ShaderCompiler optional m_samplerState; ExtendedTypeInfo m_typeInfoExt; int m_estimatedCostImpact = -1; //!< Cached value calculated by AnalyzeOptionRanks + int m_specializationId= -1; //< id of the specialization. -1 means no specialization. }; // VarInfo methods definitions diff --git a/src/AzslcMain.cpp b/src/AzslcMain.cpp index aad3e2a..aa01434 100644 --- a/src/AzslcMain.cpp +++ b/src/AzslcMain.cpp @@ -423,6 +423,9 @@ int main(int argc, const char* argv[]) int maxSpaces = std::numeric_limits::max(); auto maxSpacesOpt = cli.add_option("--max-spaces", maxSpaces, "Will choose register spaces that do not extend past this limit."); + bool useSpecializationConstants = false; + cli.add_flag("--sc-options", useSpecializationConstants, "Use specialization constants for shader options."); + std::array warningOpts; for (const auto e : Warn::Enumerate{}) { @@ -575,6 +578,7 @@ int main(int argc, const char* argv[]) emitOptions.m_emitRootSig = rootSig; emitOptions.m_padRootConstantCB = padRootConst; emitOptions.m_skipAlignmentValidation = noAlignmentValidation; + emitOptions.m_useSpecializationConstantsForOptions = useSpecializationConstants; if (*rootConstOpt) { diff --git a/src/AzslcPlatformEmitter.cpp b/src/AzslcPlatformEmitter.cpp index 19f599c..8bada0f 100644 --- a/src/AzslcPlatformEmitter.cpp +++ b/src/AzslcPlatformEmitter.cpp @@ -97,4 +97,9 @@ namespace AZ::ShaderCompiler { return size; } + + string PlatformEmitter::GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const + { + return ""; + } } diff --git a/src/AzslcPlatformEmitter.h b/src/AzslcPlatformEmitter.h index d4b4036..2a1b16d 100644 --- a/src/AzslcPlatformEmitter.h +++ b/src/AzslcPlatformEmitter.h @@ -76,5 +76,8 @@ namespace AZ::ShaderCompiler virtual uint32_t AlignRootConstants(uint32_t size) const; virtual bool RequiresUniqueSpaceForUnboundedArrays() const {return false;} + + [[nodiscard]] + virtual string GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const; }; } \ No newline at end of file diff --git a/src/AzslcReflection.cpp b/src/AzslcReflection.cpp index 693bb10..1d0836a 100644 --- a/src/AzslcReflection.cpp +++ b/src/AzslcReflection.cpp @@ -630,6 +630,7 @@ namespace AZ::ShaderCompiler void CodeReflection::DumpVariantList(const Options& options) const { AnalyzeOptionRanks(); + SetupOptionsSpecializationId(options); m_out << GetVariantList(options); m_out << "\n"; } From a42683c7f3cded769c2b80c9d26544a337ffad3d Mon Sep 17 00:00:00 2001 From: Akio Gaule <10719597+akioCL@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:48:53 -0700 Subject: [PATCH 2/5] Add support for specialization constants on Metal Signed-off-by: Akio Gaule <10719597+akioCL@users.noreply.github.com> --- .../src/CommonVulkanPlatformEmitter.cpp | 47 +++++++++++++++++++ .../Common/src/CommonVulkanPlatformEmitter.h | 24 ++++++++++ .../Windows/src/VulkanPlatformEmitter.cpp | 34 -------------- Platform/Windows/src/VulkanPlatformEmitter.h | 8 ++-- Platform/iOS/src/MetalPlatformEmitter.h | 5 +- src/CMakeLists.txt | 1 + 6 files changed, 78 insertions(+), 41 deletions(-) create mode 100644 Platform/Common/src/CommonVulkanPlatformEmitter.cpp create mode 100644 Platform/Common/src/CommonVulkanPlatformEmitter.h diff --git a/Platform/Common/src/CommonVulkanPlatformEmitter.cpp b/Platform/Common/src/CommonVulkanPlatformEmitter.cpp new file mode 100644 index 0000000..d4f1d76 --- /dev/null +++ b/Platform/Common/src/CommonVulkanPlatformEmitter.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include "CommonVulkanPlatformEmitter.h" + +namespace AZ::ShaderCompiler +{ + string CommonVulkanPlatformEmitter::GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbolUid, const Options& options) const + { + std::stringstream stream; + auto* ir = codeEmitter.GetIR(); + auto* varInfo = ir->GetSymbolSubAs(symbolUid.GetName()); + auto retInfo = varInfo->GetTypeRefInfo(); + string typeAsStr = codeEmitter.GetTranslatedName(retInfo, UsageContext::ReferenceSite); + string defaultValue = codeEmitter.GetInitializerClause(varInfo); + Modifiers forbidden = StorageFlag::Static; + assert(varInfo->m_specializationId >= 0); + stream << "[[vk::constant_id(" << varInfo->m_specializationId << ")]]\n"; + if (retInfo.m_typeClass == TypeClass::Enum) + { + // Enums are not a valid type for specialization constant, so we use the underlaying scalar type. + // The we add a global static variable with the enum type that cast from the specialization constant. + auto* enumClassInfo = ir->GetSymbolSubAs(retInfo.m_typeId.GetName()); + auto& enumerators = enumClassInfo->GetOrderedMembers(); + auto scalarType = enumClassInfo->Get()->m_underlyingType.m_arithmeticInfo.UnderlyingScalarToStr(); + string scName = JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "_SC_OPTION"; + stream << "const " << scalarType << " " << scName; + // TODO: if using a default value, emit it as the underlying scalar type, since enums are not valid default values for + // specialization constants (casting is also not allowed). We set default values for shader options at runtime so it's not + // a problem. + stream << " = (" << scalarType << ")" << "0;\n"; + // Set the default value for the global static variable as the value of the specialization constant. + defaultValue = std::move(scName); + forbidden = Modifiers{}; + } + stream << codeEmitter.GetTranslatedName(varInfo->m_typeInfoExt, UsageContext::ReferenceSite, options, forbidden) + " "; + stream << codeEmitter.GetTranslatedName(symbolUid.m_name, UsageContext::DeclarationSite) + " = "; + stream << "(" << typeAsStr << ")" << (defaultValue.empty() ? "0" : defaultValue) << "; \n"; + return stream.str(); + } +} diff --git a/Platform/Common/src/CommonVulkanPlatformEmitter.h b/Platform/Common/src/CommonVulkanPlatformEmitter.h new file mode 100644 index 0000000..3a16d29 --- /dev/null +++ b/Platform/Common/src/CommonVulkanPlatformEmitter.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include + +namespace AZ::ShaderCompiler +{ + // PlatformEmitter is not a Backend by design. It's a supplement to CodeEmitter, not a replacement + struct CommonVulkanPlatformEmitter : PlatformEmitter + { + public: + [[nodiscard]] + string GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const override; + + protected: + CommonVulkanPlatformEmitter() : PlatformEmitter {} {}; + }; +} diff --git a/Platform/Windows/src/VulkanPlatformEmitter.cpp b/Platform/Windows/src/VulkanPlatformEmitter.cpp index 636f76a..7ed8f51 100644 --- a/Platform/Windows/src/VulkanPlatformEmitter.cpp +++ b/Platform/Windows/src/VulkanPlatformEmitter.cpp @@ -79,38 +79,4 @@ namespace AZ::ShaderCompiler } return { stream.str(), registerString }; } - - string VulkanPlatformEmitter::GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbolUid, const Options& options) const - { - std::stringstream stream; - auto* ir = codeEmitter.GetIR(); - auto* varInfo = ir->GetSymbolSubAs(symbolUid.GetName()); - auto retInfo = varInfo->GetTypeRefInfo(); - string typeAsStr = codeEmitter.GetTranslatedName(retInfo, UsageContext::ReferenceSite); - string defaultValue = codeEmitter.GetInitializerClause(varInfo); - Modifiers forbidden = StorageFlag::Static; - assert(varInfo->m_specializationId >= 0); - stream << "[[vk::constant_id(" << varInfo->m_specializationId << ")]]\n"; - if (retInfo.m_typeClass == TypeClass::Enum) - { - // Enums are not a valid type for specialization constant, so we use the underlaying scalar type. - // The we add a global static variable with the enum type that cast from the specialization constant. - auto* enumClassInfo = ir->GetSymbolSubAs(retInfo.m_typeId.GetName()); - auto& enumerators = enumClassInfo->GetOrderedMembers(); - auto scalarType = enumClassInfo->Get()->m_underlyingType.m_arithmeticInfo.UnderlyingScalarToStr(); - string scName = JoinAllNestedNamesWithUnderscore(symbolUid.m_name) + "_SC_OPTION"; - stream << "const " << scalarType << " " << scName; - // TODO: if using a default value, emit it as the underlying scalar type, since enums are not valid default values for - // specialization constants (casting is also not allowed). We set default values for shader options at runtime so it's not - // a problem. - stream << " = (" << scalarType << ")" << "0;\n"; - // Set the default value for the global static variable as the value of the specialization constant. - defaultValue = std::move(scName); - forbidden = Modifiers{}; - } - stream << codeEmitter.GetTranslatedName(varInfo->m_typeInfoExt, UsageContext::ReferenceSite, options, forbidden) + " "; - stream << codeEmitter.GetTranslatedName(symbolUid.m_name, UsageContext::DeclarationSite) + " = "; - stream << "(" << typeAsStr << ")" << (defaultValue.empty() ? "0" : defaultValue) << "; \n"; - return stream.str(); - } } diff --git a/Platform/Windows/src/VulkanPlatformEmitter.h b/Platform/Windows/src/VulkanPlatformEmitter.h index 15d15de..720811a 100644 --- a/Platform/Windows/src/VulkanPlatformEmitter.h +++ b/Platform/Windows/src/VulkanPlatformEmitter.h @@ -8,11 +8,12 @@ #pragma once #include +#include namespace AZ::ShaderCompiler { // PlatformEmitter is not a Backend by design. It's a supplement to CodeEmitter, not a replacement - struct VulkanPlatformEmitter : PlatformEmitter + struct VulkanPlatformEmitter : CommonVulkanPlatformEmitter { public: //! This method will be called once and only once when the platform emitter registers itself to the system. @@ -25,10 +26,7 @@ namespace AZ::ShaderCompiler [[nodiscard]] std::pair GetDataViewHeaderFooter(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, uint32_t bindInfoRegisterIndex, string_view registerTypeLetter, optional stringifiedLogicalSpace) const override final; - [[nodiscard]] - string GetSpecializationConstant(const CodeEmitter& codeEmitter, const IdentifierUID& symbol, const Options& options) const override; - private: - VulkanPlatformEmitter() : PlatformEmitter {} {}; + VulkanPlatformEmitter() : CommonVulkanPlatformEmitter {} {}; }; } diff --git a/Platform/iOS/src/MetalPlatformEmitter.h b/Platform/iOS/src/MetalPlatformEmitter.h index 4ef0b16..aa8adc9 100644 --- a/Platform/iOS/src/MetalPlatformEmitter.h +++ b/Platform/iOS/src/MetalPlatformEmitter.h @@ -8,11 +8,12 @@ #pragma once #include +#include namespace AZ::ShaderCompiler { // PlatformEmitter is not a Backend by design. It's a supplement to CodeEmitter, not a replacement - struct MetalPlatformEmitter : PlatformEmitter + struct MetalPlatformEmitter : CommonVulkanPlatformEmitter { public: //! This method will be called once and only once when the platform emitter registers itself to the system. @@ -25,6 +26,6 @@ namespace AZ::ShaderCompiler uint32_t AlignRootConstants(uint32_t size) const override final; private: - MetalPlatformEmitter() : PlatformEmitter {} {}; + MetalPlatformEmitter() : CommonVulkanPlatformEmitter {} {}; }; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9ef9d6c..4ee3c25 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -72,6 +72,7 @@ target_include_directories( PRIVATE ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/external + ${PROJECT_SOURCE_DIR}/../Platform/Common/src ${ANTLR4CPP_INCLUDE_DIRS} ${MPARK_VARIANT_INCLUDE_DIRS} ${TINY_OPTIONAL_INCLUDE_DIRS} From c4685c65154a97b1601de456b9a0773641ef2c40 Mon Sep 17 00:00:00 2001 From: Akio Gaule <10719597+akioCL@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:30:12 -0400 Subject: [PATCH 3/5] Add tests Signed-off-by: Akio Gaule <10719597+akioCL@users.noreply.github.com> --- src/AzslcEmitter.cpp | 8 ++- .../Emission/no_specialization-attribute.azsl | 37 ++++++++++++ .../Emission/no_specialization-attribute.txt | 6 ++ .../specialization-constants-dx12.azsl | 57 +++++++++++++++++++ .../specialization-constants-dx12.txt | 15 +++++ .../Emission/specialization-constants-vk.azsl | 57 +++++++++++++++++++ .../Emission/specialization-constants-vk.txt | 10 ++++ 7 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/Emission/no_specialization-attribute.azsl create mode 100644 tests/Emission/no_specialization-attribute.txt create mode 100644 tests/Emission/specialization-constants-dx12.azsl create mode 100644 tests/Emission/specialization-constants-dx12.txt create mode 100644 tests/Emission/specialization-constants-vk.azsl create mode 100644 tests/Emission/specialization-constants-vk.txt diff --git a/src/AzslcEmitter.cpp b/src/AzslcEmitter.cpp index b31d55e..7178f51 100644 --- a/src/AzslcEmitter.cpp +++ b/src/AzslcEmitter.cpp @@ -408,7 +408,8 @@ namespace AZ::ShaderCompiler for (const auto& [uid, varInfo] : m_ir->m_symbols.GetOrderedSymbolsOfSubType_2()) { // For now only emit top level options - if (!IsTopLevelThroughTranslation(uid) || !varInfo->CheckHasStorageFlag(StorageFlag::Option)) + if (!IsTopLevelThroughTranslation(uid) || !varInfo->CheckHasStorageFlag(StorageFlag::Option) || + (options.m_useSpecializationConstantsForOptions && varInfo->m_specializationId >= 0)) { continue; } @@ -701,6 +702,11 @@ namespace AZ::ShaderCompiler // Reserved for integer type option variables. Do not re-emit outstream << "// original attribute: [[" << attrInfo << "]]\n "; } + else if (attrInfo.m_attribute == "no_specialization") + { + // Reserved for avoiding specialization of a shader option. Do not re-emit + outstream << "// original attribute: [[" << attrInfo << "]]\n "; + } else { diff --git a/tests/Emission/no_specialization-attribute.azsl b/tests/Emission/no_specialization-attribute.azsl new file mode 100644 index 0000000..cbf90d7 --- /dev/null +++ b/tests/Emission/no_specialization-attribute.azsl @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +[[no_specialization]] +option bool UseGI = true; + +ShaderResourceGroupSemantic ExampleBinding +{ + FrequencyId = 0; + ShaderVariantFallback = 64; +}; + +ShaderResourceGroup ExampleSRG : ExampleBinding +{ + float4 exampleColor; +}; + +struct VertexInput { float3 m_position : POSITION; }; + +struct VertexOutput { float4 m_position : SV_Position; }; + +VertexOutput MainVS(VertexInput input) +{ + VertexOutput output; + output.m_position = float4(input.m_position, 1.0); + return output; +} + +float4 MainPS() : SV_Target0 +{ + if (UseGI) + return ExampleSRG::exampleColor; +} diff --git a/tests/Emission/no_specialization-attribute.txt b/tests/Emission/no_specialization-attribute.txt new file mode 100644 index 0000000..a3ec47b --- /dev/null +++ b/tests/Emission/no_specialization-attribute.txt @@ -0,0 +1,6 @@ +/* + Cmdargs: ['--namespace', 'vk', '--sc-options'] +*/ +"bool GetShaderVariantKey_UseGI ( ) ;" +"static const bool UseGI = GetShaderVariantKey_UseGI ( ) ;" + diff --git a/tests/Emission/specialization-constants-dx12.azsl b/tests/Emission/specialization-constants-dx12.azsl new file mode 100644 index 0000000..0b89243 --- /dev/null +++ b/tests/Emission/specialization-constants-dx12.azsl @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +/* + * Demonstrates the use of shader variants (options) + * + * Global constants and SRG constants marked with the "option" qualifier are treated as variant options + */ + +enum class QualityT {Low, Medium, High}; +// Option keyword Type Name Default value (hint) +option QualityT Quality = QualityT::High; + +// Boolean is supported +option bool UseGI = true; + +// Integer is supported +[range(1, 64)] +option int IntOption = 42; + +ShaderResourceGroupSemantic ExampleBinding +{ + FrequencyId = 0; + ShaderVariantFallback = 64; +}; + +ShaderResourceGroup ExampleSRG : ExampleBinding +{ + float4 exampleColor; +}; + +struct VertexInput { float3 m_position : POSITION; }; + +struct VertexOutput { float4 m_position : SV_Position; }; + +VertexOutput MainVS(VertexInput input) +{ + VertexOutput output; + output.m_position = float4(input.m_position, 1.0); + return output; +} + +float4 MainPS() : SV_Target0 +{ + switch (Quality) + { + case QualityT::Low: return ExampleSRG::exampleColor * float4(IntOption, 0, 0, 0); + case QualityT::Medium: return ExampleSRG::exampleColor * float4(0, IntOption, 0, 0); + case QualityT::High: return ExampleSRG::exampleColor * float4(0, 0, IntOption, 0); + default: return ExampleSRG::exampleColor; // https://github.com/microsoft/DirectXShaderCompiler/issues/2331 + } +} diff --git a/tests/Emission/specialization-constants-dx12.txt b/tests/Emission/specialization-constants-dx12.txt new file mode 100644 index 0000000..c05add1 --- /dev/null +++ b/tests/Emission/specialization-constants-dx12.txt @@ -0,0 +1,15 @@ +/* + Cmdargs: ['--namespace', 'dx', '--sc-options'] +*/ +":: QualityT GetSpecializationConstant_Quality ( ) " +"volatile int sc_Quality = 0 ;" +"return ( :: QualityT ) sc_Quality ;" +"static const :: QualityT Quality = GetSpecializationConstant_Quality ( ) ;" +"bool GetSpecializationConstant_UseGI ( )" +"volatile int sc_UseGI = 1 ;" +"return ( bool ) sc_UseGI ;" +"static const bool UseGI = GetSpecializationConstant_UseGI ( ) ;" +"int GetSpecializationConstant_IntOption ( )" +"volatile int sc_IntOption = 2 ;" +"return ( int ) sc_IntOption ;" +"static const int IntOption = GetSpecializationConstant_IntOption ( ) ;" diff --git a/tests/Emission/specialization-constants-vk.azsl b/tests/Emission/specialization-constants-vk.azsl new file mode 100644 index 0000000..0b89243 --- /dev/null +++ b/tests/Emission/specialization-constants-vk.azsl @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +/* + * Demonstrates the use of shader variants (options) + * + * Global constants and SRG constants marked with the "option" qualifier are treated as variant options + */ + +enum class QualityT {Low, Medium, High}; +// Option keyword Type Name Default value (hint) +option QualityT Quality = QualityT::High; + +// Boolean is supported +option bool UseGI = true; + +// Integer is supported +[range(1, 64)] +option int IntOption = 42; + +ShaderResourceGroupSemantic ExampleBinding +{ + FrequencyId = 0; + ShaderVariantFallback = 64; +}; + +ShaderResourceGroup ExampleSRG : ExampleBinding +{ + float4 exampleColor; +}; + +struct VertexInput { float3 m_position : POSITION; }; + +struct VertexOutput { float4 m_position : SV_Position; }; + +VertexOutput MainVS(VertexInput input) +{ + VertexOutput output; + output.m_position = float4(input.m_position, 1.0); + return output; +} + +float4 MainPS() : SV_Target0 +{ + switch (Quality) + { + case QualityT::Low: return ExampleSRG::exampleColor * float4(IntOption, 0, 0, 0); + case QualityT::Medium: return ExampleSRG::exampleColor * float4(0, IntOption, 0, 0); + case QualityT::High: return ExampleSRG::exampleColor * float4(0, 0, IntOption, 0); + default: return ExampleSRG::exampleColor; // https://github.com/microsoft/DirectXShaderCompiler/issues/2331 + } +} diff --git a/tests/Emission/specialization-constants-vk.txt b/tests/Emission/specialization-constants-vk.txt new file mode 100644 index 0000000..c7329fd --- /dev/null +++ b/tests/Emission/specialization-constants-vk.txt @@ -0,0 +1,10 @@ +/* + Cmdargs: ['--namespace', 'vk', '--sc-options'] +*/ +"[[ vk :: constant_id ( 0 ) ]]" +"const int Quality_SC_OPTION = ( int ) 0 ;" +"static const :: QualityT Quality = ( :: QualityT ) Quality_SC_OPTION ;" +"[[ vk :: constant_id ( 1 ) ]]" +"const bool UseGI = ( bool ) true ;" +"[[ vk :: constant_id ( 2 ) ]]" +"const int IntOption = ( int ) 42 ;" From 433482fdadd3c55f7a9d6914043f7c66b2636594 Mon Sep 17 00:00:00 2001 From: Akio Gaule <10719597+akioCL@users.noreply.github.com> Date: Wed, 5 Jun 2024 21:06:03 -0400 Subject: [PATCH 4/5] Fix keyOffset when emitting get shader key function Signed-off-by: Akio Gaule <10719597+akioCL@users.noreply.github.com> --- src/AzslcEmitter.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/AzslcEmitter.cpp b/src/AzslcEmitter.cpp index 7178f51..f791ca4 100644 --- a/src/AzslcEmitter.cpp +++ b/src/AzslcEmitter.cpp @@ -408,8 +408,7 @@ namespace AZ::ShaderCompiler for (const auto& [uid, varInfo] : m_ir->m_symbols.GetOrderedSymbolsOfSubType_2()) { // For now only emit top level options - if (!IsTopLevelThroughTranslation(uid) || !varInfo->CheckHasStorageFlag(StorageFlag::Option) || - (options.m_useSpecializationConstantsForOptions && varInfo->m_specializationId >= 0)) + if (!IsTopLevelThroughTranslation(uid) || !varInfo->CheckHasStorageFlag(StorageFlag::Option)) { continue; } @@ -422,15 +421,18 @@ namespace AZ::ShaderCompiler m_out << "// Generated code: ShaderVariantOptions fallback value getters:\n"; auto shaderOptions = GetVariantList(options, true); - auto shaderOptionIndex = 0; - - for (const auto& [uid, varInfo] : symbols) + for (uint32_t shaderOptionIndex = 0; shaderOptionIndex < symbols.size(); ++shaderOptionIndex) { + const auto& [uid, varInfo] = symbols[shaderOptionIndex]; + if (options.m_useSpecializationConstantsForOptions && varInfo->m_specializationId >= 0) + { + continue; + } + const auto keySizeInBits = shaderOptions["ShaderOptions"][shaderOptionIndex]["keySize"].asUInt(); const auto keyOffsetBits = shaderOptions["ShaderOptions"][shaderOptionIndex]["keyOffset"].asUInt(); const auto defaultValue = shaderOptions["ShaderOptions"][shaderOptionIndex]["defaultValue"].asString(); - shaderOptionIndex++; EmitGetShaderKeyFunction(m_shaderVariantFallbackUid, uid, keySizeInBits, keyOffsetBits, defaultValue, varInfo->GetTypeRefInfo()); } } From 8c6b7bc87f86947d8073b6fbc21837dcb4a9c580 Mon Sep 17 00:00:00 2001 From: Akio Gaule <10719597+akioCL@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:49:37 -0400 Subject: [PATCH 5/5] Update lint files Signed-off-by: Akio Gaule <10719597+akioCL@users.noreply.github.com> --- EditorsLint/AZSL_notepad++_bright.xml | 2 +- EditorsLint/AZSL_notepad++_dark.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/EditorsLint/AZSL_notepad++_bright.xml b/EditorsLint/AZSL_notepad++_bright.xml index 1e2eac2..f3564bb 100644 --- a/EditorsLint/AZSL_notepad++_bright.xml +++ b/EditorsLint/AZSL_notepad++_bright.xml @@ -27,7 +27,7 @@ break continue if else switch case return for while do typedef namespace true false compile discard inline const struct class interface static extern register volatile inline nointerpolation shared uniform row_major column_major snorm unorm cbuffer groupshared SamplerState in out inout point triangle line lineadj triangleadj rootconstant ShaderResourceGroup ShaderResourceGroupSemantic ShaderVariantFallback FrequencyId associatedtype typealias typeof __azslc_print_message __azslc_print_symbol __azslc_prtsym_fully_qualified __azslc_prtsym_least_qualified __azslc_prtsym_constint_value enum option void bool bool1 bool2 bool3 bool4 int int1 int2 int3 int4 uint uint1 uint2 uint3 uint4 half half1 half2 half3 half4 float float1 float2 float3 float4 double double1 double2 double3 double4 matrix bool1x1 bool1x2 bool1x3 bool1x4 bool2x1 bool2x2 bool2x3 bool2x4 bool3x1 bool3x2 bool3x3 bool3x4 bool4x1 bool4x2 bool4x3 bool4x4 int1x1 int1x2 int1x3 int1x4 int2x1 int2x2 int2x3 int2x4 int3x1 int3x2 int3x3 int3x4 int4x1 int4x2 int4x3 int4x4 uint1x1 uint1x2 uint1x3 uint1x4 uint2x1 uint2x2 uint2x3 uint2x4 uint3x1 uint3x2 uint3x3 uint3x4 uint4x1 uint4x2 uint4x3 uint4x4 dword dword1 dword2 dword3 dword4 dword1x1 dword1x2 dword1x3 dword1x4 dword2x1 dword2x2 dword2x3 dword2x4 dword3x1 dword3x2 dword3x3 dword3x4 dword4x1 dword4x2 dword4x3 dword4x4 half1x1 half1x2 half1x3 half1x4 half2x1 half2x2 half2x3 half2x4 half3x1 half3x2 half3x3 half3x4 half4x1 half4x2 half4x3 half4x4 float1x1 float1x2 float1x3 float1x4 float2x1 float2x2 float2x3 float2x4 float3x1 float3x2 float3x3 float3x4 float4x1 float4x2 float4x3 float4x4 double1x1 double1x2 double1x3 double1x4 double2x1 double2x2 double2x3 double2x4 double3x1 double3x2 double3x3 double3x4 double4x1 double4x2 double4x3 double4x4 vector matrix Texture Texture1D Texture1DArray Texture2D Texture2DArray Texture2DMS Texture2DMSArray Texture3D TextureCube RWTexture1D RWTexture1DArray RWTexture2D RWTexture2DArray RWTexture3D Buffer StructuredBuffer AppendStructuredBuffer ConsumeStructuredBuffer RWBuffer RWStructuredBuffer ByteAddressBuffer RWByteAddressBuffer PointStream TriangleStream LineStream InputPatch OutputPatch SubpassInput SubpassInputMS ConstantBuffer Sampler sampler RaytracingAccelerationStructure BuiltInTriangleIntersectionAttributes RayDesc RAY_FLAG - unroll loop flatten branch earlydepthstencil domain instance maxtessfactor outputcontrolpoints outputtopology partitioning patchconstantfunc numthreads maxvertexcount precise input_attachment_index + unroll loop flatten branch earlydepthstencil domain instance maxtessfactor outputcontrolpoints outputtopology partitioning patchconstantfunc numthreads maxvertexcount precise input_attachment_index no_specialization SV_DispatchThreadID SV_DomainLocation SV_GroupID SV_GroupIndex SV_GroupThreadID SV_GSInstanceID SV_InsideTessFactor SV_OutputControlPointID SV_Coverage SV_Depth SV_Position SV_IsFrontFace SV_RenderTargetArrayIndex SV_SampleIndex SV_ViewportArrayIndex SV_InstanceID SV_PrimitiveID SV_VertexID SV_ClipDistance SV_CullDistance SV_Target BINORMAL BLENDINDICES BLENDWEIGHT COLOR NORMAL POSITION POSITIONT PSIZE TANGENT TEXCOORD FOG TESSFACTOR TEXCOORD VFACE VPOS DEPTH abs acos all AllMemoryBarrier AllMemoryBarrierWithGroupSync any asdouble asfloat asin asint asuint atan atan2 ceil clamp clip cos cosh countbits cross ddx ddx_coarse ddx_fine ddy ddy_coards ddy_fine degrees determinant DeviceMemoryBarrier DeviceMemoryBarrierWithGroupSync distance dot dst EvaluateAttributeAtCentroid EvaluateAttributeAtSample EvaluateAttributeSnapped exp exp2 f16tof32 f32tof16 faceforward firstbithigh firstbitlow floor fmod frac frexp fwidth GetRenderTargetSampleCount GetRenderTargetSamplePosition GroupMemoryBarrier GroupMemoryBarrierWithGroupSync InterlockedAdd InterlockedAnd InterlockedCompareExchange InterlockedExchange InterlockedMax InterlockedMin IntterlockedOr InterlockedXor isfinite isinf isnan ldexp length lerp lit log log10 log2 mad max min modf mul normalize pow Process2DQuadTessFactorsAvg Process2DQuadTessFactorsMax Process2DQuadTessFactorsMin ProcessIsolineTessFactors ProcessQuadTessFactorsAvg ProcessQuadTessFactorsMax ProcessQuadTessFactorsMin ProcessTriTessFactorsAvg ProcessTriTessFactorsMax ProcessTriTessFactorsMin radians rcp reflect refract reversebits round rsqrt saturate sign sin sincos sinh smoothstep sqrt step tan tanh transpose trunc Append RestartStrip CalculateLevelOfDetail CalculateLevelOfDetailUnclamped GetDimensions GetSamplePosition Load Sample SampleBias SampleCmp SampleCmpLevelZero SampleGrad SampleLevel Load2 Load3 Load4 Consume Store Store2 Store3 Store4 DecrementCounter IncrementCounter mips Gather GatherRed GatherGreen GatherBlue GatherAlpha GatherCmp GatherCmpRed GatherCmpGreen GatherCmpBlue GatherCmpAlpha AddressU AddressV AddressW BorderColor MinFilter MagFilter MipFilter MaxAnisotropy MaxLOD MinLOD MipLODBias ComparisonFunc ReductionType Point Linear Filter Comparison Minimum Maximum Wrap Mirror Clamp Border MirrorOnce Never Less Equal LessEqual Greater NotEqual GreaterEqual Always OpaqueBlack TransparentBlack OpaqueWhite SubpassLoad TraceRay ReportHit IgnoreHit CallShader AcceptHitAndEndSearch DispatchRaysIndex DispatchRaysDimensions PrimitiveIndex diff --git a/EditorsLint/AZSL_notepad++_dark.xml b/EditorsLint/AZSL_notepad++_dark.xml index 8d51f82..796591b 100644 --- a/EditorsLint/AZSL_notepad++_dark.xml +++ b/EditorsLint/AZSL_notepad++_dark.xml @@ -27,7 +27,7 @@ break continue if else switch case return for while do typedef namespace true false compile discard inline const struct class interface static extern register volatile inline nointerpolation shared uniform row_major column_major snorm unorm cbuffer groupshared SamplerState in out inout point triangle line lineadj triangleadj rootconstant ShaderResourceGroup ShaderResourceGroupSemantic ShaderVariantFallback FrequencyId associatedtype typealias typeof __azslc_print_message __azslc_print_symbol __azslc_prtsym_fully_qualified __azslc_prtsym_least_qualified __azslc_prtsym_constint_value enum option void bool bool1 bool2 bool3 bool4 int int1 int2 int3 int4 uint uint1 uint2 uint3 uint4 half half1 half2 half3 half4 float float1 float2 float3 float4 double double1 double2 double3 double4 matrix bool1x1 bool1x2 bool1x3 bool1x4 bool2x1 bool2x2 bool2x3 bool2x4 bool3x1 bool3x2 bool3x3 bool3x4 bool4x1 bool4x2 bool4x3 bool4x4 int1x1 int1x2 int1x3 int1x4 int2x1 int2x2 int2x3 int2x4 int3x1 int3x2 int3x3 int3x4 int4x1 int4x2 int4x3 int4x4 uint1x1 uint1x2 uint1x3 uint1x4 uint2x1 uint2x2 uint2x3 uint2x4 uint3x1 uint3x2 uint3x3 uint3x4 uint4x1 uint4x2 uint4x3 uint4x4 dword dword1 dword2 dword3 dword4 dword1x1 dword1x2 dword1x3 dword1x4 dword2x1 dword2x2 dword2x3 dword2x4 dword3x1 dword3x2 dword3x3 dword3x4 dword4x1 dword4x2 dword4x3 dword4x4 half1x1 half1x2 half1x3 half1x4 half2x1 half2x2 half2x3 half2x4 half3x1 half3x2 half3x3 half3x4 half4x1 half4x2 half4x3 half4x4 float1x1 float1x2 float1x3 float1x4 float2x1 float2x2 float2x3 float2x4 float3x1 float3x2 float3x3 float3x4 float4x1 float4x2 float4x3 float4x4 double1x1 double1x2 double1x3 double1x4 double2x1 double2x2 double2x3 double2x4 double3x1 double3x2 double3x3 double3x4 double4x1 double4x2 double4x3 double4x4 vector matrix Texture Texture1D Texture1DArray Texture2D Texture2DArray Texture2DMS Texture2DMSArray Texture3D TextureCube RWTexture1D RWTexture1DArray RWTexture2D RWTexture2DArray RWTexture3D Buffer StructuredBuffer AppendStructuredBuffer ConsumeStructuredBuffer RWBuffer RWStructuredBuffer ByteAddressBuffer RWByteAddressBuffer PointStream TriangleStream LineStream InputPatch OutputPatch SubpassInput SubpassInputMS ConstantBuffer Sampler sampler RaytracingAccelerationStructure BuiltInTriangleIntersectionAttributes RayDesc RAY_FLAG - unroll loop flatten branch earlydepthstencil domain instance maxtessfactor outputcontrolpoints outputtopology partitioning patchconstantfunc numthreads maxvertexcount precise input_attachment_index + unroll loop flatten branch earlydepthstencil domain instance maxtessfactor outputcontrolpoints outputtopology partitioning patchconstantfunc numthreads maxvertexcount precise input_attachment_index no_specialization SV_DispatchThreadID SV_DomainLocation SV_GroupID SV_GroupIndex SV_GroupThreadID SV_GSInstanceID SV_InsideTessFactor SV_OutputControlPointID SV_Coverage SV_Depth SV_Position SV_IsFrontFace SV_RenderTargetArrayIndex SV_SampleIndex SV_ViewportArrayIndex SV_InstanceID SV_PrimitiveID SV_VertexID SV_ClipDistance SV_CullDistance SV_Target BINORMAL BLENDINDICES BLENDWEIGHT COLOR NORMAL POSITION POSITIONT PSIZE TANGENT TEXCOORD FOG TESSFACTOR TEXCOORD VFACE VPOS DEPTH abs acos all AllMemoryBarrier AllMemoryBarrierWithGroupSync any asdouble asfloat asin asint asuint atan atan2 ceil clamp clip cos cosh countbits cross ddx ddx_coarse ddx_fine ddy ddy_coards ddy_fine degrees determinant DeviceMemoryBarrier DeviceMemoryBarrierWithGroupSync distance dot dst EvaluateAttributeAtCentroid EvaluateAttributeAtSample EvaluateAttributeSnapped exp exp2 f16tof32 f32tof16 faceforward firstbithigh firstbitlow floor fmod frac frexp fwidth GetRenderTargetSampleCount GetRenderTargetSamplePosition GroupMemoryBarrier GroupMemoryBarrierWithGroupSync InterlockedAdd InterlockedAnd InterlockedCompareExchange InterlockedExchange InterlockedMax InterlockedMin IntterlockedOr InterlockedXor isfinite isinf isnan ldexp length lerp lit log log10 log2 mad max min modf mul normalize pow Process2DQuadTessFactorsAvg Process2DQuadTessFactorsMax Process2DQuadTessFactorsMin ProcessIsolineTessFactors ProcessQuadTessFactorsAvg ProcessQuadTessFactorsMax ProcessQuadTessFactorsMin ProcessTriTessFactorsAvg ProcessTriTessFactorsMax ProcessTriTessFactorsMin radians rcp reflect refract reversebits round rsqrt saturate sign sin sincos sinh smoothstep sqrt step tan tanh transpose trunc Append RestartStrip CalculateLevelOfDetail CalculateLevelOfDetailUnclamped GetDimensions GetSamplePosition Load Sample SampleBias SampleCmp SampleCmpLevelZero SampleGrad SampleLevel Load2 Load3 Load4 Consume Store Store2 Store3 Store4 DecrementCounter IncrementCounter mips Gather GatherRed GatherGreen GatherBlue GatherAlpha GatherCmp GatherCmpRed GatherCmpGreen GatherCmpBlue GatherCmpAlpha AddressU AddressV AddressW BorderColor MinFilter MagFilter MipFilter MaxAnisotropy MaxLOD MinLOD MipLODBias ComparisonFunc ReductionType Point Linear Filter Comparison Minimum Maximum Wrap Mirror Clamp Border MirrorOnce Never Less Equal LessEqual Greater NotEqual GreaterEqual Always OpaqueBlack TransparentBlack OpaqueWhite SubpassLoad TraceRay ReportHit IgnoreHit CallShader AcceptHitAndEndSearch DispatchRaysIndex DispatchRaysDimensions PrimitiveIndex