From 6e130d2b77b8572db98edd24f5f778e630985ac1 Mon Sep 17 00:00:00 2001 From: Stephen White Date: Tue, 19 Apr 2022 11:35:46 -0400 Subject: D3D: fix SSBOs used in vertex shaders. Use the total number of pixel shader outputs as the base UAV register for vertex and pixel shaders. This is less fragile than making the vertex shader depend on the number of draw-time pixel shader outputs. Add a test that exercises SSBOs in vertex shaders, varying the number of draw-time pixel shader outputs (which should have no effect on register assignment). Bug: angleproject:7156 Change-Id: I5801d59299275ea6d2569456d53c230e7e8ee5a9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3579501 Reviewed-by: Jamie Madill Commit-Queue: Stephen White --- src/libANGLE/renderer/d3d/DynamicHLSL.cpp | 7 ++++--- src/libANGLE/renderer/d3d/DynamicHLSL.h | 3 ++- src/libANGLE/renderer/d3d/ProgramD3D.cpp | 5 +++-- src/libANGLE/renderer/d3d/ProgramD3D.h | 1 - src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src/libANGLE/renderer') 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 &outputVariables, bool usesFragDepth, const std::vector &outputLayout, - const std::vector &shaderStorageBlocks) const + const std::vector &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 &outputVariables, bool usesFragDepth, const std::vector &outputLayout, - const std::vector &shaderStorageBlocks) const; + const std::vector &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(mProgramD3D->getNumPixelShaderOutputs()); + UINT baseUAVRegister = static_cast(mProgramD3D->getPixelShaderKey().size()); deviceContext->OMSetRenderTargetsAndUnorderedAccessViews( D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, baseUAVRegister + resourceSlot, 1, &uavPtr, nullptr); -- cgit v1.2.3 From 55c21842b20406d02ce5181921b3100749c03b9a Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Thu, 14 Apr 2022 05:04:15 -0400 Subject: Vulkan: Use flat array lookups for shader variables. The array lookups we use after link now are simple array lookups and no longer use string hashing queries. This will make the descriptor cache indexing much faster after the cache key redesign. Bug: angleproject:4524 Change-Id: If19e3a4aa57c415f33c69172dd76c10a207e3264 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3580979 Reviewed-by: Shahbaz Youssefi Reviewed-by: Yuxin Hu Commit-Queue: Jamie Madill --- .../renderer/ShaderInterfaceVariableInfoMap.cpp | 116 +++++++++++----- .../renderer/ShaderInterfaceVariableInfoMap.h | 154 ++++++++------------- src/libANGLE/renderer/glslang_wrapper_utils.cpp | 70 +++++----- .../renderer/vulkan/ProgramExecutableVk.cpp | 120 ++++++++++------ src/libANGLE/renderer/vulkan/ProgramExecutableVk.h | 6 +- 5 files changed, 254 insertions(+), 212 deletions(-) (limited to 'src/libANGLE/renderer') 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()) { - 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 &data, + const gl::ShaderMap &nameToTypeAndIndexMap, + const gl::ShaderMap &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(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::getData() const +{ + return mData; +} + +const gl::ShaderMap + &ShaderInterfaceVariableInfoMap::getNameToTypeAndIndexMap() const +{ + return mNameToTypeAndIndexMap; +} + +const gl::ShaderMap + &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 - -#include +#include "common/FastVector.h" #include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/glslang_wrapper_utils.h" #include "libANGLE/renderer/renderer_utils.h" + +#include + +#include + 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; + using VariableTypeToInfoMap = angle::PackedEnumMap; + using NameToTypeAndIndexMap = angle::HashMap; + + static constexpr size_t kResourceFastMapMax = 32; + using ResourceIndexMap = angle::FastMap; + using VariableTypeToIndexMap = angle::PackedEnumMap; + ShaderInterfaceVariableInfoMap(); ~ShaderInterfaceVariableInfoMap(); void clear(); + void load(const gl::ShaderMap &data, + const gl::ShaderMap &nameToTypeAndIndexMap, + const gl::ShaderMap &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; - using VariableTypeToInfoMap = angle::PackedEnumMap; - - 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 &getData() const; + const gl::ShaderMap &getNameToTypeAndIndexMap() const; + const gl::ShaderMap &getIndexedResourceMap() const; private: - const ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, - ShaderVariableType variableType, - const std::string &variableName) const; gl::ShaderMap mData; - gl::ShaderMap> mNameToTypeMap; + gl::ShaderMap mNameToTypeAndIndexMap; + gl::ShaderMap 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 &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 &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 &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 &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 &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/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 ProgramExecutableVk::load(ContextVk *contextVk, const gl::ProgramExecutable &glExecutable, gl::BinaryInputStream *stream) { - clearVariableInfoMap(); + gl::ShaderMap data; + gl::ShaderMap nameToTypeAndIndexMap; + gl::ShaderMap indexedResourceMap; for (gl::ShaderType shaderType : gl::AllShaderTypes()) { - for (ShaderVariableType variableType : angle::AllEnums()) + size_t nameCount = stream->readInt(); + for (size_t nameIndex = 0; nameIndex < nameCount; ++nameIndex) { - size_t variableInfoMapSize = stream->readInt(); + const std::string variableName = stream->readString(); + ShaderVariableType variableType = stream->readEnum(); + uint32_t index = stream->readInt(); + nameToTypeAndIndexMap[shaderType][variableName] = {variableType, index}; + } - for (size_t i = 0; i < variableInfoMapSize; ++i) + for (ShaderVariableType variableType : angle::AllEnums()) + { + size_t infoArraySize = stream->readInt(); + 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(); info.binding = stream->readInt(); @@ -334,10 +342,21 @@ std::unique_ptr ProgramExecutableVk::load(ContextVk *contextVk, info.attributeComponentCount = stream->readInt(); info.attributeLocationCount = stream->readInt(); info.isDuplicate = stream->readBool(); + + data[shaderType][variableType].push_back(info); + } + + uint32_t resourceMapSize = stream->readInt(); + for (uint32_t resourceIndex = 0; resourceIndex < resourceMapSize; ++resourceIndex) + { + uint32_t variableIndex = stream->readInt(); + 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 ProgramExecutableVk::load(ContextVk *contextVk, void ProgramExecutableVk::save(gl::BinaryOutputStream *stream) { + const gl::ShaderMap &data = + mVariableInfoMap.getData(); + const gl::ShaderMap + &nameToTypeAndIndexMap = mVariableInfoMap.getNameToTypeAndIndexMap(); + const gl::ShaderMap + &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()) { - 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(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 &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 &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(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(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(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 &blocks, + void addInterfaceBlockDescriptorSetDesc(const std::vector &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 &blocks, ShaderVariableType variableType, VkDescriptorType descriptorType, @@ -418,8 +416,6 @@ class ProgramExecutableVk gl::ShaderVector mDynamicUniformDescriptorOffsets; std::vector 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 -- cgit v1.2.3