aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com>2022-04-19 22:19:28 +0000
committerandroid-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com>2022-04-19 22:19:28 +0000
commit6fb0b00ad2e695a76dd900cd0d025a6509056613 (patch)
treeb21d2eac62fed2ab6fe4f85a30cfbf0c36248db7
parent345b350a2a729a37d0bd18d9a7cdbe91d86a23ee (diff)
parent55c21842b20406d02ce5181921b3100749c03b9a (diff)
downloadangle-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.cpp2
-rw-r--r--src/libANGLE/angletypes.cpp16
-rw-r--r--src/libANGLE/angletypes.h10
-rw-r--r--src/libANGLE/angletypes_unittest.cpp17
-rw-r--r--src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.cpp116
-rw-r--r--src/libANGLE/renderer/ShaderInterfaceVariableInfoMap.h154
-rw-r--r--src/libANGLE/renderer/d3d/DynamicHLSL.cpp7
-rw-r--r--src/libANGLE/renderer/d3d/DynamicHLSL.h3
-rw-r--r--src/libANGLE/renderer/d3d/ProgramD3D.cpp5
-rw-r--r--src/libANGLE/renderer/d3d/ProgramD3D.h1
-rw-r--r--src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp2
-rw-r--r--src/libANGLE/renderer/glslang_wrapper_utils.cpp70
-rw-r--r--src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp120
-rw-r--r--src/libANGLE/renderer/vulkan/ProgramExecutableVk.h6
-rw-r--r--src/tests/gl_tests/StateChangeTest.cpp108
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)