1 // 2 // Copyright 2021 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // ShaderInterfaceVariableInfoMap: Maps shader interface variable SPIR-V ids to their Vulkan 7 // mapping. 8 9 #ifndef LIBANGLE_RENDERER_VULKAN_SHADERINTERFACEVARIABLEINFOMAP_H_ 10 #define LIBANGLE_RENDERER_VULKAN_SHADERINTERFACEVARIABLEINFOMAP_H_ 11 12 #include "common/FastVector.h" 13 #include "libANGLE/renderer/ProgramImpl.h" 14 #include "libANGLE/renderer/renderer_utils.h" 15 #include "libANGLE/renderer/vulkan/spv_utils.h" 16 17 #include <functional> 18 19 #include <stdio.h> 20 21 namespace rx 22 { 23 24 struct VariableIndex 25 { 26 static constexpr uint32_t kInvalid = 0xFFFF'FFFF; 27 uint32_t index = kInvalid; 28 }; 29 30 class ShaderInterfaceVariableInfoMap final : angle::NonCopyable 31 { 32 public: 33 // For each interface variable, a ShaderInterfaceVariableInfo is created. These are stored in a 34 // flat array. 35 using VariableInfoArray = std::vector<ShaderInterfaceVariableInfo>; 36 37 // Each interface variable has an associted SPIR-V id (which is different per shader type). 38 // The following map is from a SPIR-V id to its associated info in VariableInfoArray. 39 // 40 // Note that the SPIR-V ids are mostly contiguous and start at 41 // sh::vk::spirv::kIdShaderVariablesBegin. As such, the map key is actually 42 // |id - sh::vk::spirv::kIdShaderVariablesBegin|. 43 static constexpr size_t kIdFastMapMax = 32; 44 using IdToIndexMap = angle::FastMap<VariableIndex, kIdFastMapMax>; 45 46 ShaderInterfaceVariableInfoMap(); 47 ~ShaderInterfaceVariableInfoMap(); 48 49 void clear(); 50 void load(VariableInfoArray &&data, 51 gl::ShaderMap<IdToIndexMap> &&idToIndexMap, 52 gl::ShaderMap<gl::PerVertexMemberBitSet> &&inputPerVertexActiveMembers, 53 gl::ShaderMap<gl::PerVertexMemberBitSet> &&outputPerVertexActiveMembers); 54 55 ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType, uint32_t id); 56 void addResource(gl::ShaderBitSet shaderTypes, 57 const gl::ShaderMap<uint32_t> &idInShaderTypes, 58 uint32_t descriptorSet, 59 uint32_t binding); 60 ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType, uint32_t id); 61 62 void setInputPerVertexActiveMembers(gl::ShaderType shaderType, 63 gl::PerVertexMemberBitSet activeMembers); 64 void setOutputPerVertexActiveMembers(gl::ShaderType shaderType, 65 gl::PerVertexMemberBitSet activeMembers); 66 ShaderInterfaceVariableInfo &getMutable(gl::ShaderType shaderType, uint32_t id); 67 68 const ShaderInterfaceVariableInfo &getDefaultUniformInfo(gl::ShaderType shaderType) const; 69 const ShaderInterfaceVariableInfo &getAtomicCounterInfo(gl::ShaderType shaderType) const; 70 bool hasTransformFeedbackInfo(gl::ShaderType shaderType, uint32_t bufferIndex) const; 71 const ShaderInterfaceVariableInfo &getEmulatedXfbBufferInfo(uint32_t bufferIndex) const; 72 73 uint32_t getDefaultUniformBinding(gl::ShaderType shaderType) const; 74 uint32_t getEmulatedXfbBufferBinding(uint32_t xfbBufferIndex) const; 75 uint32_t getAtomicCounterBufferBinding(gl::ShaderType shaderType, 76 uint32_t atomicCounterBufferIndex) const; 77 78 bool hasVariable(gl::ShaderType shaderType, uint32_t id) const; 79 const ShaderInterfaceVariableInfo &getVariableById(gl::ShaderType shaderType, 80 uint32_t id) const; getData()81 const VariableInfoArray &getData() const { return mData; } 82 const gl::ShaderMap<IdToIndexMap> &getIdToIndexMap() const { return mIdToIndexMap; } 83 const gl::ShaderMap<gl::PerVertexMemberBitSet> &getInputPerVertexActiveMembers() const 84 { 85 return mInputPerVertexActiveMembers; 86 } 87 const gl::ShaderMap<gl::PerVertexMemberBitSet> &getOutputPerVertexActiveMembers() const 88 { 89 return mOutputPerVertexActiveMembers; 90 } 91 92 void setHasAliasingAttributes() { mHasAliasingAttributes = true; } 93 bool hasAliasingAttributes() const { return mHasAliasingAttributes; } 94 95 private: 96 void setVariableIndex(gl::ShaderType shaderType, uint32_t id, VariableIndex index); 97 const VariableIndex &getVariableIndex(gl::ShaderType shaderType, uint32_t id) const; 98 99 VariableInfoArray mData; 100 gl::ShaderMap<IdToIndexMap> mIdToIndexMap; 101 102 // Active members of `in gl_PerVertex` and `out gl_PerVertex` 103 gl::ShaderMap<gl::PerVertexMemberBitSet> mInputPerVertexActiveMembers; 104 gl::ShaderMap<gl::PerVertexMemberBitSet> mOutputPerVertexActiveMembers; 105 106 // Whether the vertex shader has aliasing attributes. Used by the SPIR-V transformer to tell if 107 // emulation is needed. 108 bool mHasAliasingAttributes = false; 109 }; 110 111 ANGLE_INLINE const ShaderInterfaceVariableInfo & 112 ShaderInterfaceVariableInfoMap::getDefaultUniformInfo(gl::ShaderType shaderType) const 113 { 114 return getVariableById(shaderType, sh::vk::spirv::kIdDefaultUniformsBlock); 115 } 116 117 ANGLE_INLINE const ShaderInterfaceVariableInfo & 118 ShaderInterfaceVariableInfoMap::getAtomicCounterInfo(gl::ShaderType shaderType) const 119 { 120 return getVariableById(shaderType, sh::vk::spirv::kIdAtomicCounterBlock); 121 } 122 123 ANGLE_INLINE const ShaderInterfaceVariableInfo & 124 ShaderInterfaceVariableInfoMap::getEmulatedXfbBufferInfo(uint32_t bufferIndex) const 125 { 126 ASSERT(bufferIndex < 4); 127 static_assert(sh::vk::spirv::kIdXfbEmulationBufferBlockOne == 128 sh::vk::spirv::kIdXfbEmulationBufferBlockZero + 1); 129 static_assert(sh::vk::spirv::kIdXfbEmulationBufferBlockTwo == 130 sh::vk::spirv::kIdXfbEmulationBufferBlockZero + 2); 131 static_assert(sh::vk::spirv::kIdXfbEmulationBufferBlockThree == 132 sh::vk::spirv::kIdXfbEmulationBufferBlockZero + 3); 133 134 // Transform feedback emulation only supports vertex shaders. 135 return getVariableById(gl::ShaderType::Vertex, 136 sh::vk::spirv::kIdXfbEmulationBufferBlockZero + bufferIndex); 137 } 138 139 ANGLE_INLINE uint32_t 140 ShaderInterfaceVariableInfoMap::getDefaultUniformBinding(gl::ShaderType shaderType) const 141 { 142 return getDefaultUniformInfo(shaderType).binding; 143 } 144 145 ANGLE_INLINE uint32_t 146 ShaderInterfaceVariableInfoMap::getEmulatedXfbBufferBinding(uint32_t bufferIndex) const 147 { 148 return getEmulatedXfbBufferInfo(bufferIndex).binding; 149 } 150 151 ANGLE_INLINE uint32_t ShaderInterfaceVariableInfoMap::getAtomicCounterBufferBinding( 152 gl::ShaderType shaderType, 153 uint32_t atomicCounterBufferIndex) const 154 { 155 return getAtomicCounterInfo(shaderType).binding + atomicCounterBufferIndex; 156 } 157 158 ANGLE_INLINE const ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::getVariableById( 159 gl::ShaderType shaderType, 160 uint32_t id) const 161 { 162 return mData[getVariableIndex(shaderType, id).index]; 163 } 164 } // namespace rx 165 #endif // LIBANGLE_RENDERER_VULKAN_SHADERINTERFACEVARIABLEINFOMAP_H_ 166