From be2835501915861c316697eb41fbfa077faa6768 Mon Sep 17 00:00:00 2001 From: steve-lunarg <steve_gh@khasekhemwy.net> Date: Tue, 18 Apr 2017 12:18:01 -0600 Subject: [PATCH] WIP: HLSL: hlsl register class iomapping Adds --hlsl-iomap option to perform IO mapping in HLSL register space. --shift-cbuffer-binding is now a synonym for --shift-ubo-binding. The idea way to do this seems to be passing in a dedicated IO resolver, but that would require more intrusive restructuring, so maybe best for its own PR. The TDefaultHlslIoResolver class and the former TDefaultIoResolver class share quite a bit of mechanism in a common base class. TODO: tbuffers are landing in the wrong register class, which needs some investigation. They're either wrong upstream, or the detection in the resolver is wrong. --- StandAlone/StandAlone.cpp | 26 +- Test/baseResults/hlsl.automap.frag.out | 27 ++ Test/hlsl.automap.frag | 57 ++++ Test/runtests | 3 +- glslang/MachineIndependent/ShaderLang.cpp | 3 + glslang/MachineIndependent/iomapper.cpp | 270 +++++++++++++----- .../MachineIndependent/localintermediate.h | 10 +- glslang/Public/ShaderLang.h | 3 + 8 files changed, 319 insertions(+), 80 deletions(-) create mode 100644 Test/baseResults/hlsl.automap.frag.out create mode 100644 Test/hlsl.automap.frag diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 60dbc4dae..3faadecfc 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -87,6 +87,7 @@ enum TOptions { EOptionNoStorageFormat = (1 << 21), EOptionKeepUncalled = (1 << 22), EOptionHlslOffsets = (1 << 23), + EOptionHlslIoMapping = (1 << 24), }; // @@ -166,6 +167,7 @@ std::array<unsigned int, EShLangCount> baseTextureBinding; std::array<unsigned int, EShLangCount> baseImageBinding; std::array<unsigned int, EShLangCount> baseUboBinding; std::array<unsigned int, EShLangCount> baseSsboBinding; +std::array<unsigned int, EShLangCount> baseUavBinding; // // Create the default name for saving a binary if -o is not provided. @@ -256,6 +258,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem baseImageBinding.fill(0); baseUboBinding.fill(0); baseSsboBinding.fill(0); + baseUavBinding.fill(0); ExecutableName = argv[0]; workItems.reserve(argc); @@ -285,12 +288,19 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem ProcessBindingBase(argc, argv, baseImageBinding); } else if (lowerword == "shift-ubo-bindings" || // synonyms lowerword == "shift-ubo-binding" || - lowerword == "sub") { + lowerword == "shift-cbuffer-bindings" || + lowerword == "shift-cbuffer-binding" || + lowerword == "sub" || + lowerword == "scb") { ProcessBindingBase(argc, argv, baseUboBinding); } else if (lowerword == "shift-ssbo-bindings" || // synonyms lowerword == "shift-ssbo-binding" || lowerword == "sbb") { ProcessBindingBase(argc, argv, baseSsboBinding); + } else if (lowerword == "shift-uav-bindings" || // synonyms + lowerword == "shift-uav-binding" || + lowerword == "suavb") { + ProcessBindingBase(argc, argv, baseUavBinding); } else if (lowerword == "auto-map-bindings" || // synonyms lowerword == "auto-map-binding" || lowerword == "amb") { @@ -326,6 +336,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem Options |= EOptionKeepUncalled; } else if (lowerword == "hlsl-offsets") { Options |= EOptionHlslOffsets; + } else if (lowerword == "hlsl-iomap" || + lowerword == "hlsl-iomapper" || + lowerword == "hlsl-iomapping") { + Options |= EOptionHlslIoMapping; } else { usage(); } @@ -577,9 +591,13 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits) shader->setShiftImageBinding(baseImageBinding[compUnit.stage]); shader->setShiftUboBinding(baseUboBinding[compUnit.stage]); shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]); + shader->setShiftUavBinding(baseUavBinding[compUnit.stage]); shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0); shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0); + if (Options & EOptionHlslIoMapping) + shader->setHlslIoMapping(true); + if (Options & EOptionAutoMapBindings) shader->setAutoMapBindings(true); @@ -982,11 +1000,15 @@ void usage() " --sib [stage] num synonym for --shift-image-binding\n" "\n" " --shift-UBO-binding [stage] num set base binding number for UBOs\n" + " --shift-cbuffer-binding [stage] num synonym for --shift-UBO-binding\n" " --sub [stage] num synonym for --shift-UBO-binding\n" "\n" " --shift-ssbo-binding [stage] num set base binding number for SSBOs\n" " --sbb [stage] num synonym for --shift-ssbo-binding\n" "\n" + " --shift-uav-binding [stage] num set base binding number for UAVs\n" + " --suavb [stage] num synonym for --shift-uav-binding\n" + "\n" " --auto-map-bindings automatically bind uniform variables without\n" " explicit bindings.\n" " --amb synonym for --auto-map-bindings\n" @@ -1009,6 +1031,8 @@ void usage() "\n" " --hlsl-offsets Allow block offsets to follow HLSL rules instead of GLSL rules.\n" " Works independently of source language.\n" + "\n" + " --hlsl-iomap Perform IO mapping in HLSL register space.\n" ); exit(EFailUsage); diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out new file mode 100644 index 000000000..ca7d285be --- /dev/null +++ b/Test/baseResults/hlsl.automap.frag.out @@ -0,0 +1,27 @@ +hlsl.automap.frag +Uniform reflection: +t1: offset -1, type 8b5d, size 1, index -1, binding 11 +t2: offset -1, type 8b5e, size 1, index -1, binding 12 +t3: offset -1, type 8b5f, size 1, index -1, binding 13 +t4.@data: offset 0, type 8b52, size 1, index 0, binding -1 +t5.@data: offset 0, type 1405, size 0, index 1, binding -1 +t6: offset -1, type 8dc2, size 1, index -1, binding 16 +s1: offset -1, type 0, size 1, index -1, binding 31 +s2: offset -1, type 0, size 1, index -1, binding 32 +u1: offset -1, type 904c, size 1, index -1, binding 41 +u2: offset -1, type 904d, size 1, index -1, binding 42 +u3: offset -1, type 904e, size 1, index -1, binding 43 +u4: offset -1, type 9051, size 1, index -1, binding 44 +u5.@data: offset 0, type 1405, size 0, index 2, binding -1 +u6.@data: offset 0, type 1406, size 1, index 3, binding -1 +cb1: offset 0, type 1404, size 1, index 4, binding -1 + +Uniform block reflection: +t4: offset -1, type ffffffff, size 0, index -1, binding 14 +t5: offset -1, type ffffffff, size 0, index -1, binding 15 +u5: offset -1, type ffffffff, size 0, index -1, binding 45 +u6: offset -1, type ffffffff, size 0, index -1, binding 46 +cb: offset -1, type ffffffff, size 4, index -1, binding 51 + +Vertex attribute reflection: + diff --git a/Test/hlsl.automap.frag b/Test/hlsl.automap.frag new file mode 100644 index 000000000..fbb454518 --- /dev/null +++ b/Test/hlsl.automap.frag @@ -0,0 +1,57 @@ +// Test register class offsets for different resource types + +SamplerState s1 : register(s1); +SamplerComparisonState s2 : register(s2); + +Texture1D <float4> t1 : register(t1); +Texture2D <float4> t2 : register(t2); +Texture3D <float4> t3 : register(t3); +StructuredBuffer<float4> t4 : register(t4); +ByteAddressBuffer t5 : register(t5); +Buffer<float4> t6 : register(t6); + +RWTexture1D <float4> u1 : register(u1); +RWTexture2D <float4> u2 : register(u2); +RWTexture3D <float4> u3 : register(u3); + +RWBuffer <float> u4 : register(u4); +RWByteAddressBuffer u5 : register(u5); +RWStructuredBuffer<float> u6 : register(u6); +AppendStructuredBuffer<float> u7 : register(u7); +ConsumeStructuredBuffer<float> u8 : register(u8); + +cbuffer cb : register(b1) { + int cb1; +}; + +// tbuffer tb : register(t7) { +// int tb1; +// }; + +float4 main() : SV_Target0 +{ + t1; + t2; + t3; + t4[0]; + t5.Load(0); + t6; + + s1; + s2; + + u1; + u2; + u3; + + u4[0]; + u5.Load(0); + u6[0]; + u7[0]; + u8[0]; + + cb1; + // tb1; TODO: wrong type? + + return 0; +} diff --git a/Test/runtests b/Test/runtests index efc449d9b..176e73ff6 100755 --- a/Test/runtests +++ b/Test/runtests @@ -35,7 +35,8 @@ $EXE -D -e flizv -l -q -C -V hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.v diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1 $EXE -D -e main -l -q -C -V hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out diff -b $BASEDIR/hlsl.reflection.binding.frag.out $TARGETDIR/hlsl.reflection.binding.frag.out || HASERROR=1 - +$EXE -D -e main -l -q --hlsl-iomap --auto-map-bindings --stb 10 --sbb 20 --ssb 30 --suavb 40 --scb 50 -D -V -e main hlsl.automap.frag > $TARGETDIR/hlsl.automap.frag.out +diff -b $BASEDIR/hlsl.automap.frag.out $TARGETDIR/hlsl.automap.frag.out || HASERROR=1 # # multi-threaded test diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 95c16e802..992038338 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1559,8 +1559,11 @@ void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShift void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); } void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); } void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); } +void TShader::setShiftCbufferBinding(unsigned int base) { intermediate->setShiftUboBinding(base); } +void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShiftUavBinding(base); } void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); } void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } +void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); } void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); } void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 9a6613e24..355cc428e 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -1,5 +1,5 @@ // -// Copyright (C) 2016 LunarG, Inc. +// Copyright (C) 2016-2017 LunarG, Inc. // // All rights reserved. // @@ -310,20 +310,15 @@ private: TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&); }; -/* - * Basic implementation of glslang::TIoMapResolver that replaces the - * previous offset behavior. - * It does the same, uses the offsets for the corresponding uniform - * types. Also respects the EOptionAutoMapBindings flag and binds - * them if needed. - */ -struct TDefaultIoResolver : public glslang::TIoMapResolver +// Base class for shared TIoMapResolver services, used by several derivations. +struct TDefaultIoResolverBase : public glslang::TIoMapResolver { int baseSamplerBinding; int baseTextureBinding; int baseImageBinding; int baseUboBinding; int baseSsboBinding; + int baseUavBinding; bool doAutoMapping; typedef std::vector<int> TSlotSet; typedef std::unordered_map<int, TSlotSet> TSlotSetMap; @@ -360,109 +355,218 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver return reserveSlot(set, base); } + virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0; + + virtual int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override = 0; + + int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override + { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + return 0; + } + + bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return true; + } + int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return -1; + } + int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return -1; + } + int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + { + return -1; + } + +protected: + static int getLayoutSet(const glslang::TType& type) { + if (type.getQualifier().hasSet()) + return type.getQualifier().layoutSet; + else + return 0; + } + + static bool isSamplerType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); + } + + static bool isTextureType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isTexture(); + } + + static bool isUboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqUniform; + } +}; + +/* + * Basic implementation of glslang::TIoMapResolver that replaces the + * previous offset behavior. + * It does the same, uses the offsets for the corresponding uniform + * types. Also respects the EOptionAutoMapBindings flag and binds + * them if needed. + */ +/* + * Default resolver + */ +struct TDefaultIoResolver : public TDefaultIoResolverBase +{ bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override { if (type.getQualifier().hasBinding()) { - int set; - if (type.getQualifier().hasSet()) - set = type.getQualifier().layoutSet; - else - set = 0; + const int set = getLayoutSet(type); - if (type.getBasicType() == glslang::EbtSampler) { - const glslang::TSampler& sampler = type.getSampler(); - if (sampler.isPureSampler()) - return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding); + if (isImageType(type)) + return checkEmpty(set, baseImageBinding + type.getQualifier().layoutBinding); - if (sampler.isTexture()) - return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding); - } - - if (type.getQualifier().storage == EvqUniform) - return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding); + if (isTextureType(type)) + return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding); - if (type.getQualifier().storage == EvqBuffer) + if (isSsboType(type)) return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding); + + if (isSamplerType(type)) + return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding); + + if (isUboType(type)) + return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding); } return true; } int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override { - int set; - if (type.getQualifier().hasSet()) - set = type.getQualifier().layoutSet; - else - set = 0; + const int set = getLayoutSet(type); if (type.getQualifier().hasBinding()) { - if (type.getBasicType() == glslang::EbtSampler) { - const glslang::TSampler& sampler = type.getSampler(); - if (sampler.isImage()) - return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding); + if (isImageType(type)) + return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding); + + if (isTextureType(type)) + return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding); - if (sampler.isPureSampler()) - return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding); + if (isSsboType(type)) + return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding); - if (sampler.isTexture()) - return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding); - } + if (isSamplerType(type)) + return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding); - if (type.getQualifier().storage == EvqUniform) + if (isUboType(type)) return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding); - - if (type.getQualifier().storage == EvqBuffer) - return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding); } else if (is_live && doAutoMapping) { // find free slot, the caller did make sure it passes all vars with binding // first and now all are passed that do not have a binding and needs one - if (type.getBasicType() == glslang::EbtSampler) { - const glslang::TSampler& sampler = type.getSampler(); - if (sampler.isImage()) - return getFreeSlot(set, baseImageBinding); - - if (sampler.isPureSampler()) - return getFreeSlot(set, baseSamplerBinding); - if (sampler.isTexture()) - return getFreeSlot(set, baseTextureBinding); - } + if (isImageType(type)) + return getFreeSlot(set, baseImageBinding); - if (type.getQualifier().storage == EvqUniform) - return getFreeSlot(set, baseUboBinding); + if (isTextureType(type)) + return getFreeSlot(set, baseTextureBinding); - if (type.getQualifier().storage == EvqBuffer) + if (isSsboType(type)) return getFreeSlot(set, baseSsboBinding); + + if (isSamplerType(type)) + return getFreeSlot(set, baseSamplerBinding); + + if (isUboType(type)) + return getFreeSlot(set, baseUboBinding); } return -1; } - int resolveSet(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override - { - if (type.getQualifier().hasSet()) - return type.getQualifier().layoutSet; - return 0; +protected: + static bool isImageType(const glslang::TType& type) { + return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); } - bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + static bool isSsboType(const glslang::TType& type) { + return type.getQualifier().storage == EvqBuffer; + } +}; + +struct TDefaultHlslIoResolver : public TDefaultIoResolverBase +{ + bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override { + if (type.getQualifier().hasBinding()) { + const int set = getLayoutSet(type); + + // Use Uav binding if requested: else will pass through to old behavior + if (isUavType(type)) + return checkEmpty(set, baseUavBinding + type.getQualifier().layoutBinding); + + if (isSrvType(type)) + return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding); + + if (isSamplerType(type)) + return checkEmpty(set, baseSamplerBinding + type.getQualifier().layoutBinding); + + if (isUboType(type)) + return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding); + } return true; } - int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override + + int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override { + const int set = getLayoutSet(type); + + if (type.getQualifier().hasBinding()) { + if (isUavType(type)) + return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding); + + if (isSrvType(type)) + return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding); + + if (isSamplerType(type)) + return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding); + + if (isUboType(type)) + return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding); + } else if (is_live && doAutoMapping) { + // find free slot, the caller did make sure it passes all vars with binding + // first and now all are passed that do not have a binding and needs one + + if (isUavType(type)) + return getFreeSlot(set, baseUavBinding); + + if (isSrvType(type)) + return getFreeSlot(set, baseTextureBinding); + + if (isSamplerType(type)) + return getFreeSlot(set, baseSamplerBinding); + + if (isUboType(type)) + return getFreeSlot(set, baseUboBinding); + } + return -1; } - int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override - { - return -1; + +protected: + // Return true if this is a SRV (shader resource view) type: + static bool isSrvType(const glslang::TType& type) { + return isTextureType(type) || type.getQualifier().storage == EvqBuffer; } - int resolveInOutIndex(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override - { - return -1; + + // Return true if this is a UAV (unordered access view) type: + static bool isUavType(const glslang::TType& type) { + if (type.getQualifier().readonly) + return false; + + return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || + (type.getQualifier().storage == EvqBuffer); } }; + // Map I/O variables to provided offsets, and make bindings for // unbound but live variables. // @@ -475,6 +579,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi intermediate.getShiftImageBinding() == 0 && intermediate.getShiftUboBinding() == 0 && intermediate.getShiftSsboBinding() == 0 && + intermediate.getShiftUavBinding() == 0 && intermediate.getAutoMapBindings() == false && resolver == nullptr) return true; @@ -488,15 +593,26 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi // if no resolver is provided, use the default resolver with the given shifts and auto map settings TDefaultIoResolver defaultResolver; + TDefaultHlslIoResolver defaultHlslResolver; + if (resolver == nullptr) { - defaultResolver.baseSamplerBinding = intermediate.getShiftSamplerBinding(); - defaultResolver.baseTextureBinding = intermediate.getShiftTextureBinding(); - defaultResolver.baseImageBinding = intermediate.getShiftImageBinding(); - defaultResolver.baseUboBinding = intermediate.getShiftUboBinding(); - defaultResolver.baseSsboBinding = intermediate.getShiftSsboBinding(); - defaultResolver.doAutoMapping = intermediate.getAutoMapBindings(); - - resolver = &defaultResolver; + TDefaultIoResolverBase* resolverBase; + + // TODO: use a passed in IO mapper for this + if (intermediate.usingHlslIoMapping()) + resolverBase = &defaultHlslResolver; + else + resolverBase = &defaultResolver; + + resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding(); + resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding(); + resolverBase->baseImageBinding = intermediate.getShiftImageBinding(); + resolverBase->baseUboBinding = intermediate.getShiftUboBinding(); + resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding(); + resolverBase->baseUavBinding = intermediate.getShiftUavBinding(); + resolverBase->doAutoMapping = intermediate.getAutoMapBindings(); + + resolver = resolverBase; } TVarLiveMap inVarMap, outVarMap, uniformVarMap; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 0bd9d161f..2fd2e9fd3 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -175,11 +175,13 @@ public: shiftImageBinding(0), shiftUboBinding(0), shiftSsboBinding(0), + shiftUavBinding(0), autoMapBindings(false), flattenUniformArrays(false), useUnknownFormat(false), hlslOffsets(false), - useStorageBuffer(false) + useStorageBuffer(false), + hlslIoMapping(false) { localSize[0] = 1; localSize[1] = 1; @@ -212,6 +214,8 @@ public: unsigned int getShiftUboBinding() const { return shiftUboBinding; } void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; } unsigned int getShiftSsboBinding() const { return shiftSsboBinding; } + void setShiftUavBinding(unsigned int shift) { shiftUavBinding = shift; } + unsigned int getShiftUavBinding() const { return shiftUavBinding; } void setAutoMapBindings(bool map) { autoMapBindings = map; } bool getAutoMapBindings() const { return autoMapBindings; } void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; } @@ -222,6 +226,8 @@ public: bool usingHlslOFfsets() const { return hlslOffsets; } void setUseStorageBuffer() { useStorageBuffer = true; } bool usingStorageBuffer() const { return useStorageBuffer; } + void setHlslIoMapping(bool b) { hlslIoMapping = b; } + bool usingHlslIoMapping() { return hlslIoMapping; } void setVersion(int v) { version = v; } int getVersion() const { return version; } @@ -505,11 +511,13 @@ protected: unsigned int shiftImageBinding; unsigned int shiftUboBinding; unsigned int shiftSsboBinding; + unsigned int shiftUavBinding; bool autoMapBindings; bool flattenUniformArrays; bool useUnknownFormat; bool hlslOffsets; bool useStorageBuffer; + bool hlslIoMapping; typedef std::list<TCall> TGraph; TGraph callGraph; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index e5e50508e..432329ce0 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -303,8 +303,11 @@ public: void setShiftTextureBinding(unsigned int base); void setShiftImageBinding(unsigned int base); void setShiftUboBinding(unsigned int base); + void setShiftUavBinding(unsigned int base); + void setShiftCbufferBinding(unsigned int base); // synonym for setShiftUboBinding void setShiftSsboBinding(unsigned int base); void setAutoMapBindings(bool map); + void setHlslIoMapping(bool hlslIoMap); void setFlattenUniformArrays(bool flatten); void setNoStorageFormat(bool useUnknownFormat); -- GitLab