From c9ef8d58a135061262fd321a82061d27dc733cf5 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 3 May 2023 20:16:58 -0400 Subject: HLSL->Vulkan binding support (#2865) * WIP around VK shift binding. * Refactor around options parsing. * Remove needless passing around of sink. * Some more tidying around OptionsParser. * Handle vulkan shift parsing. * Fix small issue around vk binding and "all". * Fixing some small issues. Missing break. * Split out VulkanLayoutOptions * WIP binding taking into account HLSL->Vulkan options. * First attempt at making binding work with HLSLVulkanOptions. * VulkanLayoutOptions -> HLSLToVulkanLayoutOptions * WIP with HLSL-Vulkan binding. * Some more testing around vk-shift. * Improvements around global binding. More tests. * Improve test coverage. Improve checking for requirements around default space. * Update command line options. * Small fixes. * Small fix in options reporting. * Fix warning issue. * Some fixes for isDefault for HLSLToVulkanLayoutOptions. * Update hlsl-to-vulkan-shift output. The difference was due to default handling if shift isn't specified, and not being specified was not correctly tracked. --- source/compiler-core/slang-command-line-args.h | 16 +- source/compiler-core/slang-diagnostic-sink.h | 2 +- source/slang/slang-compiler.h | 13 +- source/slang/slang-diagnostic-defs.h | 1 + .../slang/slang-hlsl-to-vulkan-layout-options.cpp | 132 + source/slang/slang-hlsl-to-vulkan-layout-options.h | 85 + source/slang/slang-options.cpp | 3556 +++++++++++--------- source/slang/slang-parameter-binding.cpp | 359 +- source/slang/slang.cpp | 14 + 9 files changed, 2385 insertions(+), 1793 deletions(-) create mode 100644 source/slang/slang-hlsl-to-vulkan-layout-options.cpp create mode 100644 source/slang/slang-hlsl-to-vulkan-layout-options.h (limited to 'source') diff --git a/source/compiler-core/slang-command-line-args.h b/source/compiler-core/slang-command-line-args.h index 31807cd48..b2bd48c61 100644 --- a/source/compiler-core/slang-command-line-args.h +++ b/source/compiler-core/slang-command-line-args.h @@ -109,17 +109,15 @@ struct CommandLineReader /// Set the current index void setIndex(Index index) { SLANG_ASSERT(index >= 0 && index <= m_args->getArgCount()); m_index = index; } + void init(CommandLineArgs* args, DiagnosticSink* sink) { m_args = args; m_sink = sink; m_index = 0; } + /// Set up reader with args - CommandLineReader(CommandLineArgs* args, DiagnosticSink* sink): - m_args(args), - m_index(0), - m_sink(sink) - { - } + CommandLineReader(CommandLineArgs* args, DiagnosticSink* sink) { init(args, sink); } + CommandLineReader() = default; - DiagnosticSink* m_sink; - CommandLineArgs* m_args; - Index m_index; + DiagnosticSink* m_sink = nullptr; + CommandLineArgs* m_args = nullptr; + Index m_index = 0; }; struct DownstreamArgs diff --git a/source/compiler-core/slang-diagnostic-sink.h b/source/compiler-core/slang-diagnostic-sink.h index 5131e5194..ebd43b456 100644 --- a/source/compiler-core/slang-diagnostic-sink.h +++ b/source/compiler-core/slang-diagnostic-sink.h @@ -255,7 +255,7 @@ public: /// Default Ctor DiagnosticSink(): m_sourceManager(nullptr), - m_sourceLocationLexer (nullptr) + m_sourceLocationLexer(nullptr) { } diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 117c3f037..42fc3ca1f 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -25,6 +25,8 @@ #include "slang-syntax.h" #include "slang-content-assist-info.h" +#include "slang-hlsl-to-vulkan-layout-options.h" + #include "slang-serialize-ir-types.h" #include "../compiler-core/slang-artifact-representation-impl.h" @@ -1535,6 +1537,7 @@ namespace Slang class TargetRequest : public RefObject { public: + TargetRequest(Linkage* linkage, CodeGenTarget format); void addTargetFlags(SlangTargetFlags flags) @@ -1575,6 +1578,10 @@ namespace Slang return (targetFlags & SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM) != 0; } + void setHLSLToVulkanLayoutOptions(HLSLToVulkanLayoutOptions* opts); + + const HLSLToVulkanLayoutOptions* getHLSLToVulkanLayoutOptions() const { return hlslToVulkanLayoutOptions; } + bool shouldDumpIntermediates() { return dumpIntermediates; } void setTrackLiveness(bool enable) { enableLivenessTracking = enable; } @@ -1611,6 +1618,8 @@ namespace Slang bool dumpIntermediates = false; bool forceGLSLScalarBufferLayout = false; bool enableLivenessTracking = false; + + RefPtr hlslToVulkanLayoutOptions; ///< Optional vulkan layout options }; /// Are we generating code for a D3D API? @@ -1858,7 +1867,7 @@ namespace Slang Type* const* args, DiagnosticSink* sink); - /// Add a mew target and return its index. + /// Add a new target and return its index. UInt addTarget( CodeGenTarget target); @@ -2629,6 +2638,8 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL setDiagnosticFlags(SlangDiagnosticFlags flags) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL setDebugInfoFormat(SlangDebugInfoFormat format) SLANG_OVERRIDE; + void setHLSLToVulkanLayoutOptions(int targetIndex, HLSLToVulkanLayoutOptions* vulkanLayoutOptions); + EndToEndCompileRequest( Session* session); diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index a35c48a6a..e8d521630 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -85,6 +85,7 @@ DIAGNOSTIC( 32, Warning, explicitStageDoesntMatchImpliedStage, "the stage spe DIAGNOSTIC( 33, Error, stageSpecificationIgnoredBecauseNoEntryPoints, "one or more stages were specified, but no entry points were specified with '-entry'") DIAGNOSTIC( 34, Error, stageSpecificationIgnoredBecauseBeforeAllEntryPoints, "when compiling multiple entry points, any '-stage' options must follow the '-entry' option that they apply to") DIAGNOSTIC( 35, Error, noStageSpecifiedInPassThroughMode, "no stage was specified for entry point '$0'; when using the '-pass-through' option, stages must be fully specified on the command line") +DIAGNOSTIC( 36, Error, expectingAnInteger, "expecting an integer value") DIAGNOSTIC( 40, Warning, sameProfileSpecifiedMoreThanOnce, "the '$0' was specified more than once for target '$0'") DIAGNOSTIC( 41, Error, conflictingProfilesSpecifiedForTarget, "conflicting profiles have been specified for target '$0'") diff --git a/source/slang/slang-hlsl-to-vulkan-layout-options.cpp b/source/slang/slang-hlsl-to-vulkan-layout-options.cpp new file mode 100644 index 000000000..e143762a1 --- /dev/null +++ b/source/slang/slang-hlsl-to-vulkan-layout-options.cpp @@ -0,0 +1,132 @@ +// slang-hlsl-to-vulkan-layout-options.cpp + +#include "slang-hlsl-to-vulkan-layout-options.h" + +namespace Slang { + +namespace { // anonymous + +typedef HLSLToVulkanLayoutOptions::Kind ShiftKind; + +/* {b|s|t|u} */ + +static NamesDescriptionValue s_vulkanShiftKinds[] = +{ + { ValueInt(ShiftKind::Buffer), "b", "Vulkan Buffer resource" }, + { ValueInt(ShiftKind::Sampler), "s", "Vulkan Sampler resource" }, + { ValueInt(ShiftKind::Texture), "t", "Vulkan Texture resource" }, + { ValueInt(ShiftKind::Uniform), "u", "Vulkan Uniform resource" }, +}; + +} // anonymous + +/* static */ConstArrayView HLSLToVulkanLayoutOptions::getKindInfos() +{ + return makeConstArrayView(s_vulkanShiftKinds); +} + +HLSLToVulkanLayoutOptions::HLSLToVulkanLayoutOptions() +{ + for (auto& shift : m_allShifts) + { + shift = kInvalidShift; + } +} + + + /// Set the the all option for the kind +void HLSLToVulkanLayoutOptions::setAllShift(Kind kind, Index shift) +{ + // We try to follow the convention, of the *last* entry set is the one used. + // If there a "all" set, we remove everything for the kind. + + // Find all the entries for the kind + List keys; + for (auto& pair : m_shifts) + { + if (pair.key.kind == kind) + { + keys.add(pair.key); + } + } + // Remove them all + for (auto& key : keys) + { + m_shifts.remove(key); + } + + m_allShifts[Index(kind)] = shift; +} + +void HLSLToVulkanLayoutOptions::setShift(Kind kind, Index set, Index shift) +{ + SLANG_ASSERT(shift != kInvalidShift); + + Key key{ kind, set }; + m_shifts.add(key, shift); +} + +Index HLSLToVulkanLayoutOptions::getShift(Kind kind, Index set) const +{ + if (auto ptr = m_shifts.tryGetValue(Key{ kind, set })) + { + return *ptr; + } + + return m_allShifts[Index(kind)]; +} + +bool HLSLToVulkanLayoutOptions::isDefault() const +{ + // If any all shift is set it's not default + for (auto shift : m_allShifts) + { + if (shift != kInvalidShift) + { + return false; + } + } + + // If any has a non zero shift, it's not default + for (auto& pair : m_shifts) + { + // We need a value that is non zero... + if (pair.value) + { + return false; + } + } + + // If either has been set it's not default + return m_globalsBinding < 0 && m_globalsBindingSet < 0; +} + +/* static */HLSLToVulkanLayoutOptions::Kind HLSLToVulkanLayoutOptions::getKind(slang::ParameterCategory param) +{ + typedef slang::ParameterCategory ParameterCategory; + + switch (param) + { + case ParameterCategory::Mixed: + { + // TODO(JS): + // Hmm, is this TextureSampler? + return Kind::Invalid; + } + case ParameterCategory::Uniform: + case ParameterCategory::ConstantBuffer: + { + return Kind::Uniform; + } + case ParameterCategory::ShaderResource: return Kind::Texture; + case ParameterCategory::UnorderedAccess: return Kind::Buffer; + case ParameterCategory::SamplerState: return Kind::Sampler; + + default: + { + return Kind::Invalid; + } + } +} + +} // namespace Slang diff --git a/source/slang/slang-hlsl-to-vulkan-layout-options.h b/source/slang/slang-hlsl-to-vulkan-layout-options.h new file mode 100644 index 000000000..9260fe91d --- /dev/null +++ b/source/slang/slang-hlsl-to-vulkan-layout-options.h @@ -0,0 +1,85 @@ +// slang-hlsl-to-vulkan-layout-options.h +#ifndef SLANG_HLSL_TO_VULKAN_LAYOUT_OPTIONS_H +#define SLANG_HLSL_TO_VULKAN_LAYOUT_OPTIONS_H + +#include "../core/slang-basic.h" +#include "../core/slang-name-value.h" + +namespace Slang +{ + +/* +For support features similar to described here.. + +https://github.com/microsoft/DirectXShaderCompiler/blob/main/docs/SPIR-V.rst#descriptors + +Options that allow for infering Vulkan bindings based on HLSL register bindings + */ +struct HLSLToVulkanLayoutOptions : public RefObject +{ +public: + + static const Index kInvalidShift = Index(0x80000000); + + // {b|s|t|u} + enum class Kind + { + Invalid = -1, + + Buffer, ///< Buffer + Sampler, ///< Sampler + Texture, ///< Texture + Uniform, ///< Uniform + + CountOf, + }; + + struct Key + { + typedef Key ThisType; + + bool operator==(const ThisType& rhs) const { return kind == rhs.kind && set == rhs.set; } + bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + + HashCode getHashCode() const { return combineHash(Slang::getHashCode(kind), Slang::getHashCode(set)); } + + Kind kind; ///< The kind this entry is for + Index set; ///< The set this shift is associated with + }; + + /// Set the the all option for the kind + void setAllShift(Kind kind, Index shift); + + /// Set the shift for kind/set + void setShift(Kind kind, Index set, Index shift); + + /// Get the shift. Returns kInvalidShift if no shift is found + Index getShift(Kind kind, Index set) const; + + /// Returns true if contains default information. If so it can in effect be ignored + bool isDefault() const; + + /// True as global binds set + bool hasGlobalsBinding() const { return m_globalsBinding >= 0 && m_globalsBindingSet >= 0; } + + /// Ctor + HLSLToVulkanLayoutOptions(); + + /// Get information about the different kinds + static ConstArrayView getKindInfos(); + + /// Given a paramCategory get the kind. Returns Kind::Invalid if not an applicable category + static Kind getKind(slang::ParameterCategory param); + + Index m_globalsBinding = -1; + Index m_globalsBindingSet = -1; + + Index m_allShifts[Count(Kind::CountOf)]; + + /// Maps a key to the amount of shift + Dictionary m_shifts; +}; + +} // namespace Slang + +#endif diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 353c6e57f..0c788a404 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -19,6 +19,7 @@ #include "slang-repro.h" #include "slang-serialize-ir.h" +#include "slang-hlsl-to-vulkan-layout-options.h" #include "../core/slang-castable.h" #include "../core/slang-file-system.h" @@ -81,6 +82,10 @@ enum class OptionKind LineDirectiveMode, Optimization, Obfuscate, + + VulkanBindShift, + VulkanBindGlobals, + GLSLForceScalarLayout, EnableEffectAnnotations, @@ -160,10 +165,25 @@ enum class ValueCategory OptimizationLevel, DebugLevel, FileSystemType, + VulkanShift, CountOf, }; +template +struct GetValueCategory; + +#define SLANG_GET_VALUE_CATEGORY(cat, type) template <> struct GetValueCategory { enum { Value = Index(ValueCategory::cat) }; }; + +SLANG_GET_VALUE_CATEGORY(Compiler, SlangPassThrough) +SLANG_GET_VALUE_CATEGORY(ArchiveType, SlangArchiveType) +SLANG_GET_VALUE_CATEGORY(LineDirectiveMode, SlangLineDirectiveMode) +SLANG_GET_VALUE_CATEGORY(FloatingPointMode, FloatingPointMode) +SLANG_GET_VALUE_CATEGORY(FileSystemType, TypeTextUtil::FileSystemType) +SLANG_GET_VALUE_CATEGORY(HelpStyle, CommandOptionsWriter::Style) +SLANG_GET_VALUE_CATEGORY(OptimizationLevel, SlangOptimizationLevel) +SLANG_GET_VALUE_CATEGORY(VulkanShift, HLSLToVulkanLayoutOptions::Kind) + } // anonymous static void _addOptions(const ConstArrayView