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