Commit 093250e0 by Jamie Madill Committed by Commit Bot

Vulkan: Make shader variable info maps a class.

Instead of using a map type directly we abstract the info maps into an encapsulated class. We can enforce a specific API set instead of using the same API as the map class. This also cleans up a few of the APIs related to these maps. This change will allow future changes to the way the variables are stored in the class without drastically changing the interface. Bug: angleproject:3572 Bug: angleproject:4524 Change-Id: Ic1a63e1776c39f49b895a1274bae8282d7a6b9b5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2600080 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent c2847bbc
......@@ -111,10 +111,46 @@ struct ShaderInterfaceVariableInfo
uint8_t attributeLocationCount = 0;
};
// TODO: http://anglebug.com/4524: Need a different hash key than a string, since
// that's slow to calculate.
using ShaderInterfaceVariableInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>;
using ShaderMapInterfaceVariableInfoMap = gl::ShaderMap<ShaderInterfaceVariableInfoMap>;
// TODO: http://anglebug.com/4524: Need a different hash key than a string, since that's slow to
// calculate.
class ShaderInterfaceVariableInfoMap final : angle::NonCopyable
{
public:
ShaderInterfaceVariableInfoMap();
~ShaderInterfaceVariableInfoMap();
void clear();
bool contains(gl::ShaderType shaderType, const std::string &variableName) const;
const ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType,
const std::string &variableName) const;
ShaderInterfaceVariableInfo &get(gl::ShaderType shaderType, const std::string &variableName);
ShaderInterfaceVariableInfo &add(gl::ShaderType shaderType, const std::string &variableName);
ShaderInterfaceVariableInfo &addOrGet(gl::ShaderType shaderType,
const std::string &variableName);
size_t variableCount(gl::ShaderType shaderType) const { return mData[shaderType].size(); }
using VariableNameToInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>;
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) const;
private:
gl::ShaderMap<VariableNameToInfoMap> mData;
};
void GlslangInitialize();
void GlslangRelease();
......@@ -139,7 +175,7 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<ShaderInterfaceVariableInfoMap> *variableInfoMapOut);
ShaderInterfaceVariableInfoMap *variableInfoMapOut);
// Transform the source to include actual binding points for various shader resources (textures,
// buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap
......@@ -150,10 +186,11 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut);
ShaderInterfaceVariableInfoMap *variableInfoMapOut);
angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob,
SpirvBlob *spirvBlobOut);
......
......@@ -318,11 +318,11 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
// Gather variable info and transform sources.
gl::ShaderMap<std::string> shaderSources;
gl::ShaderMap<std::string> xfbOnlyShaderSources;
ShaderMapInterfaceVariableInfoMap variableInfoMap;
ShaderMapInterfaceVariableInfoMap xfbOnlyVariableInfoMap;
ShaderInterfaceVariableInfoMap variableInfoMap;
ShaderInterfaceVariableInfoMap xfbOnlyVariableInfoMap;
mtl::GlslangGetShaderSource(mState, resources, &shaderSources,
&xfbOnlyShaderSources[gl::ShaderType::Vertex], &variableInfoMap,
&xfbOnlyVariableInfoMap[gl::ShaderType::Vertex]);
&xfbOnlyVariableInfoMap);
// Convert GLSL to spirv code
gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
......@@ -341,8 +341,7 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
}
// Convert spirv code to MSL
ANGLE_TRY(mtl::SpirvCodeToMsl(contextMtl, mState,
xfbOnlyVariableInfoMap[gl::ShaderType::Vertex], &shaderCodes,
ANGLE_TRY(mtl::SpirvCodeToMsl(contextMtl, mState, xfbOnlyVariableInfoMap, &shaderCodes,
&xfbOnlyShaderCodes[gl::ShaderType::Vertex],
&mMslShaderTranslateInfo, &mMslXfbOnlyVertexShaderInfo));
......
......@@ -47,14 +47,14 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut,
std::string *xfbOnlyShaderSourceOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut);
angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut);
// Translate from SPIR-V code to Metal shader source code.
......
......@@ -407,7 +407,7 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut,
std::string *xfbOnlyShaderSourceOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut)
{
GlslangSourceOptions options = CreateSourceOptions();
......@@ -425,18 +425,16 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
GlslangProgramInterfaceInfo xfbOnlyInterfaceInfo;
ResetGlslangProgramInterfaceInfo(&xfbOnlyInterfaceInfo);
ShaderMapInterfaceVariableInfoMap xfbOnlyVariableMaps;
options.emulateTransformFeedback = true;
rx::GlslangGenTransformFeedbackEmulationOutputs(
options, programState, &xfbOnlyInterfaceInfo, xfbOnlyShaderSourceOut,
&xfbOnlyVariableMaps[gl::ShaderType::Vertex]);
xfbOnlyVSVariableInfoMapOut);
GlslangAssignLocations(options, programState.getExecutable(), gl::ShaderType::Vertex,
gl::ShaderType::InvalidEnum, &xfbOnlyInterfaceInfo,
&xfbOnlyVariableMaps);
*xfbOnlyVSVariableInfoMapOut = std::move(xfbOnlyVariableMaps[gl::ShaderType::Vertex]);
xfbOnlyVSVariableInfoMapOut);
}
}
......@@ -444,7 +442,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{
gl::ShaderMap<SpirvBlob> initialSpirvBlobs;
......@@ -460,7 +458,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
angle::Result status = GlslangTransformSpirvCode(
[context](GlslangError error) { return HandleError(context, error); }, options,
variableInfoMap[shaderType], initialSpirvBlobs[shaderType],
shaderType, variableInfoMap, initialSpirvBlobs[shaderType],
&(*shaderCodeOut)[shaderType]);
if (status != angle::Result::Continue)
{
......@@ -495,9 +493,11 @@ angle::Result SpirvCodeToMsl(Context *context,
for (uint32_t bufferIdx = 0; bufferIdx < kMaxShaderXFBs; ++bufferIdx)
{
std::string bufferName = rx::GetXfbBufferName(bufferIdx);
if (xfbVSVariableInfoMap.count(bufferName))
if (xfbVSVariableInfoMap.contains(gl::ShaderType::Vertex, bufferName))
{
xfbOriginalBindings[xfbVSVariableInfoMap.at(bufferName).binding] = bufferIdx;
const ShaderInterfaceVariableInfo &info =
xfbVSVariableInfoMap.get(gl::ShaderType::Vertex, bufferName);
xfbOriginalBindings[info.binding] = bufferIdx;
}
}
......
......@@ -62,7 +62,7 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features,
const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut)
ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{
GlslangSourceOptions options = CreateSourceOptions(features);
GlslangGetShaderSource(options, programState, resources, programInterfaceInfo, shaderSourcesOut,
......@@ -85,12 +85,13 @@ angle::Result GlslangWrapperVk::GetShaderCode(vk::Context *context,
angle::Result GlslangWrapperVk::TransformSpirV(
vk::Context *context,
const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob,
SpirvBlob *shaderCodeOut)
{
return GlslangTransformSpirvCode(
[context](GlslangError error) { return ErrorHandler(context, error); }, options,
[context](GlslangError error) { return ErrorHandler(context, error); }, options, shaderType,
variableInfoMap, initialSpirvBlob, shaderCodeOut);
}
......
......@@ -35,7 +35,7 @@ class GlslangWrapperVk
const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut);
ShaderInterfaceVariableInfoMap *variableInfoMapOut);
static angle::Result GetShaderCode(vk::Context *context,
const gl::ShaderBitSet &linkedShaderStages,
......@@ -45,6 +45,7 @@ class GlslangWrapperVk
static angle::Result TransformSpirV(vk::Context *context,
const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob,
SpirvBlob *shaderCodeOut);
......
......@@ -32,7 +32,7 @@ class ShaderInfo final : angle::NonCopyable
angle::Result initShaders(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages,
const gl::ShaderMap<std::string> &shaderSources,
ProgramExecutableVk *executableVk);
const ShaderInterfaceVariableInfoMap &variableInfoMap);
void release(ContextVk *contextVk);
ANGLE_INLINE bool valid() const { return mIsInitialized; }
......@@ -69,7 +69,7 @@ class ProgramInfo final : angle::NonCopyable
const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo,
ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk);
const ShaderInterfaceVariableInfoMap &variableInfoMap);
void release(ContextVk *contextVk);
ANGLE_INLINE bool valid(const gl::ShaderType shaderType) const
......@@ -110,10 +110,6 @@ class ProgramExecutableVk
std::unique_ptr<rx::LinkEvent> load(gl::BinaryInputStream *stream);
void clearVariableInfoMap();
ShaderMapInterfaceVariableInfoMap &getShaderInterfaceVariableInfoMap()
{
return mVariableInfoMap;
}
ProgramVk *getShaderProgram(const gl::State &glState, gl::ShaderType shaderType) const;
......@@ -229,9 +225,9 @@ class ProgramExecutableVk
ContextVk *contextVk,
vk::ResourceUseList *resourceUseList,
vk::CommandBufferHelper *commandBufferHelper);
angle::Result updateImagesDescriptorSet(const gl::ProgramExecutable &executable,
const gl::ShaderType shaderType,
ContextVk *contextVk);
angle::Result updateImagesDescriptorSet(ContextVk *contextVk,
const gl::ProgramExecutable &executable,
const gl::ShaderType shaderType);
angle::Result initDynamicDescriptorPools(ContextVk *contextVk,
vk::DescriptorSetLayoutDesc &descriptorSetLayoutDesc,
DescriptorSetIndex descriptorSetIndex,
......@@ -268,7 +264,7 @@ class ProgramExecutableVk
// TODO: http://anglebug.com/4524: Need a different hash key than a string,
// since that's slow to calculate.
ShaderMapInterfaceVariableInfoMap mVariableInfoMap;
ShaderInterfaceVariableInfoMap mVariableInfoMap;
// We store all permutations of surface rotation and transformed SPIR-V programs here. We may
// need some LRU algorithm to free least used programs to reduce the number of programs.
......
......@@ -84,7 +84,7 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
GlslangAssignLocations(options, glProgram->getState().getExecutable(), shaderType,
frontShaderType, &glslangProgramInterfaceInfo,
&mExecutable.getShaderInterfaceVariableInfoMap());
&mExecutable.mVariableInfoMap);
frontShaderType = shaderType;
}
}
......
......@@ -274,8 +274,9 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
&mExecutable.mVariableInfoMap);
// Compile the shaders.
angle::Result status = mOriginalShaderInfo.initShaders(
contextVk, mState.getExecutable().getLinkedShaderStages(), shaderSources, &mExecutable);
angle::Result status =
mOriginalShaderInfo.initShaders(contextVk, mState.getExecutable().getLinkedShaderStages(),
shaderSources, mExecutable.mVariableInfoMap);
if (status != angle::Result::Continue)
{
return std::make_unique<LinkEventDone>(status);
......
......@@ -145,22 +145,24 @@ class ProgramVk : public ProgramImpl
const gl::ProgramExecutable &glExecutable,
gl::ShaderMap<VkDeviceSize> &uniformOffsets) const;
ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk,
const gl::ShaderType shaderType,
ProgramTransformOptions optionBits,
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
ANGLE_INLINE angle::Result initGraphicsShaderProgram(
ContextVk *contextVk,
const gl::ShaderType shaderType,
ProgramTransformOptions optionBits,
ProgramInfo *programInfo,
const ShaderInterfaceVariableInfoMap &variableInfoMap)
{
return initProgram(contextVk, shaderType, optionBits, programInfo, executableVk);
return initProgram(contextVk, shaderType, optionBits, programInfo, variableInfoMap);
}
ANGLE_INLINE angle::Result initComputeProgram(ContextVk *contextVk,
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
ANGLE_INLINE angle::Result initComputeProgram(
ContextVk *contextVk,
ProgramInfo *programInfo,
const ShaderInterfaceVariableInfoMap &variableInfoMap)
{
ProgramTransformOptions optionBits = {};
return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo,
executableVk);
variableInfoMap);
}
GlslangProgramInterfaceInfo &getGlslangProgramInterfaceInfo()
......@@ -194,7 +196,7 @@ class ProgramVk : public ProgramImpl
const gl::ShaderType shaderType,
ProgramTransformOptions optionBits,
ProgramInfo *programInfo,
ProgramExecutableVk *executableVk)
const ShaderInterfaceVariableInfoMap &variableInfoMap)
{
ASSERT(mOriginalShaderInfo.valid());
......@@ -203,7 +205,7 @@ class ProgramVk : public ProgramImpl
if (!programInfo->valid(shaderType))
{
ANGLE_TRY(programInfo->initProgram(contextVk, shaderType, mOriginalShaderInfo,
optionBits, executableVk));
optionBits, variableInfoMap));
}
ASSERT(programInfo->valid(shaderType));
......
......@@ -203,7 +203,7 @@ angle::Result TransformFeedbackVk::bindIndexedBuffer(
void TransformFeedbackVk::updateDescriptorSetLayout(
ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const
{
......@@ -212,8 +212,9 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{
const std::string bufferName = GetXfbBufferName(bufferIndex);
const ShaderInterfaceVariableInfo &info = vsVariableInfoMap[bufferName];
const std::string bufferName = GetXfbBufferName(bufferIndex);
const ShaderInterfaceVariableInfo &info =
variableInfoMap.get(gl::ShaderType::Vertex, bufferName);
descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_VERTEX_BIT, nullptr);
......@@ -221,6 +222,7 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
}
void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorSet descSet) const
{
......@@ -239,11 +241,12 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
bufferInfo.range = VK_WHOLE_SIZE;
}
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet);
writeDescriptorSet(contextVk, variableInfoMap, xfbBufferCount, descriptorBufferInfo, descSet);
}
void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
VkDescriptorSet descSet) const
{
if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
......@@ -272,7 +275,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
ASSERT(bufferInfo.range != 0);
}
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet);
writeDescriptorSet(contextVk, variableInfoMap, xfbBufferCount, descriptorBufferInfo, descSet);
}
void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
......@@ -314,15 +317,16 @@ void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
}
void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const
{
ProgramExecutableVk *executableVk = contextVk->getExecutable();
ShaderMapInterfaceVariableInfoMap variableInfoMap =
executableVk->getShaderInterfaceVariableInfoMap();
const std::string bufferName = GetXfbBufferName(0);
ShaderInterfaceVariableInfo &info = variableInfoMap[gl::ShaderType::Vertex][bufferName];
ASSERT(contextVk->getFeatures().emulateTransformFeedback.enabled);
const std::string bufferName = GetXfbBufferName(0);
const ShaderInterfaceVariableInfo &info =
variableInfoMap.get(gl::ShaderType::Vertex, bufferName);
VkWriteDescriptorSet &writeDescriptorInfo = contextVk->allocWriteDescriptorSet();
writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
......
......@@ -44,14 +44,16 @@ class TransformFeedbackVk : public TransformFeedbackImpl
const gl::OffsetBindingPointer<gl::Buffer> &binding) override;
void updateDescriptorSetLayout(ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const;
void initDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorSet descSet) const;
void updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
VkDescriptorSet descSet) const;
void getBufferOffsets(ContextVk *contextVk,
GLint drawCallFirstVertex,
......@@ -94,6 +96,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl
private:
void writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment