diff options
author | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2022-04-19 22:19:28 +0000 |
---|---|---|
committer | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2022-04-19 22:19:28 +0000 |
commit | 6fb0b00ad2e695a76dd900cd0d025a6509056613 (patch) | |
tree | b21d2eac62fed2ab6fe4f85a30cfbf0c36248db7 | |
parent | 345b350a2a729a37d0bd18d9a7cdbe91d86a23ee (diff) | |
parent | 55c21842b20406d02ce5181921b3100749c03b9a (diff) | |
download | angle-6fb0b00ad2e695a76dd900cd0d025a6509056613.tar.gz |
Roll ANGLE from cfc92ebf1f1e to 55c21842b204 (3 revisions)
https://chromium.googlesource.com/angle/angle.git/+log/cfc92ebf1f1e..55c21842b204
Please enable autosubmit on changes if possible when approving them.
If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/angle-android-autoroll
Please CC ianelliott@google.com on the revert to ensure that a human
is aware of the problem.
To file a bug in ANGLE: https://bugs.chromium.org/p/angleproject/issues/entry
To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug
Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Test: Presubmit checks will test this change.
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
Change-Id: Ie328f7c5bf83f6b501440c4e67750218ee699ec6
-rw-r--r-- | src/libANGLE/State.cpp | 2 | ||||
-rw-r--r-- | src/libANGLE/angletypes.cpp | 16 | ||||
-rw-r--r-- | src/libANGLE/angletypes.h | 10 | ||||
-rw-r--r-- | src/libANGLE/angletypes_unittest.cpp | 17 | ||||
-rw-r--r-- | src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp | 116 | ||||
-rw-r--r-- | src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h | 154 | ||||
-rw-r--r-- | src/libANGLE/renderer/d3d/DynamicHLSL.cpp | 7 | ||||
-rw-r--r-- | src/libANGLE/renderer/d3d/DynamicHLSL.h | 3 | ||||
-rw-r--r-- | src/libANGLE/renderer/d3d/ProgramD3D.cpp | 5 | ||||
-rw-r--r-- | src/libANGLE/renderer/d3d/ProgramD3D.h | 1 | ||||
-rw-r--r-- | src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp | 2 | ||||
-rw-r--r-- | src/libANGLE/renderer/glslang_wrapper_utils.cpp | 70 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp | 120 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/ProgramExecutableVk.h | 6 | ||||
-rw-r--r-- | src/tests/gl_tests/StateChangeTest.cpp | 108 |
15 files changed, 402 insertions, 235 deletions
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp index 383bf7ce44..daee4f0f77 100644 --- a/src/libANGLE/State.cpp +++ b/src/libANGLE/State.cpp @@ -799,7 +799,7 @@ bool State::anyActiveDrawBufferChannelMasked() const { // Compare current color mask with all-enabled color mask, while ignoring disabled draw // buffers. - return (mBlendStateExt.compareColorMask(mBlendStateExt.mMaxColorMask) & + return (mBlendStateExt.compareColorMask(mBlendStateExt.mAllColorMask) & mDrawFramebuffer->getDrawBufferMask()) .any(); } diff --git a/src/libANGLE/angletypes.cpp b/src/libANGLE/angletypes.cpp index 9076160958..6294e16ce9 100644 --- a/src/libANGLE/angletypes.cpp +++ b/src/libANGLE/angletypes.cpp @@ -355,16 +355,20 @@ BlendStateExt::BlendStateExt(const size_t drawBuffers) mMaxEquationMask(EquationStorage::GetMask(drawBuffers)), mEquationColor(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mMaxEquationMask)), mEquationAlpha(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mMaxEquationMask)), - mMaxColorMask(ColorMaskStorage::GetMask(drawBuffers)), - mColorMask(ColorMaskStorage::GetReplicatedValue(PackColorMask(true, true, true, true), - mMaxColorMask)), + mAllColorMask(ColorMaskStorage::GetReplicatedValue(PackColorMask(true, true, true, true), + ColorMaskStorage::GetMask(drawBuffers))), + mColorMask(mAllColorMask), mMaxEnabledMask(0xFF >> (8 - drawBuffers)), mMaxDrawBuffers(drawBuffers) {} BlendStateExt::BlendStateExt(const BlendStateExt &other) = default; -BlendStateExt &BlendStateExt::operator=(const BlendStateExt &other) = default; +BlendStateExt &BlendStateExt::operator=(const BlendStateExt &other) +{ + memcpy(this, &other, sizeof(BlendStateExt)); + return *this; +} void BlendStateExt::setEnabled(const bool enabled) { @@ -383,14 +387,14 @@ BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskValue(const const bool alpha) const { return BlendStateExt::ColorMaskStorage::GetReplicatedValue( - PackColorMask(red, green, blue, alpha), mMaxColorMask); + PackColorMask(red, green, blue, alpha), mAllColorMask); } BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskIndexed( const size_t index) const { return ColorMaskStorage::GetReplicatedValue( - ColorMaskStorage::GetValueIndexed(index, mColorMask), mMaxColorMask); + ColorMaskStorage::GetValueIndexed(index, mColorMask), mAllColorMask); } void BlendStateExt::setColorMask(const bool red, diff --git a/src/libANGLE/angletypes.h b/src/libANGLE/angletypes.h index a890f5c24a..886afb140f 100644 --- a/src/libANGLE/angletypes.h +++ b/src/libANGLE/angletypes.h @@ -706,25 +706,25 @@ class BlendStateExt final ///////// Data Members ///////// - FactorStorage::Type mMaxFactorMask; + const FactorStorage::Type mMaxFactorMask; FactorStorage::Type mSrcColor; FactorStorage::Type mDstColor; FactorStorage::Type mSrcAlpha; FactorStorage::Type mDstAlpha; - EquationStorage::Type mMaxEquationMask; + const EquationStorage::Type mMaxEquationMask; EquationStorage::Type mEquationColor; EquationStorage::Type mEquationAlpha; - ColorMaskStorage::Type mMaxColorMask; + const ColorMaskStorage::Type mAllColorMask; ColorMaskStorage::Type mColorMask; - DrawBufferMask mMaxEnabledMask; + const DrawBufferMask mMaxEnabledMask; DrawBufferMask mEnabledMask; // Cache of whether the blend equation for each index is from KHR_blend_equation_advanced. DrawBufferMask mUsesAdvancedBlendEquationMask; - size_t mMaxDrawBuffers; + const size_t mMaxDrawBuffers; }; // Used in StateCache diff --git a/src/libANGLE/angletypes_unittest.cpp b/src/libANGLE/angletypes_unittest.cpp index de3bf083da..27e5ea9476 100644 --- a/src/libANGLE/angletypes_unittest.cpp +++ b/src/libANGLE/angletypes_unittest.cpp @@ -49,7 +49,7 @@ TEST(BlendStateExt, Init) const gl::BlendStateExt blendStateExt = gl::BlendStateExt(1); ASSERT_EQ(blendStateExt.mMaxDrawBuffers, 1u); ASSERT_EQ(blendStateExt.mMaxEnabledMask.to_ulong(), 1u); - ASSERT_EQ(blendStateExt.mMaxColorMask, is64Bit ? 0xFFu : 0xFu); + ASSERT_EQ(blendStateExt.mAllColorMask, 0xFu); ASSERT_EQ(blendStateExt.mMaxEquationMask, 0xFFu); ASSERT_EQ(blendStateExt.mMaxFactorMask, 0xFFu); checkInitState(blendStateExt); @@ -59,7 +59,7 @@ TEST(BlendStateExt, Init) const gl::BlendStateExt blendStateExt = gl::BlendStateExt(4); ASSERT_EQ(blendStateExt.mMaxDrawBuffers, 4u); ASSERT_EQ(blendStateExt.mMaxEnabledMask.to_ulong(), 0xFu); - ASSERT_EQ(blendStateExt.mMaxColorMask, is64Bit ? 0xFFFFFFFFu : 0xFFFFu); + ASSERT_EQ(blendStateExt.mAllColorMask, is64Bit ? 0x0F0F0F0Fu : 0xFFFFu); ASSERT_EQ(blendStateExt.mMaxEquationMask, 0xFFFFFFFFu); ASSERT_EQ(blendStateExt.mMaxFactorMask, 0xFFFFFFFFu); checkInitState(blendStateExt); @@ -69,7 +69,7 @@ TEST(BlendStateExt, Init) const gl::BlendStateExt blendStateExt = gl::BlendStateExt(8); ASSERT_EQ(blendStateExt.mMaxDrawBuffers, 8u); ASSERT_EQ(blendStateExt.mMaxEnabledMask.to_ulong(), 0xFFu); - ASSERT_EQ(blendStateExt.mMaxColorMask, is64Bit ? 0xFFFFFFFFFFFFFFFFu : 0xFFFFFFFFu); + ASSERT_EQ(blendStateExt.mAllColorMask, is64Bit ? 0x0F0F0F0F0F0F0F0Fu : 0xFFFFFFFFu); ASSERT_EQ(blendStateExt.mMaxEquationMask, 0xFFFFFFFFFFFFFFFFu); ASSERT_EQ(blendStateExt.mMaxFactorMask, 0xFFFFFFFFFFFFFFFFu); checkInitState(blendStateExt); @@ -120,6 +120,17 @@ TEST(BlendStateExt, ColorMask) ASSERT_EQ(diff.to_ulong(), 23u); } +// Test that all-enabled color mask correctly compares with the current color mask +TEST(BlendStateExt, MaxColorMask) +{ + gl::BlendStateExt blendStateExt = gl::BlendStateExt(4); + + blendStateExt.setColorMaskIndexed(2, true, false, true, false); + + const gl::DrawBufferMask diff = blendStateExt.compareColorMask(blendStateExt.mAllColorMask); + ASSERT_EQ(diff.to_ulong(), 4u); +} + // Test blend equations manipulations TEST(BlendStateExt, BlendEquations) { diff --git a/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp b/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp index 88ad6503de..ae040dfc19 100644 --- a/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp +++ b/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp @@ -22,22 +22,23 @@ void ShaderInterfaceVariableInfoMap::clear() { for (gl::ShaderType shaderType : gl::AllShaderTypes()) { - for (VariableNameToInfoMap &typeMap : mData[shaderType]) + for (ShaderVariableType variableType : angle::AllEnums<ShaderVariableType>()) { - typeMap.clear(); + mData[shaderType][variableType].clear(); + mIndexedResourceIndexMap[shaderType][variableType].clear(); } - mNameToTypeMap[shaderType].clear(); + mNameToTypeAndIndexMap[shaderType].clear(); } } -const ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::get( - gl::ShaderType shaderType, - ShaderVariableType variableType, - const std::string &variableName) const +void ShaderInterfaceVariableInfoMap::load( + const gl::ShaderMap<VariableTypeToInfoMap> &data, + const gl::ShaderMap<NameToTypeAndIndexMap> &nameToTypeAndIndexMap, + const gl::ShaderMap<VariableTypeToIndexMap> &indexedResourceIndexMap) { - auto it = mData[shaderType][variableType].find(variableName); - ASSERT(it != mData[shaderType][variableType].end()); - return it->second; + mData = data; + mNameToTypeAndIndexMap = nameToTypeAndIndexMap; + mIndexedResourceIndexMap = indexedResourceIndexMap; } void ShaderInterfaceVariableInfoMap::setActiveStages(gl::ShaderType shaderType, @@ -45,9 +46,9 @@ void ShaderInterfaceVariableInfoMap::setActiveStages(gl::ShaderType shaderType, const std::string &variableName, gl::ShaderBitSet activeStages) { - auto it = mData[shaderType][variableType].find(variableName); - ASSERT(it != mData[shaderType][variableType].end()); - it->second.activeStages = activeStages; + ASSERT(hasVariable(shaderType, variableName)); + uint32_t index = mNameToTypeAndIndexMap[shaderType][variableName].index; + mData[shaderType][variableType][index].activeStages = activeStages; } ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::getMutable( @@ -55,9 +56,9 @@ ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::getMutable( ShaderVariableType variableType, const std::string &variableName) { - auto it = mData[shaderType][variableType].find(variableName); - ASSERT(it != mData[shaderType][variableType].end()); - return it->second; + ASSERT(hasVariable(shaderType, variableName)); + uint32_t index = mNameToTypeAndIndexMap[shaderType][variableName].index; + return mData[shaderType][variableType][index]; } void ShaderInterfaceVariableInfoMap::markAsDuplicate(gl::ShaderType shaderType, @@ -65,7 +66,8 @@ void ShaderInterfaceVariableInfoMap::markAsDuplicate(gl::ShaderType shaderType, const std::string &variableName) { ASSERT(hasVariable(shaderType, variableName)); - mData[shaderType][variableType][variableName].isDuplicate = true; + uint32_t index = mNameToTypeAndIndexMap[shaderType][variableName].index; + mData[shaderType][variableType][index].isDuplicate = true; } ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::add(gl::ShaderType shaderType, @@ -73,8 +75,10 @@ ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::add(gl::ShaderType const std::string &variableName) { ASSERT(!hasVariable(shaderType, variableName)); - mNameToTypeMap[shaderType][variableName] = variableType; - return mData[shaderType][variableType][variableName]; + uint32_t index = static_cast<uint32_t>(mData[shaderType][variableType].size()); + mNameToTypeAndIndexMap[shaderType][variableName] = {variableType, index}; + mData[shaderType][variableType].resize(index + 1); + return mData[shaderType][variableType][index]; } ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::addOrGet( @@ -82,32 +86,32 @@ ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::addOrGet( ShaderVariableType variableType, const std::string &variableName) { - mNameToTypeMap[shaderType][variableName] = variableType; - return mData[shaderType][variableType][variableName]; -} - -ShaderInterfaceVariableInfoMap::Iterator ShaderInterfaceVariableInfoMap::getIterator( - gl::ShaderType shaderType, - ShaderVariableType variableType) const -{ - return Iterator(mData[shaderType][variableType].begin(), mData[shaderType][variableType].end()); + if (!hasVariable(shaderType, variableName)) + { + return add(shaderType, variableType, variableName); + } + else + { + uint32_t index = mNameToTypeAndIndexMap[shaderType][variableName].index; + return mData[shaderType][variableType][index]; + } } bool ShaderInterfaceVariableInfoMap::hasVariable(gl::ShaderType shaderType, const std::string &variableName) const { - auto iter = mNameToTypeMap[shaderType].find(variableName); - return (iter != mNameToTypeMap[shaderType].end()); + auto iter = mNameToTypeAndIndexMap[shaderType].find(variableName); + return (iter != mNameToTypeAndIndexMap[shaderType].end()); } const ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::getVariableByName( gl::ShaderType shaderType, const std::string &variableName) const { - auto iter = mNameToTypeMap[shaderType].find(variableName); - ASSERT(iter != mNameToTypeMap[shaderType].end()); - ShaderVariableType variableType = iter->second; - return get(shaderType, variableType, variableName); + auto iter = mNameToTypeAndIndexMap[shaderType].find(variableName); + ASSERT(iter != mNameToTypeAndIndexMap[shaderType].end()); + TypeAndIndex typeAndIndex = iter->second; + return mData[shaderType][typeAndIndex.variableType][typeAndIndex.index]; } bool ShaderInterfaceVariableInfoMap::hasTransformFeedbackInfo(gl::ShaderType shaderType, @@ -116,4 +120,48 @@ bool ShaderInterfaceVariableInfoMap::hasTransformFeedbackInfo(gl::ShaderType sha std::string bufferName = rx::GetXfbBufferName(bufferIndex); return hasVariable(shaderType, bufferName); } + +void ShaderInterfaceVariableInfoMap::mapIndexedResourceByName(gl::ShaderType shaderType, + ShaderVariableType variableType, + uint32_t resourceIndex, + const std::string &variableName) +{ + ASSERT(hasVariable(shaderType, variableName)); + const auto &iter = mNameToTypeAndIndexMap[shaderType].find(variableName); + const TypeAndIndex &typeAndIndex = iter->second; + ASSERT(typeAndIndex.variableType == variableType); + mapIndexedResource(shaderType, variableType, resourceIndex, typeAndIndex.index); +} + +void ShaderInterfaceVariableInfoMap::mapIndexedResource(gl::ShaderType shaderType, + ShaderVariableType variableType, + uint32_t resourceIndex, + uint32_t variableIndex) +{ + mIndexedResourceIndexMap[shaderType][variableType][resourceIndex] = variableIndex; +} + +const ShaderInterfaceVariableInfoMap::VariableInfoArray & +ShaderInterfaceVariableInfoMap::getAttributes() const +{ + return mData[gl::ShaderType::Vertex][ShaderVariableType::Attribute]; +} + +const gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToInfoMap> + &ShaderInterfaceVariableInfoMap::getData() const +{ + return mData; +} + +const gl::ShaderMap<ShaderInterfaceVariableInfoMap::NameToTypeAndIndexMap> + &ShaderInterfaceVariableInfoMap::getNameToTypeAndIndexMap() const +{ + return mNameToTypeAndIndexMap; +} + +const gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToIndexMap> + &ShaderInterfaceVariableInfoMap::getIndexedResourceMap() const +{ + return mIndexedResourceIndexMap; +} } // namespace rx diff --git a/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h b/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h index f62e3b81d1..c4541aa366 100644 --- a/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h +++ b/src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h @@ -9,12 +9,15 @@ #ifndef LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_ #define LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_ -#include <functional> - -#include <stdio.h> +#include "common/FastVector.h" #include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/glslang_wrapper_utils.h" #include "libANGLE/renderer/renderer_utils.h" + +#include <functional> + +#include <stdio.h> + namespace rx { @@ -36,15 +39,31 @@ enum class ShaderVariableType EnumCount, }; -// TODO: http://anglebug.com/4524: Need a different hash key than a string, since that's slow to -// calculate. +struct TypeAndIndex +{ + ShaderVariableType variableType; + uint32_t index; +}; + class ShaderInterfaceVariableInfoMap final : angle::NonCopyable { public: + using VariableInfoArray = std::vector<ShaderInterfaceVariableInfo>; + using VariableTypeToInfoMap = angle::PackedEnumMap<ShaderVariableType, VariableInfoArray>; + using NameToTypeAndIndexMap = angle::HashMap<std::string, TypeAndIndex>; + + static constexpr size_t kResourceFastMapMax = 32; + using ResourceIndexMap = angle::FastMap<uint32_t, kResourceFastMapMax>; + using VariableTypeToIndexMap = angle::PackedEnumMap<ShaderVariableType, ResourceIndexMap>; + ShaderInterfaceVariableInfoMap(); ~ShaderInterfaceVariableInfoMap(); void clear(); + void load(const gl::ShaderMap<VariableTypeToInfoMap> &data, + const gl::ShaderMap<NameToTypeAndIndexMap> &nameToTypeAndIndexMap, + const gl::ShaderMap<VariableTypeToIndexMap> &indexedResourceIndexMap); + ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType, ShaderVariableType variableType, const std::string &variableName); @@ -54,10 +73,6 @@ class ShaderInterfaceVariableInfoMap final : angle::NonCopyable ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType, ShaderVariableType variableType, const std::string &variableName); - size_t variableCount(gl::ShaderType shaderType, ShaderVariableType variableType) const - { - return mData[shaderType][variableType].size(); - } void setActiveStages(gl::ShaderType shaderType, ShaderVariableType variableType, @@ -68,104 +83,55 @@ class ShaderInterfaceVariableInfoMap final : angle::NonCopyable const std::string &variableName); const ShaderInterfaceVariableInfo &getDefaultUniformInfo(gl::ShaderType shaderType) const; - const ShaderInterfaceVariableInfo &getIndexedVariableInfo( - const gl::ProgramExecutable &executable, - gl::ShaderType shaderType, - ShaderVariableType variableType, - uint32_t variableIndex) const; + const ShaderInterfaceVariableInfo &getIndexedVariableInfo(gl::ShaderType shaderType, + ShaderVariableType variableType, + uint32_t variableIndex) const; bool hasAtomicCounterInfo(gl::ShaderType shaderType) const; const ShaderInterfaceVariableInfo &getAtomicCounterInfo(gl::ShaderType shaderType) const; - const ShaderInterfaceVariableInfo &getFramebufferFetchInfo( - const gl::ProgramExecutable &executable, - gl::ShaderType shaderType) const; + const ShaderInterfaceVariableInfo &getFramebufferFetchInfo(gl::ShaderType shaderType) const; bool hasTransformFeedbackInfo(gl::ShaderType shaderType, uint32_t bufferIndex) const; const ShaderInterfaceVariableInfo &getTransformFeedbackInfo(gl::ShaderType shaderType, uint32_t bufferIndex) const; - using VariableNameToInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>; - using VariableTypeToInfoMap = angle::PackedEnumMap<ShaderVariableType, VariableNameToInfoMap>; - - class Iterator final - { - public: - Iterator(VariableNameToInfoMap::const_iterator beginIt, - VariableNameToInfoMap::const_iterator endIt) - : mBeginIt(beginIt), mEndIt(endIt) - {} - VariableNameToInfoMap::const_iterator begin() { return mBeginIt; } - VariableNameToInfoMap::const_iterator end() { return mEndIt; } - - private: - VariableNameToInfoMap::const_iterator mBeginIt; - VariableNameToInfoMap::const_iterator mEndIt; - }; - - Iterator getIterator(gl::ShaderType shaderType, ShaderVariableType variableType) const; - bool hasVariable(gl::ShaderType shaderType, const std::string &variableName) const; const ShaderInterfaceVariableInfo &getVariableByName(gl::ShaderType shaderType, const std::string &variableName) const; + void mapIndexedResourceByName(gl::ShaderType shaderType, + ShaderVariableType variableType, + uint32_t resourceIndex, + const std::string &variableName); + void mapIndexedResource(gl::ShaderType shaderType, + ShaderVariableType variableType, + uint32_t resourceIndex, + uint32_t variableIndex); + + const VariableInfoArray &getAttributes() const; + const gl::ShaderMap<VariableTypeToInfoMap> &getData() const; + const gl::ShaderMap<NameToTypeAndIndexMap> &getNameToTypeAndIndexMap() const; + const gl::ShaderMap<VariableTypeToIndexMap> &getIndexedResourceMap() const; private: - const ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, - ShaderVariableType variableType, - const std::string &variableName) const; gl::ShaderMap<VariableTypeToInfoMap> mData; - gl::ShaderMap<angle::HashMap<std::string, ShaderVariableType>> mNameToTypeMap; + gl::ShaderMap<NameToTypeAndIndexMap> mNameToTypeAndIndexMap; + gl::ShaderMap<VariableTypeToIndexMap> mIndexedResourceIndexMap; }; ANGLE_INLINE const ShaderInterfaceVariableInfo & ShaderInterfaceVariableInfoMap::getDefaultUniformInfo(gl::ShaderType shaderType) const { - const char *uniformName = kDefaultUniformNames[shaderType]; - return get(shaderType, ShaderVariableType::DefaultUniform, uniformName); + ASSERT(mData[shaderType][ShaderVariableType::DefaultUniform].size() == 1); + return mData[shaderType][ShaderVariableType::DefaultUniform][0]; } ANGLE_INLINE const ShaderInterfaceVariableInfo & -ShaderInterfaceVariableInfoMap::getIndexedVariableInfo(const gl::ProgramExecutable &executable, - gl::ShaderType shaderType, +ShaderInterfaceVariableInfoMap::getIndexedVariableInfo(gl::ShaderType shaderType, ShaderVariableType variableType, - uint32_t variableIndex) const + uint32_t resourceIndex) const { - switch (variableType) - { - case ShaderVariableType::Image: - { - const std::vector<gl::LinkedUniform> &uniforms = executable.getUniforms(); - uint32_t uniformIndex = executable.getUniformIndexFromImageIndex(variableIndex); - const gl::LinkedUniform &imageUniform = uniforms[uniformIndex]; - const std::string samplerName = GlslangGetMappedSamplerName(imageUniform.name); - return get(shaderType, variableType, samplerName); - } - case ShaderVariableType::ShaderStorageBuffer: - { - const std::vector<gl::InterfaceBlock> &blocks = executable.getShaderStorageBlocks(); - const gl::InterfaceBlock &block = blocks[variableIndex]; - const std::string blockName = block.mappedName; - return get(shaderType, variableType, blockName); - } - case ShaderVariableType::Texture: - { - const std::vector<gl::LinkedUniform> &uniforms = executable.getUniforms(); - uint32_t uniformIndex = executable.getUniformIndexFromSamplerIndex(variableIndex); - const gl::LinkedUniform &samplerUniform = uniforms[uniformIndex]; - const std::string samplerName = GlslangGetMappedSamplerName(samplerUniform.name); - return get(shaderType, variableType, samplerName); - } - case ShaderVariableType::UniformBuffer: - { - const std::vector<gl::InterfaceBlock> &blocks = executable.getUniformBlocks(); - const gl::InterfaceBlock &block = blocks[variableIndex]; - const std::string blockName = block.mappedName; - return get(shaderType, variableType, blockName); - } - - default: - break; - } - - UNREACHABLE(); - return mData[shaderType].begin()->begin()->second; + ASSERT(resourceIndex < mIndexedResourceIndexMap[shaderType][variableType].size()); + uint32_t variableIndex = mIndexedResourceIndexMap[shaderType][variableType][resourceIndex]; + ASSERT(variableIndex < mData[shaderType][variableType].size()); + return mData[shaderType][variableType][variableIndex]; } ANGLE_INLINE bool ShaderInterfaceVariableInfoMap::hasAtomicCounterInfo( @@ -177,27 +143,23 @@ ANGLE_INLINE bool ShaderInterfaceVariableInfoMap::hasAtomicCounterInfo( ANGLE_INLINE const ShaderInterfaceVariableInfo & ShaderInterfaceVariableInfoMap::getAtomicCounterInfo(gl::ShaderType shaderType) const { - std::string blockName(sh::vk::kAtomicCountersBlockName); - return get(shaderType, ShaderVariableType::AtomicCounter, blockName); + ASSERT(mData[shaderType][ShaderVariableType::AtomicCounter].size() == 1); + return mData[shaderType][ShaderVariableType::AtomicCounter][0]; } ANGLE_INLINE const ShaderInterfaceVariableInfo & -ShaderInterfaceVariableInfoMap::getFramebufferFetchInfo(const gl::ProgramExecutable &executable, - gl::ShaderType shaderType) const +ShaderInterfaceVariableInfoMap::getFramebufferFetchInfo(gl::ShaderType shaderType) const { - const std::vector<gl::LinkedUniform> &uniforms = executable.getUniforms(); - const uint32_t baseUniformIndex = executable.getFragmentInoutRange().low(); - const gl::LinkedUniform &baseInputAttachment = uniforms.at(baseUniformIndex); - std::string baseMappedName = baseInputAttachment.mappedName; - return get(shaderType, ShaderVariableType::FramebufferFetch, baseMappedName); + ASSERT(!mData[shaderType][ShaderVariableType::FramebufferFetch].empty()); + return mData[shaderType][ShaderVariableType::FramebufferFetch][0]; } ANGLE_INLINE const ShaderInterfaceVariableInfo & ShaderInterfaceVariableInfoMap::getTransformFeedbackInfo(gl::ShaderType shaderType, uint32_t bufferIndex) const { - const std::string bufferName = GetXfbBufferName(bufferIndex); - return get(shaderType, ShaderVariableType::TransformFeedback, bufferName); + ASSERT(bufferIndex < mData[shaderType][ShaderVariableType::TransformFeedback].size()); + return mData[shaderType][ShaderVariableType::TransformFeedback][bufferIndex]; } } // namespace rx #endif // LIBANGLE_RENDERER_SHADERINTERFACEVARIABLEINFOMAP_H_ diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp index 930e371aec..3257c00457 100644 --- a/src/libANGLE/renderer/d3d/DynamicHLSL.cpp +++ b/src/libANGLE/renderer/d3d/DynamicHLSL.cpp @@ -308,7 +308,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( angle::ReplaceSubstring(&vertexHLSL, VERTEX_ATTRIBUTE_STUB_STRING, structStream.str()); ASSERT(success); - success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &vertexHLSL, inputLayout.size(), + success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &vertexHLSL, baseUAVRegister, gl::ShaderType::Vertex); ASSERT(success); @@ -320,7 +320,8 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( const std::vector<PixelShaderOutputVariable> &outputVariables, bool usesFragDepth, const std::vector<GLenum> &outputLayout, - const std::vector<ShaderStorageBlock> &shaderStorageBlocks) const + const std::vector<ShaderStorageBlock> &shaderStorageBlocks, + size_t baseUAVRegister) const { const int shaderModel = mRenderer->getMajorShaderModel(); std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; @@ -394,7 +395,7 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( angle::ReplaceSubstring(&pixelHLSL, PIXEL_OUTPUT_STUB_STRING, declarationStream.str()); ASSERT(success); - success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &pixelHLSL, numOutputs, + success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &pixelHLSL, baseUAVRegister, gl::ShaderType::Fragment); ASSERT(success); diff --git a/src/libANGLE/renderer/d3d/DynamicHLSL.h b/src/libANGLE/renderer/d3d/DynamicHLSL.h index 4785b7b27a..63b572e27c 100644 --- a/src/libANGLE/renderer/d3d/DynamicHLSL.h +++ b/src/libANGLE/renderer/d3d/DynamicHLSL.h @@ -157,7 +157,8 @@ class DynamicHLSL : angle::NonCopyable const std::vector<PixelShaderOutputVariable> &outputVariables, bool usesFragDepth, const std::vector<GLenum> &outputLayout, - const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks) const; + const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks, + size_t baseUAVRegister) const; std::string generateShaderForImage2DBindSignature( const d3d::Context *context, ProgramD3D &programD3D, diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp index eb57441d9f..c25e355b21 100644 --- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp +++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -1544,7 +1544,8 @@ angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout( std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature( mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth, - mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment]); + mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment], + mPixelShaderKey.size()); // Generate new pixel executable ShaderExecutableD3D *pixelExecutable = nullptr; @@ -1588,7 +1589,7 @@ angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout( // Generate new dynamic layout with attribute conversions std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout( mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getProgramInputs(), - mShaderStorageBlocks[gl::ShaderType::Vertex], getNumPixelShaderOutputs()); + mShaderStorageBlocks[gl::ShaderType::Vertex], mPixelShaderKey.size()); // Generate new vertex executable ShaderExecutableD3D *vertexExecutable = nullptr; diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h index 113b25dd4b..29cb0b062a 100644 --- a/src/libANGLE/renderer/d3d/ProgramD3D.h +++ b/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -357,7 +357,6 @@ class ProgramD3D : public ProgramImpl bool hasNamedUniform(const std::string &name); bool usesVertexID() const { return mUsesVertexID; } - size_t getNumPixelShaderOutputs() const { return mPixelShaderOutputLayoutCache.size(); } private: // These forward-declared tasks are used for multi-thread shader compiles. diff --git a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp index 916de4c979..86068e565f 100644 --- a/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp +++ b/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -841,7 +841,7 @@ void StateManager11::setUnorderedAccessViewInternal(gl::ShaderType shaderType, case gl::ShaderType::Vertex: case gl::ShaderType::Fragment: { - UINT baseUAVRegister = static_cast<UINT>(mProgramD3D->getNumPixelShaderOutputs()); + UINT baseUAVRegister = static_cast<UINT>(mProgramD3D->getPixelShaderKey().size()); deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, baseUAVRegister + resourceSlot, 1, &uavPtr, nullptr); diff --git a/src/libANGLE/renderer/glslang_wrapper_utils.cpp b/src/libANGLE/renderer/glslang_wrapper_utils.cpp index f1fc5dc8f7..d673a44b70 100644 --- a/src/libANGLE/renderer/glslang_wrapper_utils.cpp +++ b/src/libANGLE/renderer/glslang_wrapper_utils.cpp @@ -807,12 +807,13 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options, UniformBindingIndexMap *uniformBindingIndexMapOut, ShaderInterfaceVariableInfoMap *variableInfoMapOut) { - for (const gl::InterfaceBlock &block : blocks) + for (uint32_t blockIndex = 0; blockIndex < blocks.size(); ++blockIndex) { - if (!block.isArray || block.arrayElement == 0) + const gl::InterfaceBlock &block = blocks[blockIndex]; + // TODO: http://anglebug.com/4523: All blocks should be active + if (programExecutable.hasLinkedShaderStage(shaderType) && block.isActive(shaderType)) { - // TODO: http://anglebug.com/4523: All blocks should be active - if (programExecutable.hasLinkedShaderStage(shaderType) && block.isActive(shaderType)) + if (!block.isArray || block.arrayElement == 0) { AddAndUpdateResourceMaps(shaderType, variableType, block.mappedName, &(programInterfaceInfo->currentShaderResourceBindingIndex), @@ -820,6 +821,8 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options, programInterfaceInfo->shaderResourceDescriptorSetIndex, uniformBindingIndexMapOut, variableInfoMapOut); } + variableInfoMapOut->mapIndexedResourceByName(shaderType, variableType, blockIndex, + block.mappedName); } } } @@ -859,11 +862,10 @@ void AssignImageBindings(const GlslangSourceOptions &options, for (unsigned int uniformIndex : imageUniformRange) { const gl::LinkedUniform &imageUniform = uniforms[uniformIndex]; - - std::string name = imageUniform.mappedName; - if (GetImageNameWithoutIndices(&name)) + if (programExecutable.hasLinkedShaderStage(shaderType)) { - if (programExecutable.hasLinkedShaderStage(shaderType)) + std::string name = imageUniform.mappedName; + if (GetImageNameWithoutIndices(&name)) { bool updateFrontShaderType = false; if ((*uniformBindingIndexMapOut).count(name) > 0) @@ -878,6 +880,9 @@ void AssignImageBindings(const GlslangSourceOptions &options, programInterfaceInfo->shaderResourceDescriptorSetIndex, uniformBindingIndexMapOut, variableInfoMapOut); } + uint32_t imageIndex = uniformIndex - imageUniformRange.low(); + variableInfoMapOut->mapIndexedResourceByName(shaderType, ShaderVariableType::Image, + imageIndex, name); } } } @@ -931,26 +936,27 @@ void AssignTextureBindings(const GlslangSourceOptions &options, { const gl::LinkedUniform &samplerUniform = uniforms[uniformIndex]; - if (gl::SamplerNameContainsNonZeroArrayElement(samplerUniform.name)) + // TODO: http://anglebug.com/4523: All uniforms should be active + if (!programExecutable.hasLinkedShaderStage(shaderType) || + !samplerUniform.isActive(shaderType)) { continue; } - if (UniformNameIsIndexZero(samplerUniform.name)) + // Samplers in structs are extracted and renamed. + const std::string samplerName = GlslangGetMappedSamplerName(samplerUniform.name); + if (!gl::SamplerNameContainsNonZeroArrayElement(samplerUniform.name)) { - // Samplers in structs are extracted and renamed. - const std::string samplerName = GlslangGetMappedSamplerName(samplerUniform.name); - - // TODO: http://anglebug.com/4523: All uniforms should be active - if (programExecutable.hasLinkedShaderStage(shaderType) && - samplerUniform.isActive(shaderType)) - { - AddAndUpdateResourceMaps(shaderType, ShaderVariableType::Texture, samplerName, - &(programInterfaceInfo->currentTextureBindingIndex), true, - false, programInterfaceInfo->textureDescriptorSetIndex, - uniformBindingIndexMapOut, variableInfoMapOut); - } + ASSERT(UniformNameIsIndexZero(samplerUniform.name)); + AddAndUpdateResourceMaps(shaderType, ShaderVariableType::Texture, samplerName, + &(programInterfaceInfo->currentTextureBindingIndex), true, + false, programInterfaceInfo->textureDescriptorSetIndex, + uniformBindingIndexMapOut, variableInfoMapOut); } + + uint32_t textureIndex = uniformIndex - programExecutable.getSamplerUniformRange().low(); + variableInfoMapOut->mapIndexedResourceByName(shaderType, ShaderVariableType::Texture, + textureIndex, samplerName); } } @@ -4694,19 +4700,11 @@ bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap { gl::AttributesMask isLocationAssigned; - for (const auto &infoIter : - variableInfoMap.getIterator(gl::ShaderType::Vertex, ShaderVariableType::Attribute)) + for (const ShaderInterfaceVariableInfo &info : variableInfoMap.getAttributes()) { - const ShaderInterfaceVariableInfo &info = infoIter.second; - - // Ignore non attribute ids. - if (info.attributeComponentCount == 0) - { - continue; - } - ASSERT(info.activeStages[gl::ShaderType::Vertex]); ASSERT(info.location != ShaderInterfaceVariableInfo::kInvalid); + ASSERT(info.attributeComponentCount > 0); ASSERT(info.attributeLocationCount > 0); for (uint8_t offset = 0; offset < info.attributeLocationCount; ++offset) @@ -4744,14 +4742,12 @@ bool GetImageNameWithoutIndices(std::string *name) return true; } - if (!UniformNameIsIndexZero(*name)) - { - return false; - } + bool isIndexZero = UniformNameIsIndexZero(*name); // Strip all indices *name = name->substr(0, name->find('[')); - return true; + + return isIndexZero; } std::string GlslangGetMappedSamplerName(const std::string &originalName) diff --git a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp index a192d822f7..671eb696ec 100644 --- a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp +++ b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp @@ -301,19 +301,27 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(ContextVk *contextVk, const gl::ProgramExecutable &glExecutable, gl::BinaryInputStream *stream) { - clearVariableInfoMap(); + gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToInfoMap> data; + gl::ShaderMap<ShaderInterfaceVariableInfoMap::NameToTypeAndIndexMap> nameToTypeAndIndexMap; + gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToIndexMap> indexedResourceMap; for (gl::ShaderType shaderType : gl::AllShaderTypes()) { - for (ShaderVariableType variableType : angle::AllEnums<ShaderVariableType>()) + size_t nameCount = stream->readInt<size_t>(); + for (size_t nameIndex = 0; nameIndex < nameCount; ++nameIndex) { - size_t variableInfoMapSize = stream->readInt<size_t>(); + const std::string variableName = stream->readString(); + ShaderVariableType variableType = stream->readEnum<ShaderVariableType>(); + uint32_t index = stream->readInt<uint32_t>(); + nameToTypeAndIndexMap[shaderType][variableName] = {variableType, index}; + } - for (size_t i = 0; i < variableInfoMapSize; ++i) + for (ShaderVariableType variableType : angle::AllEnums<ShaderVariableType>()) + { + size_t infoArraySize = stream->readInt<size_t>(); + for (size_t infoIndex = 0; infoIndex < infoArraySize; ++infoIndex) { - const std::string variableName = stream->readString(); - ShaderInterfaceVariableInfo &info = - mVariableInfoMap.add(shaderType, variableType, variableName); + ShaderInterfaceVariableInfo info; info.descriptorSet = stream->readInt<uint32_t>(); info.binding = stream->readInt<uint32_t>(); @@ -334,10 +342,21 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(ContextVk *contextVk, info.attributeComponentCount = stream->readInt<uint8_t>(); info.attributeLocationCount = stream->readInt<uint8_t>(); info.isDuplicate = stream->readBool(); + + data[shaderType][variableType].push_back(info); + } + + uint32_t resourceMapSize = stream->readInt<uint32_t>(); + for (uint32_t resourceIndex = 0; resourceIndex < resourceMapSize; ++resourceIndex) + { + uint32_t variableIndex = stream->readInt<uint32_t>(); + indexedResourceMap[shaderType][variableType][resourceIndex] = variableIndex; } } } + mVariableInfoMap.load(data, nameToTypeAndIndexMap, indexedResourceMap); + mOriginalShaderInfo.load(stream); // Deserializes the uniformLayout data of mDefaultUniformBlocks @@ -373,17 +392,33 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(ContextVk *contextVk, void ProgramExecutableVk::save(gl::BinaryOutputStream *stream) { + const gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToInfoMap> &data = + mVariableInfoMap.getData(); + const gl::ShaderMap<ShaderInterfaceVariableInfoMap::NameToTypeAndIndexMap> + &nameToTypeAndIndexMap = mVariableInfoMap.getNameToTypeAndIndexMap(); + const gl::ShaderMap<ShaderInterfaceVariableInfoMap::VariableTypeToIndexMap> + &indexedResourceMap = mVariableInfoMap.getIndexedResourceMap(); + for (gl::ShaderType shaderType : gl::AllShaderTypes()) { + stream->writeInt(nameToTypeAndIndexMap[shaderType].size()); + for (const auto &iter : nameToTypeAndIndexMap[shaderType]) + { + const std::string &name = iter.first; + const TypeAndIndex &typeAndIndex = iter.second; + stream->writeString(name); + stream->writeEnum(typeAndIndex.variableType); + stream->writeInt(typeAndIndex.index); + } + for (ShaderVariableType variableType : angle::AllEnums<ShaderVariableType>()) { - stream->writeInt(mVariableInfoMap.variableCount(shaderType, variableType)); - for (const auto &it : mVariableInfoMap.getIterator(shaderType, variableType)) - { - const std::string &name = it.first; - const ShaderInterfaceVariableInfo &info = it.second; + const ShaderInterfaceVariableInfoMap::VariableInfoArray &infoArray = + data[shaderType][variableType]; - stream->writeString(name); + stream->writeInt(infoArray.size()); + for (const ShaderInterfaceVariableInfo &info : infoArray) + { stream->writeInt(info.descriptorSet); stream->writeInt(info.binding); stream->writeInt(info.location); @@ -404,6 +439,15 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream) stream->writeInt(info.attributeLocationCount); stream->writeBool(info.isDuplicate); } + + const ShaderInterfaceVariableInfoMap::ResourceIndexMap &resourceIndexMap = + indexedResourceMap[shaderType][variableType]; + stream->writeInt(static_cast<uint32_t>(resourceIndexMap.size())); + for (uint32_t resourceIndex = 0; resourceIndex < resourceIndexMap.size(); + ++resourceIndex) + { + stream->writeInt(resourceIndexMap[resourceIndex]); + } } } @@ -538,7 +582,6 @@ angle::Result ProgramExecutableVk::allocateDescriptorSetAndGetInfo( } void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc( - const gl::ProgramExecutable &glExecutable, const std::vector<gl::InterfaceBlock> &blocks, gl::ShaderType shaderType, ShaderVariableType variableType, @@ -556,8 +599,8 @@ void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc( continue; } - const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - glExecutable, shaderType, variableType, bufferIndex); + const ShaderInterfaceVariableInfo &info = + mVariableInfoMap.getIndexedVariableInfo(shaderType, variableType, bufferIndex); if (info.isDuplicate) { continue; @@ -630,7 +673,7 @@ void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable } const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - executable, shaderType, ShaderVariableType::Image, imageIndex); + shaderType, ShaderVariableType::Image, imageIndex); if (info.isDuplicate) { continue; @@ -662,7 +705,7 @@ void ProgramExecutableVk::addInputAttachmentDescriptorSetDesc( } const ShaderInterfaceVariableInfo &baseInfo = - mVariableInfoMap.getFramebufferFetchInfo(executable, shaderType); + mVariableInfoMap.getFramebufferFetchInfo(shaderType); if (baseInfo.isDuplicate) { return; @@ -722,7 +765,7 @@ angle::Result ProgramExecutableVk::addTextureDescriptorSetDesc( } const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - executable, shaderType, ShaderVariableType::Texture, textureIndex); + shaderType, ShaderVariableType::Texture, textureIndex); if (info.isDuplicate) { continue; @@ -1070,11 +1113,11 @@ angle::Result ProgramExecutableVk::createPipelineLayout( for (gl::ShaderType shaderType : linkedShaderStages) { - addInterfaceBlockDescriptorSetDesc(glExecutable, glExecutable.getUniformBlocks(), - shaderType, ShaderVariableType::UniformBuffer, + addInterfaceBlockDescriptorSetDesc(glExecutable.getUniformBlocks(), shaderType, + ShaderVariableType::UniformBuffer, mUniformBufferDescriptorType, &resourcesSetDesc); - addInterfaceBlockDescriptorSetDesc(glExecutable, glExecutable.getShaderStorageBlocks(), - shaderType, ShaderVariableType::ShaderStorageBuffer, + addInterfaceBlockDescriptorSetDesc(glExecutable.getShaderStorageBlocks(), shaderType, + ShaderVariableType::ShaderStorageBuffer, kStorageBufferDescriptorType, &resourcesSetDesc); addAtomicCounterBufferDescriptorSetDesc(glExecutable.getAtomicCounterBuffers(), shaderType, &resourcesSetDesc); @@ -1247,7 +1290,6 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet( gl::ShaderType shaderType, const vk::DescriptorSetDesc &shaderBuffersDesc, const gl::BufferVector &buffers, - const gl::ProgramExecutable &glExecutable, const std::vector<gl::InterfaceBlock> &blocks, ShaderVariableType variableType, VkDescriptorType descriptorType, @@ -1277,14 +1319,13 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet( continue; } - const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - glExecutable, shaderType, variableType, blockIndex); + const ShaderInterfaceVariableInfo &info = + mVariableInfoMap.getIndexedVariableInfo(shaderType, variableType, blockIndex); if (info.isDuplicate) { continue; } - uint32_t binding = info.binding; uint32_t arrayElement = block.isArray ? block.arrayElement : 0; if (bufferBinding.get() == nullptr) @@ -1296,7 +1337,7 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet( emptyBuffer->retainReadOnly(resourceUseList); WriteBufferDescriptorSetBinding(*emptyBuffer, 0, emptyBuffer->getSize(), - descriptorSet, descriptorType, binding, + descriptorSet, descriptorType, info.binding, arrayElement, 0, &bufferInfo, &writeInfo); } if (IsDynamicDescriptor(descriptorType)) @@ -1327,8 +1368,8 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet( VkDeviceSize offset = IsDynamicDescriptor(descriptorType) ? 0 : bufferBinding.getOffset(); WriteBufferDescriptorSetBinding(bufferHelper, offset, size, descriptorSet, - descriptorType, binding, arrayElement, 0, &bufferInfo, - &writeInfo); + descriptorType, info.binding, arrayElement, 0, + &bufferInfo, &writeInfo); } if (IsDynamicDescriptor(descriptorType)) { @@ -1461,7 +1502,7 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( uint32_t arraySize = static_cast<uint32_t>(imageBinding.boundImageUnits.size()); const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - executable, shaderType, ShaderVariableType::Image, imageIndex); + shaderType, ShaderVariableType::Image, imageIndex); if (info.isDuplicate) { continue; @@ -1600,12 +1641,11 @@ angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet( { ANGLE_TRY(updateBuffersDescriptorSet( contextVk, updateBuilder, emptyBuffer, resourceUseList, shaderType, shaderBuffersDesc, - uniformBuffers, *executable, executable->getUniformBlocks(), - ShaderVariableType::UniformBuffer, mUniformBufferDescriptorType, - limits.maxUniformBufferRange, cacheHit)); + uniformBuffers, executable->getUniformBlocks(), ShaderVariableType::UniformBuffer, + mUniformBufferDescriptorType, limits.maxUniformBufferRange, cacheHit)); ANGLE_TRY(updateBuffersDescriptorSet( contextVk, updateBuilder, emptyBuffer, resourceUseList, shaderType, shaderBuffersDesc, - storageBuffers, *executable, executable->getShaderStorageBlocks(), + storageBuffers, executable->getShaderStorageBlocks(), ShaderVariableType::ShaderStorageBuffer, kStorageBufferDescriptorType, limits.maxStorageBufferRange, cacheHit)); ANGLE_TRY(updateAtomicCounterBuffersDescriptorSet( @@ -1644,7 +1684,7 @@ angle::Result ProgramExecutableVk::updateInputAttachmentDescriptorSet( const gl::LinkedUniform &baseInputAttachment = uniforms.at(baseUniformIndex); const ShaderInterfaceVariableInfo &baseInfo = - mVariableInfoMap.getFramebufferFetchInfo(executable, shaderType); + mVariableInfoMap.getFramebufferFetchInfo(shaderType); if (baseInfo.isDuplicate) { return angle::Result::Continue; @@ -1787,8 +1827,11 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet( continue; } + uint32_t arrayOffset = samplerUniform.outerArrayOffset; + uint32_t arraySize = static_cast<uint32_t>(samplerBinding.boundTextureUnits.size()); + const ShaderInterfaceVariableInfo &info = mVariableInfoMap.getIndexedVariableInfo( - executable, shaderType, ShaderVariableType::Texture, textureIndex); + shaderType, ShaderVariableType::Texture, textureIndex); if (info.isDuplicate) { continue; @@ -1815,9 +1858,6 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet( } ASSERT(descriptorSet != VK_NULL_HANDLE); - uint32_t arrayOffset = samplerUniform.outerArrayOffset; - uint32_t arraySize = static_cast<uint32_t>(samplerBinding.boundTextureUnits.size()); - VkWriteDescriptorSet *writeInfos = updateBuilder->allocWriteDescriptorSets(arraySize); // Texture buffers use buffer views, so they are especially handled. diff --git a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h index 69e83b82bf..cd540cbca3 100644 --- a/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h +++ b/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h @@ -256,8 +256,7 @@ class ProgramExecutableVk vk::ResourceUseList *resourceUseList, DescriptorSetIndex descriptorSetIndex, bool *newPoolAllocatedOut); - void addInterfaceBlockDescriptorSetDesc(const gl::ProgramExecutable &glExecutable, - const std::vector<gl::InterfaceBlock> &blocks, + void addInterfaceBlockDescriptorSetDesc(const std::vector<gl::InterfaceBlock> &blocks, gl::ShaderType shaderType, ShaderVariableType variableType, VkDescriptorType descType, @@ -302,7 +301,6 @@ class ProgramExecutableVk gl::ShaderType shaderType, const vk::DescriptorSetDesc &shaderBuffersDesc, const gl::BufferVector &buffers, - const gl::ProgramExecutable &glExecutable, const std::vector<gl::InterfaceBlock> &blocks, ShaderVariableType variableType, VkDescriptorType descriptorType, @@ -418,8 +416,6 @@ class ProgramExecutableVk gl::ShaderVector<uint32_t> mDynamicUniformDescriptorOffsets; std::vector<uint32_t> mDynamicShaderBufferDescriptorOffsets; - // TODO: http://anglebug.com/4524: Need a different hash key than a string, - // since that's slow to calculate. ShaderInterfaceVariableInfoMap mVariableInfoMap; // We store all permutations of surface rotation and transformed SPIR-V programs here. We may diff --git a/src/tests/gl_tests/StateChangeTest.cpp b/src/tests/gl_tests/StateChangeTest.cpp index 98856f7486..e31263dedf 100644 --- a/src/tests/gl_tests/StateChangeTest.cpp +++ b/src/tests/gl_tests/StateChangeTest.cpp @@ -4770,6 +4770,114 @@ void main() glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } +// Tests that writing to an SSBO in the vertex shader before and after a change to the drawbuffers +// still works +TEST_P(SimpleStateChangeTestES31, VertWriteSSBOThenChangeDrawbuffersThenWriteSSBO) +{ + GLint maxVertexShaderStorageBlocks; + glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks); + + ANGLE_SKIP_TEST_IF(maxVertexShaderStorageBlocks < 1); + + constexpr GLsizei kSize = 1; + + GLTexture color; + glBindTexture(GL_TEXTURE_2D, color); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize); + EXPECT_GL_NO_ERROR(); + + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0); + EXPECT_GL_NO_ERROR(); + + constexpr std::array<float, 4> kBufferInitValue = {0.125f, 0.25f, 0.5f, 1.0f}; + GLBuffer buffer; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(), + GL_STATIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer); + + // Create a program that writes to the SSBO in the vertex shader. + constexpr char kVS[] = R"(#version 310 es +in vec4 a_position; +uniform vec4 value; +layout(binding = 0, std430) buffer Output { + vec4 value; +} b; +void main() +{ + b.value = value; + gl_Position = a_position; +})"; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, essl31_shaders::fs::Green()); + + const GLuint program = glCreateProgram(); + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + CheckLinkStatusAndReturnProgram(program, true); + + // Detach the shaders, so any draw-time shader rewriting won't be able to use them. + glDetachShader(program, vs); + glDetachShader(program, fs); + + glUseProgram(program); + GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib()); + ASSERT_NE(-1, positionLoc); + GLint valueLoc = glGetUniformLocation(program, "value"); + ASSERT_NE(-1, valueLoc); + + const std::array<Vector3, 6> &quadVertices = GetQuadVertices(); + const size_t posBufferSize = quadVertices.size() * sizeof(Vector3); + + GLBuffer posBuffer; + glBindBuffer(GL_ARRAY_BUFFER, posBuffer); + glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW); + glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glEnableVertexAttribArray(positionLoc); + + glUseProgram(program); + constexpr float kValue1[4] = {0.1f, 0.2f, 0.3f, 0.4f}; + + glUniform4fv(valueLoc, 1, kValue1); + glDrawArrays(GL_TRIANGLES, 0, 6); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + EXPECT_GL_NO_ERROR(); + + // Verify that the program wrote the SSBO correctly. + const float *ptr = reinterpret_cast<const float *>( + glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT)); + + for (int i = 0; i < 4; ++i) + { + EXPECT_NEAR(ptr[i], kValue1[i], 0.001); + } + + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + + GLenum drawBuffers[] = {GL_NONE}; + glDrawBuffers(1, drawBuffers); + + constexpr float kValue2[4] = {0.5f, 0.6f, 0.7f, 0.9f}; + glUniform4fv(valueLoc, 1, kValue2); + glDrawArrays(GL_TRIANGLES, 0, 6); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + EXPECT_GL_NO_ERROR(); + // Verify that the program wrote the SSBO correctly. + ptr = reinterpret_cast<const float *>( + glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT)); + + for (int i = 0; i < 4; ++i) + { + EXPECT_NEAR(ptr[i], kValue2[i], 0.001); + } + + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); +} + // Tests that rendering to a texture in one draw call followed by sampling from it in a dispatch // call works correctly. This requires an implicit barrier in between the calls. TEST_P(SimpleStateChangeTestES31, DrawThenSampleWithCompute) |