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
...@@ -191,21 +191,8 @@ uint32_t CountExplicitOutputs(OutputIter outputsBegin, ...@@ -191,21 +191,8 @@ uint32_t CountExplicitOutputs(OutputIter outputsBegin,
return std::accumulate(outputsBegin, outputsEnd, 0, reduce); return std::accumulate(outputsBegin, outputsEnd, 0, reduce);
} }
ShaderInterfaceVariableInfo *AddShaderInterfaceVariable(ShaderInterfaceVariableInfoMap *infoMap,
const std::string &varName)
{
ASSERT(infoMap->find(varName) == infoMap->end());
return &(*infoMap)[varName];
}
ShaderInterfaceVariableInfo *GetShaderInterfaceVariable(ShaderInterfaceVariableInfoMap *infoMap,
const std::string &varName)
{
ASSERT(infoMap->find(varName) != infoMap->end());
return &(*infoMap)[varName];
}
ShaderInterfaceVariableInfo *AddResourceInfoToAllStages(ShaderInterfaceVariableInfoMap *infoMap, ShaderInterfaceVariableInfo *AddResourceInfoToAllStages(ShaderInterfaceVariableInfoMap *infoMap,
gl::ShaderType shaderType,
const std::string &varName, const std::string &varName,
uint32_t descriptorSet, uint32_t descriptorSet,
uint32_t binding) uint32_t binding)
...@@ -213,85 +200,86 @@ ShaderInterfaceVariableInfo *AddResourceInfoToAllStages(ShaderInterfaceVariableI ...@@ -213,85 +200,86 @@ ShaderInterfaceVariableInfo *AddResourceInfoToAllStages(ShaderInterfaceVariableI
gl::ShaderBitSet allStages; gl::ShaderBitSet allStages;
allStages.set(); allStages.set();
ShaderInterfaceVariableInfo *info = AddShaderInterfaceVariable(infoMap, varName); ShaderInterfaceVariableInfo &info = infoMap->add(shaderType, varName);
info->descriptorSet = descriptorSet; info.descriptorSet = descriptorSet;
info->binding = binding; info.binding = binding;
info->activeStages = allStages; info.activeStages = allStages;
return info; return &info;
} }
ShaderInterfaceVariableInfo *AddResourceInfo(ShaderInterfaceVariableInfoMap *infoMap, ShaderInterfaceVariableInfo *AddResourceInfo(ShaderInterfaceVariableInfoMap *infoMap,
gl::ShaderType shaderType,
const std::string &varName, const std::string &varName,
uint32_t descriptorSet, uint32_t descriptorSet,
uint32_t binding, uint32_t binding)
const gl::ShaderType shaderType)
{ {
gl::ShaderBitSet stages; gl::ShaderBitSet stages;
stages.set(shaderType); stages.set(shaderType);
ShaderInterfaceVariableInfo *info = AddShaderInterfaceVariable(infoMap, varName); ShaderInterfaceVariableInfo &info = infoMap->add(shaderType, varName);
info->descriptorSet = descriptorSet; info.descriptorSet = descriptorSet;
info->binding = binding; info.binding = binding;
info->activeStages = stages; info.activeStages = stages;
return info; return &info;
} }
// Add location information for an in/out variable. // Add location information for an in/out variable.
ShaderInterfaceVariableInfo *AddLocationInfo(ShaderInterfaceVariableInfoMap *infoMap, ShaderInterfaceVariableInfo *AddLocationInfo(ShaderInterfaceVariableInfoMap *infoMap,
gl::ShaderType shaderType,
const std::string &varName, const std::string &varName,
uint32_t location, uint32_t location,
uint32_t component, uint32_t component,
gl::ShaderType stage,
uint8_t attributeComponentCount, uint8_t attributeComponentCount,
uint8_t attributeLocationCount) uint8_t attributeLocationCount)
{ {
// The info map for this name may or may not exist already. This function merges the // The info map for this name may or may not exist already. This function merges the
// location/component information. // location/component information.
ShaderInterfaceVariableInfo *info = &(*infoMap)[varName]; ShaderInterfaceVariableInfo &info = infoMap->addOrGet(shaderType, varName);
ASSERT(info->descriptorSet == ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.descriptorSet == ShaderInterfaceVariableInfo::kInvalid);
ASSERT(info->binding == ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.binding == ShaderInterfaceVariableInfo::kInvalid);
ASSERT(info->location == ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.location == ShaderInterfaceVariableInfo::kInvalid);
ASSERT(info->component == ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.component == ShaderInterfaceVariableInfo::kInvalid);
info->location = location; info.location = location;
info->component = component; info.component = component;
info->activeStages.set(stage); info.activeStages.set(shaderType);
info->attributeComponentCount = attributeComponentCount; info.attributeComponentCount = attributeComponentCount;
info->attributeLocationCount = attributeLocationCount; info.attributeLocationCount = attributeLocationCount;
return info; return &info;
} }
// Add location information for an in/out variable // Add location information for an in/out variable
void AddVaryingLocationInfo(ShaderInterfaceVariableInfoMap &infoMap, void AddVaryingLocationInfo(ShaderInterfaceVariableInfoMap *infoMap,
const gl::VaryingInShaderRef &ref, const gl::VaryingInShaderRef &ref,
const bool isStructField, const bool isStructField,
const uint32_t location, const uint32_t location,
const uint32_t component) const uint32_t component)
{ {
const std::string &name = isStructField ? ref.parentStructMappedName : ref.varying->mappedName; const std::string &name = isStructField ? ref.parentStructMappedName : ref.varying->mappedName;
AddLocationInfo(&infoMap, name, location, component, ref.stage, 0, 0); AddLocationInfo(infoMap, ref.stage, name, location, component, 0, 0);
} }
// Modify an existing out variable and add transform feedback information. // Modify an existing out variable and add transform feedback information.
ShaderInterfaceVariableInfo *SetXfbInfo(ShaderInterfaceVariableInfoMap *infoMap, ShaderInterfaceVariableInfo *SetXfbInfo(ShaderInterfaceVariableInfoMap *infoMap,
gl::ShaderType shaderType,
const std::string &varName, const std::string &varName,
int fieldIndex, int fieldIndex,
uint32_t xfbBuffer, uint32_t xfbBuffer,
uint32_t xfbOffset, uint32_t xfbOffset,
uint32_t xfbStride) uint32_t xfbStride)
{ {
ShaderInterfaceVariableInfo *info = GetShaderInterfaceVariable(infoMap, varName); ShaderInterfaceVariableInfo &info = infoMap->get(shaderType, varName);
ShaderInterfaceVariableXfbInfo *xfb = &info->xfb; ShaderInterfaceVariableXfbInfo *xfb = &info.xfb;
if (fieldIndex >= 0) if (fieldIndex >= 0)
{ {
if (info->fieldXfb.size() <= static_cast<size_t>(fieldIndex)) if (info.fieldXfb.size() <= static_cast<size_t>(fieldIndex))
{ {
info->fieldXfb.resize(fieldIndex + 1); info.fieldXfb.resize(fieldIndex + 1);
} }
xfb = &info->fieldXfb[fieldIndex]; xfb = &info.fieldXfb[fieldIndex];
} }
ASSERT(xfb->buffer == ShaderInterfaceVariableXfbInfo::kInvalid); ASSERT(xfb->buffer == ShaderInterfaceVariableXfbInfo::kInvalid);
...@@ -301,7 +289,7 @@ ShaderInterfaceVariableInfo *SetXfbInfo(ShaderInterfaceVariableInfoMap *infoMap, ...@@ -301,7 +289,7 @@ ShaderInterfaceVariableInfo *SetXfbInfo(ShaderInterfaceVariableInfoMap *infoMap,
xfb->buffer = xfbBuffer; xfb->buffer = xfbBuffer;
xfb->offset = xfbOffset; xfb->offset = xfbOffset;
xfb->stride = xfbStride; xfb->stride = xfbStride;
return info; return &info;
} }
std::string SubstituteTransformFeedbackMarkers(const std::string &originalSource, std::string SubstituteTransformFeedbackMarkers(const std::string &originalSource,
...@@ -387,6 +375,7 @@ std::string GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVa ...@@ -387,6 +375,7 @@ std::string GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVa
} }
void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &options, void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &options,
gl::ShaderType shaderType,
const gl::ProgramState &programState, const gl::ProgramState &programState,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
std::string *vertexShader, std::string *vertexShader,
...@@ -416,9 +405,9 @@ void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &optio ...@@ -416,9 +405,9 @@ void GenerateTransformFeedbackEmulationOutputs(const GlslangSourceOptions &optio
// Add this entry to the info map, so we can easily assert that every resource has an entry // Add this entry to the info map, so we can easily assert that every resource has an entry
// in this map. // in this map.
AddResourceInfo(variableInfoMapOut, bufferName, AddResourceInfo(variableInfoMapOut, shaderType, bufferName,
programInterfaceInfo->uniformsAndXfbDescriptorSetIndex, programInterfaceInfo->uniformsAndXfbDescriptorSetIndex,
programInterfaceInfo->currentUniformBindingIndex, gl::ShaderType::Vertex); programInterfaceInfo->currentUniformBindingIndex);
++programInterfaceInfo->currentUniformBindingIndex; ++programInterfaceInfo->currentUniformBindingIndex;
} }
...@@ -520,7 +509,7 @@ void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programSt ...@@ -520,7 +509,7 @@ void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programSt
} }
void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable, void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
gl::ShaderType stage, gl::ShaderType shaderType,
ShaderInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
// Assign attribute locations for the vertex shader. // Assign attribute locations for the vertex shader.
...@@ -535,9 +524,8 @@ void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable, ...@@ -535,9 +524,8 @@ void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
const uint8_t componentCount = isMatrix ? rowCount : colCount; const uint8_t componentCount = isMatrix ? rowCount : colCount;
const uint8_t locationCount = isMatrix ? colCount : rowCount; const uint8_t locationCount = isMatrix ? colCount : rowCount;
AddLocationInfo(variableInfoMapOut, attribute.mappedName, attribute.location, AddLocationInfo(variableInfoMapOut, shaderType, attribute.mappedName, attribute.location,
ShaderInterfaceVariableInfo::kInvalid, stage, componentCount, ShaderInterfaceVariableInfo::kInvalid, componentCount, locationCount);
locationCount);
} }
} }
...@@ -573,8 +561,8 @@ void AssignOutputLocations(const gl::ProgramExecutable &programExecutable, ...@@ -573,8 +561,8 @@ void AssignOutputLocations(const gl::ProgramExecutable &programExecutable,
implicitOutputs.begin(), implicitOutputs.end()) == 1); implicitOutputs.begin(), implicitOutputs.end()) == 1);
} }
AddLocationInfo(variableInfoMapOut, outputVar.mappedName, location, AddLocationInfo(variableInfoMapOut, shaderType, outputVar.mappedName, location,
ShaderInterfaceVariableInfo::kInvalid, shaderType, 0, 0); ShaderInterfaceVariableInfo::kInvalid, 0, 0);
} }
} }
...@@ -583,8 +571,8 @@ void AssignOutputLocations(const gl::ProgramExecutable &programExecutable, ...@@ -583,8 +571,8 @@ void AssignOutputLocations(const gl::ProgramExecutable &programExecutable,
// location 0 to these entries, adding an entry for them here allows us to ASSERT that every // location 0 to these entries, adding an entry for them here allows us to ASSERT that every
// shader interface variable is processed during the SPIR-V transformation. This is done when // shader interface variable is processed during the SPIR-V transformation. This is done when
// iterating the ids provided by OpEntryPoint. // iterating the ids provided by OpEntryPoint.
AddLocationInfo(variableInfoMapOut, "webgl_FragColor", 0, 0, shaderType, 0, 0); AddLocationInfo(variableInfoMapOut, shaderType, "webgl_FragColor", 0, 0, 0, 0);
AddLocationInfo(variableInfoMapOut, "webgl_FragData", 0, 0, shaderType, 0, 0); AddLocationInfo(variableInfoMapOut, shaderType, "webgl_FragData", 0, 0, 0, 0);
} }
void AssignVaryingLocations(const GlslangSourceOptions &options, void AssignVaryingLocations(const GlslangSourceOptions &options,
...@@ -592,7 +580,7 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -592,7 +580,7 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType, const gl::ShaderType frontShaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
uint32_t locationsUsedForEmulation = programInterfaceInfo->locationsUsedForXfbExtension; uint32_t locationsUsedForEmulation = programInterfaceInfo->locationsUsedForXfbExtension;
...@@ -602,9 +590,9 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -602,9 +590,9 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
{ {
uint32_t lineRasterEmulationPositionLocation = locationsUsedForEmulation++; uint32_t lineRasterEmulationPositionLocation = locationsUsedForEmulation++;
AddLocationInfo(&(*variableInfoMapOut)[shaderType], sh::vk::kLineRasterEmulationPosition, AddLocationInfo(variableInfoMapOut, shaderType, sh::vk::kLineRasterEmulationPosition,
lineRasterEmulationPositionLocation, ShaderInterfaceVariableInfo::kInvalid, lineRasterEmulationPositionLocation, ShaderInterfaceVariableInfo::kInvalid,
shaderType, 0, 0); 0, 0);
} }
// Assign varying locations. // Assign varying locations.
...@@ -636,18 +624,14 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -636,18 +624,14 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
// being "_ufield". In such a case, use |parentStructMappedName|. // being "_ufield". In such a case, use |parentStructMappedName|.
if (varying.frontVarying.varying && (varying.frontVarying.stage == shaderType)) if (varying.frontVarying.varying && (varying.frontVarying.stage == shaderType))
{ {
ShaderInterfaceVariableInfoMap &infoMap = AddVaryingLocationInfo(variableInfoMapOut, varying.frontVarying,
(*variableInfoMapOut)[varying.frontVarying.stage]; varying.isStructField(), location, component);
AddVaryingLocationInfo(infoMap, varying.frontVarying, varying.isStructField(), location,
component);
} }
if (varying.backVarying.varying && (varying.backVarying.stage == shaderType)) if (varying.backVarying.varying && (varying.backVarying.stage == shaderType))
{ {
ShaderInterfaceVariableInfoMap &infoMap = AddVaryingLocationInfo(variableInfoMapOut, varying.backVarying, varying.isStructField(),
(*variableInfoMapOut)[varying.backVarying.stage]; location, component);
AddVaryingLocationInfo(infoMap, varying.backVarying, varying.isStructField(), location,
component);
} }
} }
...@@ -660,15 +644,14 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -660,15 +644,14 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
// If name is already in the map, it will automatically have marked all other stages // If name is already in the map, it will automatically have marked all other stages
// inactive. // inactive.
if ((*variableInfoMapOut)[shaderType].find(varyingName) != if (variableInfoMapOut->contains(shaderType, varyingName))
(*variableInfoMapOut)[shaderType].end())
{ {
continue; continue;
} }
// Otherwise, add an entry for it with all locations inactive. // Otherwise, add an entry for it with all locations inactive.
ShaderInterfaceVariableInfo *info = &(*variableInfoMapOut)[shaderType][varyingName]; ShaderInterfaceVariableInfo &info = variableInfoMapOut->addOrGet(shaderType, varyingName);
ASSERT(info->location == ShaderInterfaceVariableInfo::kInvalid); ASSERT(info.location == ShaderInterfaceVariableInfo::kInvalid);
} }
// Add an entry for active builtins varyings. This will allow inactive builtins, such as // Add an entry for active builtins varyings. This will allow inactive builtins, such as
...@@ -679,9 +662,9 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -679,9 +662,9 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
{ {
ASSERT(gl::IsBuiltInName(builtInName)); ASSERT(gl::IsBuiltInName(builtInName));
ShaderInterfaceVariableInfo *info = &(*variableInfoMapOut)[shaderType][builtInName]; ShaderInterfaceVariableInfo &info = variableInfoMapOut->addOrGet(shaderType, builtInName);
info->activeStages.set(shaderType); info.activeStages.set(shaderType);
info->varyingIsOutput = true; info.varyingIsOutput = true;
} }
// If an output builtin is active in the previous stage, assume it's active in the input of the // If an output builtin is active in the previous stage, assume it's active in the input of the
...@@ -692,9 +675,10 @@ void AssignVaryingLocations(const GlslangSourceOptions &options, ...@@ -692,9 +675,10 @@ void AssignVaryingLocations(const GlslangSourceOptions &options,
{ {
ASSERT(gl::IsBuiltInName(builtInName)); ASSERT(gl::IsBuiltInName(builtInName));
ShaderInterfaceVariableInfo *info = &(*variableInfoMapOut)[shaderType][builtInName]; ShaderInterfaceVariableInfo &info =
info->activeStages.set(shaderType); variableInfoMapOut->addOrGet(shaderType, builtInName);
info->varyingIsInput = true; info.activeStages.set(shaderType);
info.varyingIsInput = true;
} }
} }
} }
...@@ -747,10 +731,10 @@ void AssignTransformFeedbackExtensionQualifiers(const gl::ProgramExecutable &pro ...@@ -747,10 +731,10 @@ void AssignTransformFeedbackExtensionQualifiers(const gl::ProgramExecutable &pro
ASSERT(xfbVaryingLocation < locationsUsedForXfbExtension); ASSERT(xfbVaryingLocation < locationsUsedForXfbExtension);
AddLocationInfo(variableInfoMapOut, xfbVaryingName, xfbVaryingLocation, AddLocationInfo(variableInfoMapOut, shaderType, xfbVaryingName, xfbVaryingLocation,
ShaderInterfaceVariableInfo::kInvalid, shaderType, 0, 0); ShaderInterfaceVariableInfo::kInvalid, 0, 0);
SetXfbInfo(variableInfoMapOut, xfbVaryingName, -1, bufferIndex, currentOffset, SetXfbInfo(variableInfoMapOut, shaderType, xfbVaryingName, -1, bufferIndex,
currentStride); currentOffset, currentStride);
} }
else if (!tfVarying.isArray() || tfVarying.arrayIndex == GL_INVALID_INDEX) else if (!tfVarying.isArray() || tfVarying.arrayIndex == GL_INVALID_INDEX)
{ {
...@@ -809,8 +793,8 @@ void AssignTransformFeedbackExtensionQualifiers(const gl::ProgramExecutable &pro ...@@ -809,8 +793,8 @@ void AssignTransformFeedbackExtensionQualifiers(const gl::ProgramExecutable &pro
// Set xfb info for this varying. AssignVaryingLocations should have already added // Set xfb info for this varying. AssignVaryingLocations should have already added
// location information for these varyings. // location information for these varyings.
SetXfbInfo(variableInfoMapOut, mappedName, fieldIndex, bufferIndex, currentOffset, SetXfbInfo(variableInfoMapOut, shaderType, mappedName, fieldIndex, bufferIndex,
currentStride); currentOffset, currentStride);
} }
} }
} }
...@@ -820,18 +804,17 @@ void AssignUniformBindings(const GlslangSourceOptions &options, ...@@ -820,18 +804,17 @@ void AssignUniformBindings(const GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable, const gl::ProgramExecutable &programExecutable,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
if (programExecutable.hasLinkedShaderStage(shaderType)) if (programExecutable.hasLinkedShaderStage(shaderType))
{ {
AddResourceInfo(&(*variableInfoMapOut)[shaderType], kDefaultUniformNames[shaderType], AddResourceInfo(variableInfoMapOut, shaderType, kDefaultUniformNames[shaderType],
programInterfaceInfo->uniformsAndXfbDescriptorSetIndex, programInterfaceInfo->uniformsAndXfbDescriptorSetIndex,
programInterfaceInfo->currentUniformBindingIndex, shaderType); programInterfaceInfo->currentUniformBindingIndex);
++programInterfaceInfo->currentUniformBindingIndex; ++programInterfaceInfo->currentUniformBindingIndex;
// Assign binding to the driver uniforms block // Assign binding to the driver uniforms block
AddResourceInfoToAllStages(&(*variableInfoMapOut)[shaderType], AddResourceInfoToAllStages(variableInfoMapOut, shaderType, sh::vk::kDriverUniformsBlockName,
sh::vk::kDriverUniformsBlockName,
programInterfaceInfo->driverUniformsDescriptorSetIndex, 0); programInterfaceInfo->driverUniformsDescriptorSetIndex, 0);
} }
} }
...@@ -843,7 +826,7 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options, ...@@ -843,7 +826,7 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options,
const std::vector<gl::InterfaceBlock> &blocks, const std::vector<gl::InterfaceBlock> &blocks,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
for (const gl::InterfaceBlock &block : blocks) for (const gl::InterfaceBlock &block : blocks)
{ {
...@@ -852,10 +835,9 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options, ...@@ -852,10 +835,9 @@ void AssignInterfaceBlockBindings(const GlslangSourceOptions &options,
// TODO: http://anglebug.com/4523: All blocks should be active // TODO: http://anglebug.com/4523: All blocks should be active
if (programExecutable.hasLinkedShaderStage(shaderType) && block.isActive(shaderType)) if (programExecutable.hasLinkedShaderStage(shaderType) && block.isActive(shaderType))
{ {
AddResourceInfo(&(*variableInfoMapOut)[shaderType], block.mappedName, AddResourceInfo(variableInfoMapOut, shaderType, block.mappedName,
programInterfaceInfo->shaderResourceDescriptorSetIndex, programInterfaceInfo->shaderResourceDescriptorSetIndex,
programInterfaceInfo->currentShaderResourceBindingIndex, programInterfaceInfo->currentShaderResourceBindingIndex);
shaderType);
++programInterfaceInfo->currentShaderResourceBindingIndex; ++programInterfaceInfo->currentShaderResourceBindingIndex;
} }
} }
...@@ -869,7 +851,7 @@ void AssignAtomicCounterBufferBindings(const GlslangSourceOptions &options, ...@@ -869,7 +851,7 @@ void AssignAtomicCounterBufferBindings(const GlslangSourceOptions &options,
const std::vector<gl::AtomicCounterBuffer> &buffers, const std::vector<gl::AtomicCounterBuffer> &buffers,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
if (buffers.size() == 0) if (buffers.size() == 0)
{ {
...@@ -878,9 +860,9 @@ void AssignAtomicCounterBufferBindings(const GlslangSourceOptions &options, ...@@ -878,9 +860,9 @@ void AssignAtomicCounterBufferBindings(const GlslangSourceOptions &options,
if (programExecutable.hasLinkedShaderStage(shaderType)) if (programExecutable.hasLinkedShaderStage(shaderType))
{ {
AddResourceInfo(&(*variableInfoMapOut)[shaderType], sh::vk::kAtomicCountersBlockName, AddResourceInfo(variableInfoMapOut, shaderType, sh::vk::kAtomicCountersBlockName,
programInterfaceInfo->shaderResourceDescriptorSetIndex, programInterfaceInfo->shaderResourceDescriptorSetIndex,
programInterfaceInfo->currentShaderResourceBindingIndex, shaderType); programInterfaceInfo->currentShaderResourceBindingIndex);
++programInterfaceInfo->currentShaderResourceBindingIndex; ++programInterfaceInfo->currentShaderResourceBindingIndex;
} }
} }
...@@ -893,7 +875,7 @@ void AssignImageBindings(const GlslangSourceOptions &options, ...@@ -893,7 +875,7 @@ void AssignImageBindings(const GlslangSourceOptions &options,
const gl::RangeUI &imageUniformRange, const gl::RangeUI &imageUniformRange,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
for (unsigned int uniformIndex : imageUniformRange) for (unsigned int uniformIndex : imageUniformRange)
{ {
...@@ -904,10 +886,9 @@ void AssignImageBindings(const GlslangSourceOptions &options, ...@@ -904,10 +886,9 @@ void AssignImageBindings(const GlslangSourceOptions &options,
{ {
if (programExecutable.hasLinkedShaderStage(shaderType)) if (programExecutable.hasLinkedShaderStage(shaderType))
{ {
AddResourceInfo(&(*variableInfoMapOut)[shaderType], name, AddResourceInfo(variableInfoMapOut, shaderType, name,
programInterfaceInfo->shaderResourceDescriptorSetIndex, programInterfaceInfo->shaderResourceDescriptorSetIndex,
programInterfaceInfo->currentShaderResourceBindingIndex, programInterfaceInfo->currentShaderResourceBindingIndex);
shaderType);
++programInterfaceInfo->currentShaderResourceBindingIndex; ++programInterfaceInfo->currentShaderResourceBindingIndex;
} }
} }
...@@ -918,7 +899,7 @@ void AssignNonTextureBindings(const GlslangSourceOptions &options, ...@@ -918,7 +899,7 @@ void AssignNonTextureBindings(const GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable, const gl::ProgramExecutable &programExecutable,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
const std::vector<gl::InterfaceBlock> &uniformBlocks = programExecutable.getUniformBlocks(); const std::vector<gl::InterfaceBlock> &uniformBlocks = programExecutable.getUniformBlocks();
AssignInterfaceBlockBindings(options, programExecutable, uniformBlocks, shaderType, AssignInterfaceBlockBindings(options, programExecutable, uniformBlocks, shaderType,
...@@ -946,7 +927,7 @@ void AssignTextureBindings(const GlslangSourceOptions &options, ...@@ -946,7 +927,7 @@ void AssignTextureBindings(const GlslangSourceOptions &options,
const gl::ProgramExecutable &programExecutable, const gl::ProgramExecutable &programExecutable,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
// Assign textures to a descriptor set and binding. // Assign textures to a descriptor set and binding.
const std::vector<gl::LinkedUniform> &uniforms = programExecutable.getUniforms(); const std::vector<gl::LinkedUniform> &uniforms = programExecutable.getUniforms();
...@@ -972,9 +953,9 @@ void AssignTextureBindings(const GlslangSourceOptions &options, ...@@ -972,9 +953,9 @@ void AssignTextureBindings(const GlslangSourceOptions &options,
if (programExecutable.hasLinkedShaderStage(shaderType) && if (programExecutable.hasLinkedShaderStage(shaderType) &&
samplerUniform.isActive(shaderType)) samplerUniform.isActive(shaderType))
{ {
AddResourceInfo(&(*variableInfoMapOut)[shaderType], samplerName, AddResourceInfo(variableInfoMapOut, shaderType, samplerName,
programInterfaceInfo->textureDescriptorSetIndex, programInterfaceInfo->textureDescriptorSetIndex,
programInterfaceInfo->currentTextureBindingIndex, shaderType); programInterfaceInfo->currentTextureBindingIndex);
++programInterfaceInfo->currentTextureBindingIndex; ++programInterfaceInfo->currentTextureBindingIndex;
} }
} }
...@@ -1437,12 +1418,14 @@ class SpirvTransformer final : public SpirvTransformerBase ...@@ -1437,12 +1418,14 @@ class SpirvTransformer final : public SpirvTransformerBase
{ {
public: public:
SpirvTransformer(const std::vector<uint32_t> &spirvBlobIn, SpirvTransformer(const std::vector<uint32_t> &spirvBlobIn,
gl::ShaderType shaderType,
GlslangSpirvOptions options, GlslangSpirvOptions options,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
SpirvBlob *spirvBlobOut) SpirvBlob *spirvBlobOut)
: SpirvTransformerBase(spirvBlobIn, variableInfoMap, spirvBlobOut), : SpirvTransformerBase(spirvBlobIn, variableInfoMap, spirvBlobOut),
mOptions(options), mOptions(options),
mHasTransformFeedbackOutput(false), mHasTransformFeedbackOutput(false),
mShaderType(shaderType),
mOutputPerVertex{}, mOutputPerVertex{},
mInputPerVertex{} mInputPerVertex{}
{} {}
...@@ -1488,6 +1471,8 @@ class SpirvTransformer final : public SpirvTransformerBase ...@@ -1488,6 +1471,8 @@ class SpirvTransformer final : public SpirvTransformerBase
GlslangSpirvOptions mOptions; GlslangSpirvOptions mOptions;
bool mHasTransformFeedbackOutput; bool mHasTransformFeedbackOutput;
gl::ShaderType mShaderType;
// Traversal state: // Traversal state:
bool mInsertFunctionVariables = false; bool mInsertFunctionVariables = false;
uint32_t mEntryPointId = 0; uint32_t mEntryPointId = 0;
...@@ -1803,11 +1788,8 @@ void SpirvTransformer::visitDecorate(const uint32_t *instruction) ...@@ -1803,11 +1788,8 @@ void SpirvTransformer::visitDecorate(const uint32_t *instruction)
// http://anglebug.com/3606 // http://anglebug.com/3606
if (strcmp(name, "gl_PerVertex") != 0) if (strcmp(name, "gl_PerVertex") != 0)
{ {
auto infoIter = mVariableInfoMap.find(name); const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(mShaderType, name);
ASSERT(infoIter != mVariableInfoMap.end()); mVariableInfoById[id] = &info;
const ShaderInterfaceVariableInfo *info = &infoIter->second;
mVariableInfoById[id] = info;
} }
} }
} }
...@@ -1855,7 +1837,12 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) ...@@ -1855,7 +1837,12 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction)
return; return;
} }
auto infoIter = mVariableInfoMap.find(name); if (!mVariableInfoMap.contains(mShaderType, name))
{
return;
}
const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(mShaderType, name);
// Assume output gl_PerVertex is encountered first. When the storage class of these types are // Assume output gl_PerVertex is encountered first. When the storage class of these types are
// determined, the variables can be swapped if this assumption was incorrect. // determined, the variables can be swapped if this assumption was incorrect.
...@@ -1864,10 +1851,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) ...@@ -1864,10 +1851,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction)
mOutputPerVertex.typeId = id; mOutputPerVertex.typeId = id;
// Keep track of the range of members that are active. // Keep track of the range of members that are active.
const bool isActive = if (info.varyingIsOutput && member > mOutputPerVertex.maxActiveMember)
infoIter != mVariableInfoMap.end() && infoIter->second.varyingIsOutput;
if (isActive && member > mOutputPerVertex.maxActiveMember)
{ {
mOutputPerVertex.maxActiveMember = member; mOutputPerVertex.maxActiveMember = member;
} }
...@@ -1877,9 +1861,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction) ...@@ -1877,9 +1861,7 @@ void SpirvTransformer::visitMemberName(const uint32_t *instruction)
mInputPerVertex.typeId = id; mInputPerVertex.typeId = id;
// Keep track of the range of members that are active. // Keep track of the range of members that are active.
const bool isActive = infoIter != mVariableInfoMap.end() && infoIter->second.varyingIsInput; if (info.varyingIsInput && member > mInputPerVertex.maxActiveMember)
if (isActive && member > mInputPerVertex.maxActiveMember)
{ {
mInputPerVertex.maxActiveMember = member; mInputPerVertex.maxActiveMember = member;
} }
...@@ -2005,15 +1987,12 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) ...@@ -2005,15 +1987,12 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction)
} }
// Every shader interface variable should have an associated data. // Every shader interface variable should have an associated data.
auto infoIter = mVariableInfoMap.find(name); const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(mShaderType, name);
ASSERT(infoIter != mVariableInfoMap.end());
const ShaderInterfaceVariableInfo *info = &infoIter->second;
// Associate the id of this name with its info. // Associate the id of this name with its info.
mVariableInfoById[id] = info; mVariableInfoById[id] = &info;
if (info && info->useRelaxedPrecision && info->activeStages[mOptions.shaderType] && if (info.useRelaxedPrecision && info.activeStages[mOptions.shaderType] &&
mFixedVaryingId[id] == 0) mFixedVaryingId[id] == 0)
{ {
mFixedVaryingId[id] = getNewId(); mFixedVaryingId[id] = getNewId();
...@@ -2023,8 +2002,8 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) ...@@ -2023,8 +2002,8 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction)
// Note if the variable is captured by transform feedback. In that case, the TransformFeedback // Note if the variable is captured by transform feedback. In that case, the TransformFeedback
// capability needs to be added. // capability needs to be added.
if (mOptions.shaderType != gl::ShaderType::Fragment && if (mOptions.shaderType != gl::ShaderType::Fragment &&
(info->xfb.buffer != ShaderInterfaceVariableInfo::kInvalid || !info->fieldXfb.empty()) && (info.xfb.buffer != ShaderInterfaceVariableInfo::kInvalid || !info.fieldXfb.empty()) &&
info->activeStages[mOptions.shaderType]) info.activeStages[mOptions.shaderType])
{ {
mHasTransformFeedbackOutput = true; mHasTransformFeedbackOutput = true;
} }
...@@ -3601,7 +3580,7 @@ bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap ...@@ -3601,7 +3580,7 @@ bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap
{ {
gl::AttributesMask isLocationAssigned; gl::AttributesMask isLocationAssigned;
for (const auto &infoIter : variableInfoMap) for (const auto &infoIter : variableInfoMap.getIterator(gl::ShaderType::Vertex))
{ {
const ShaderInterfaceVariableInfo &info = infoIter.second; const ShaderInterfaceVariableInfo &info = infoIter.second;
...@@ -3633,10 +3612,67 @@ bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap ...@@ -3633,10 +3612,67 @@ bool HasAliasingAttributes(const ShaderInterfaceVariableInfoMap &variableInfoMap
} }
} // anonymous namespace } // anonymous namespace
// ShaderInterfaceVariableInfo implementation.
const uint32_t ShaderInterfaceVariableInfo::kInvalid; const uint32_t ShaderInterfaceVariableInfo::kInvalid;
ShaderInterfaceVariableInfo::ShaderInterfaceVariableInfo() {} ShaderInterfaceVariableInfo::ShaderInterfaceVariableInfo() {}
// ShaderInterfaceVariableInfoMap implementation.
ShaderInterfaceVariableInfoMap::ShaderInterfaceVariableInfoMap() = default;
ShaderInterfaceVariableInfoMap::~ShaderInterfaceVariableInfoMap() = default;
void ShaderInterfaceVariableInfoMap::clear()
{
for (VariableNameToInfoMap &shaderMap : mData)
{
shaderMap.clear();
}
}
bool ShaderInterfaceVariableInfoMap::contains(gl::ShaderType shaderType,
const std::string &variableName) const
{
return mData[shaderType].find(variableName) != mData[shaderType].end();
}
const ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::get(
gl::ShaderType shaderType,
const std::string &variableName) const
{
auto it = mData[shaderType].find(variableName);
ASSERT(it != mData[shaderType].end());
return it->second;
}
ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::get(gl::ShaderType shaderType,
const std::string &variableName)
{
auto it = mData[shaderType].find(variableName);
ASSERT(it != mData[shaderType].end());
return it->second;
}
ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::add(gl::ShaderType shaderType,
const std::string &variableName)
{
ASSERT(!contains(shaderType, variableName));
return mData[shaderType][variableName];
}
ShaderInterfaceVariableInfo &ShaderInterfaceVariableInfoMap::addOrGet(
gl::ShaderType shaderType,
const std::string &variableName)
{
return mData[shaderType][variableName];
}
ShaderInterfaceVariableInfoMap::Iterator ShaderInterfaceVariableInfoMap::getIterator(
gl::ShaderType shaderType) const
{
return Iterator(mData[shaderType].begin(), mData[shaderType].end());
}
void GlslangInitialize() void GlslangInitialize()
{ {
int result = ShInitialize(); int result = ShInitialize();
...@@ -3734,8 +3770,9 @@ void GlslangGenTransformFeedbackEmulationOutputs(const GlslangSourceOptions &opt ...@@ -3734,8 +3770,9 @@ void GlslangGenTransformFeedbackEmulationOutputs(const GlslangSourceOptions &opt
std::string *vertexShader, std::string *vertexShader,
ShaderInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
GenerateTransformFeedbackEmulationOutputs(options, programState, programInterfaceInfo, GenerateTransformFeedbackEmulationOutputs(options, gl::ShaderType::Vertex, programState,
vertexShader, variableInfoMapOut); programInterfaceInfo, vertexShader,
variableInfoMapOut);
} }
void GlslangAssignLocations(const GlslangSourceOptions &options, void GlslangAssignLocations(const GlslangSourceOptions &options,
...@@ -3743,22 +3780,20 @@ void GlslangAssignLocations(const GlslangSourceOptions &options, ...@@ -3743,22 +3780,20 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType, const gl::ShaderType frontShaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
// Assign outputs to the fragment shader, if any. // Assign outputs to the fragment shader, if any.
if ((shaderType == gl::ShaderType::Fragment) && if ((shaderType == gl::ShaderType::Fragment) &&
programExecutable.hasLinkedShaderStage(gl::ShaderType::Fragment)) programExecutable.hasLinkedShaderStage(gl::ShaderType::Fragment))
{ {
AssignOutputLocations(programExecutable, gl::ShaderType::Fragment, AssignOutputLocations(programExecutable, gl::ShaderType::Fragment, variableInfoMapOut);
&(*variableInfoMapOut)[gl::ShaderType::Fragment]);
} }
// Assign attributes to the vertex shader, if any. // Assign attributes to the vertex shader, if any.
if ((shaderType == gl::ShaderType::Vertex) && if ((shaderType == gl::ShaderType::Vertex) &&
programExecutable.hasLinkedShaderStage(gl::ShaderType::Vertex)) programExecutable.hasLinkedShaderStage(gl::ShaderType::Vertex))
{ {
AssignAttributeLocations(programExecutable, gl::ShaderType::Vertex, AssignAttributeLocations(programExecutable, gl::ShaderType::Vertex, variableInfoMapOut);
&(*variableInfoMapOut)[gl::ShaderType::Vertex]);
} }
if (!programExecutable.hasLinkedShaderStage(gl::ShaderType::Compute)) if (!programExecutable.hasLinkedShaderStage(gl::ShaderType::Compute))
...@@ -3773,7 +3808,7 @@ void GlslangAssignLocations(const GlslangSourceOptions &options, ...@@ -3773,7 +3808,7 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
{ {
AssignTransformFeedbackExtensionQualifiers( AssignTransformFeedbackExtensionQualifiers(
programExecutable, programInterfaceInfo->locationsUsedForXfbExtension, shaderType, programExecutable, programInterfaceInfo->locationsUsedForXfbExtension, shaderType,
&(*variableInfoMapOut)[shaderType]); variableInfoMapOut);
} }
} }
...@@ -3790,7 +3825,7 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -3790,7 +3825,7 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) for (const gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
...@@ -3815,9 +3850,9 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -3815,9 +3850,9 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
else if (options.emulateTransformFeedback) else if (options.emulateTransformFeedback)
{ {
ASSERT(xfbStage == gl::ShaderType::Vertex); ASSERT(xfbStage == gl::ShaderType::Vertex);
GenerateTransformFeedbackEmulationOutputs(options, programState, GenerateTransformFeedbackEmulationOutputs(options, xfbStage, programState,
programInterfaceInfo, xfbSource, programInterfaceInfo, xfbSource,
&(*variableInfoMapOut)[xfbStage]); variableInfoMapOut);
} }
else else
{ {
...@@ -3855,6 +3890,7 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -3855,6 +3890,7 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
const GlslangSpirvOptions &options, const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob, const SpirvBlob &initialSpirvBlob,
SpirvBlob *spirvBlobOut) SpirvBlob *spirvBlobOut)
...@@ -3873,7 +3909,8 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, ...@@ -3873,7 +3909,8 @@ angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
#endif // defined(ANGLE_DEBUG_SPIRV_TRANSFORMER) && ANGLE_DEBUG_SPIRV_TRANSFORMER #endif // defined(ANGLE_DEBUG_SPIRV_TRANSFORMER) && ANGLE_DEBUG_SPIRV_TRANSFORMER
// Transform the SPIR-V code by assigning location/set/binding values. // Transform the SPIR-V code by assigning location/set/binding values.
SpirvTransformer transformer(initialSpirvBlob, options, variableInfoMap, spirvBlobOut); SpirvTransformer transformer(initialSpirvBlob, shaderType, options, variableInfoMap,
spirvBlobOut);
ANGLE_GLSLANG_CHECK(callback, transformer.transform(), GlslangError::InvalidSpirv); ANGLE_GLSLANG_CHECK(callback, transformer.transform(), GlslangError::InvalidSpirv);
// If there are aliasing vertex attributes, transform the SPIR-V again to remove them. // If there are aliasing vertex attributes, transform the SPIR-V again to remove them.
......
...@@ -111,10 +111,46 @@ struct ShaderInterfaceVariableInfo ...@@ -111,10 +111,46 @@ struct ShaderInterfaceVariableInfo
uint8_t attributeLocationCount = 0; uint8_t attributeLocationCount = 0;
}; };
// TODO: http://anglebug.com/4524: Need a different hash key than a string, since // TODO: http://anglebug.com/4524: Need a different hash key than a string, since that's slow to
// that's slow to calculate. // calculate.
using ShaderInterfaceVariableInfoMap = angle::HashMap<std::string, ShaderInterfaceVariableInfo>; class ShaderInterfaceVariableInfoMap final : angle::NonCopyable
using ShaderMapInterfaceVariableInfoMap = gl::ShaderMap<ShaderInterfaceVariableInfoMap>; {
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 GlslangInitialize();
void GlslangRelease(); void GlslangRelease();
...@@ -139,7 +175,7 @@ void GlslangAssignLocations(const GlslangSourceOptions &options, ...@@ -139,7 +175,7 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const gl::ShaderType frontShaderType, const gl::ShaderType frontShaderType,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<ShaderInterfaceVariableInfoMap> *variableInfoMapOut); ShaderInterfaceVariableInfoMap *variableInfoMapOut);
// Transform the source to include actual binding points for various shader resources (textures, // 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 // buffers, xfb, etc). For some variables, these values are instead output to the variableInfoMap
...@@ -150,10 +186,11 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -150,10 +186,11 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut); ShaderInterfaceVariableInfoMap *variableInfoMapOut);
angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback, angle::Result GlslangTransformSpirvCode(const GlslangErrorCallback &callback,
const GlslangSpirvOptions &options, const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob, const SpirvBlob &initialSpirvBlob,
SpirvBlob *spirvBlobOut); SpirvBlob *spirvBlobOut);
......
...@@ -318,11 +318,11 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, ...@@ -318,11 +318,11 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
// Gather variable info and transform sources. // Gather variable info and transform sources.
gl::ShaderMap<std::string> shaderSources; gl::ShaderMap<std::string> shaderSources;
gl::ShaderMap<std::string> xfbOnlyShaderSources; gl::ShaderMap<std::string> xfbOnlyShaderSources;
ShaderMapInterfaceVariableInfoMap variableInfoMap; ShaderInterfaceVariableInfoMap variableInfoMap;
ShaderMapInterfaceVariableInfoMap xfbOnlyVariableInfoMap; ShaderInterfaceVariableInfoMap xfbOnlyVariableInfoMap;
mtl::GlslangGetShaderSource(mState, resources, &shaderSources, mtl::GlslangGetShaderSource(mState, resources, &shaderSources,
&xfbOnlyShaderSources[gl::ShaderType::Vertex], &variableInfoMap, &xfbOnlyShaderSources[gl::ShaderType::Vertex], &variableInfoMap,
&xfbOnlyVariableInfoMap[gl::ShaderType::Vertex]); &xfbOnlyVariableInfoMap);
// Convert GLSL to spirv code // Convert GLSL to spirv code
gl::ShaderMap<std::vector<uint32_t>> shaderCodes; gl::ShaderMap<std::vector<uint32_t>> shaderCodes;
...@@ -341,8 +341,7 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, ...@@ -341,8 +341,7 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext,
} }
// Convert spirv code to MSL // Convert spirv code to MSL
ANGLE_TRY(mtl::SpirvCodeToMsl(contextMtl, mState, ANGLE_TRY(mtl::SpirvCodeToMsl(contextMtl, mState, xfbOnlyVariableInfoMap, &shaderCodes,
xfbOnlyVariableInfoMap[gl::ShaderType::Vertex], &shaderCodes,
&xfbOnlyShaderCodes[gl::ShaderType::Vertex], &xfbOnlyShaderCodes[gl::ShaderType::Vertex],
&mMslShaderTranslateInfo, &mMslXfbOnlyVertexShaderInfo)); &mMslShaderTranslateInfo, &mMslXfbOnlyVertexShaderInfo));
......
...@@ -47,14 +47,14 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -47,14 +47,14 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
std::string *xfbOnlyShaderSourceOut, std::string *xfbOnlyShaderSourceOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut, ShaderInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut); ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut);
angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut); gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut);
// Translate from SPIR-V code to Metal shader source code. // Translate from SPIR-V code to Metal shader source code.
......
...@@ -407,7 +407,7 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -407,7 +407,7 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
std::string *xfbOnlyShaderSourceOut, std::string *xfbOnlyShaderSourceOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut, ShaderInterfaceVariableInfoMap *variableInfoMapOut,
ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut) ShaderInterfaceVariableInfoMap *xfbOnlyVSVariableInfoMapOut)
{ {
GlslangSourceOptions options = CreateSourceOptions(); GlslangSourceOptions options = CreateSourceOptions();
...@@ -425,18 +425,16 @@ void GlslangGetShaderSource(const gl::ProgramState &programState, ...@@ -425,18 +425,16 @@ void GlslangGetShaderSource(const gl::ProgramState &programState,
GlslangProgramInterfaceInfo xfbOnlyInterfaceInfo; GlslangProgramInterfaceInfo xfbOnlyInterfaceInfo;
ResetGlslangProgramInterfaceInfo(&xfbOnlyInterfaceInfo); ResetGlslangProgramInterfaceInfo(&xfbOnlyInterfaceInfo);
ShaderMapInterfaceVariableInfoMap xfbOnlyVariableMaps;
options.emulateTransformFeedback = true; options.emulateTransformFeedback = true;
rx::GlslangGenTransformFeedbackEmulationOutputs( rx::GlslangGenTransformFeedbackEmulationOutputs(
options, programState, &xfbOnlyInterfaceInfo, xfbOnlyShaderSourceOut, options, programState, &xfbOnlyInterfaceInfo, xfbOnlyShaderSourceOut,
&xfbOnlyVariableMaps[gl::ShaderType::Vertex]); xfbOnlyVSVariableInfoMapOut);
GlslangAssignLocations(options, programState.getExecutable(), gl::ShaderType::Vertex, GlslangAssignLocations(options, programState.getExecutable(), gl::ShaderType::Vertex,
gl::ShaderType::InvalidEnum, &xfbOnlyInterfaceInfo, gl::ShaderType::InvalidEnum, &xfbOnlyInterfaceInfo,
&xfbOnlyVariableMaps); xfbOnlyVSVariableInfoMapOut);
*xfbOnlyVSVariableInfoMapOut = std::move(xfbOnlyVariableMaps[gl::ShaderType::Vertex]);
} }
} }
...@@ -444,7 +442,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, ...@@ -444,7 +442,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
const gl::Caps &glCaps, const gl::Caps &glCaps,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
const ShaderMapInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut) gl::ShaderMap<std::vector<uint32_t>> *shaderCodeOut)
{ {
gl::ShaderMap<SpirvBlob> initialSpirvBlobs; gl::ShaderMap<SpirvBlob> initialSpirvBlobs;
...@@ -460,7 +458,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context, ...@@ -460,7 +458,7 @@ angle::Result GlslangGetShaderSpirvCode(ErrorHandler *context,
angle::Result status = GlslangTransformSpirvCode( angle::Result status = GlslangTransformSpirvCode(
[context](GlslangError error) { return HandleError(context, error); }, options, [context](GlslangError error) { return HandleError(context, error); }, options,
variableInfoMap[shaderType], initialSpirvBlobs[shaderType], shaderType, variableInfoMap, initialSpirvBlobs[shaderType],
&(*shaderCodeOut)[shaderType]); &(*shaderCodeOut)[shaderType]);
if (status != angle::Result::Continue) if (status != angle::Result::Continue)
{ {
...@@ -495,9 +493,11 @@ angle::Result SpirvCodeToMsl(Context *context, ...@@ -495,9 +493,11 @@ angle::Result SpirvCodeToMsl(Context *context,
for (uint32_t bufferIdx = 0; bufferIdx < kMaxShaderXFBs; ++bufferIdx) for (uint32_t bufferIdx = 0; bufferIdx < kMaxShaderXFBs; ++bufferIdx)
{ {
std::string bufferName = rx::GetXfbBufferName(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, ...@@ -62,7 +62,7 @@ void GlslangWrapperVk::GetShaderSource(const angle::FeaturesVk &features,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
{ {
GlslangSourceOptions options = CreateSourceOptions(features); GlslangSourceOptions options = CreateSourceOptions(features);
GlslangGetShaderSource(options, programState, resources, programInterfaceInfo, shaderSourcesOut, GlslangGetShaderSource(options, programState, resources, programInterfaceInfo, shaderSourcesOut,
...@@ -85,12 +85,13 @@ angle::Result GlslangWrapperVk::GetShaderCode(vk::Context *context, ...@@ -85,12 +85,13 @@ angle::Result GlslangWrapperVk::GetShaderCode(vk::Context *context,
angle::Result GlslangWrapperVk::TransformSpirV( angle::Result GlslangWrapperVk::TransformSpirV(
vk::Context *context, vk::Context *context,
const GlslangSpirvOptions &options, const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob, const SpirvBlob &initialSpirvBlob,
SpirvBlob *shaderCodeOut) SpirvBlob *shaderCodeOut)
{ {
return GlslangTransformSpirvCode( return GlslangTransformSpirvCode(
[context](GlslangError error) { return ErrorHandler(context, error); }, options, [context](GlslangError error) { return ErrorHandler(context, error); }, options, shaderType,
variableInfoMap, initialSpirvBlob, shaderCodeOut); variableInfoMap, initialSpirvBlob, shaderCodeOut);
} }
......
...@@ -35,7 +35,7 @@ class GlslangWrapperVk ...@@ -35,7 +35,7 @@ class GlslangWrapperVk
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
GlslangProgramInterfaceInfo *programInterfaceInfo, GlslangProgramInterfaceInfo *programInterfaceInfo,
gl::ShaderMap<std::string> *shaderSourcesOut, gl::ShaderMap<std::string> *shaderSourcesOut,
ShaderMapInterfaceVariableInfoMap *variableInfoMapOut); ShaderInterfaceVariableInfoMap *variableInfoMapOut);
static angle::Result GetShaderCode(vk::Context *context, static angle::Result GetShaderCode(vk::Context *context,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
...@@ -45,6 +45,7 @@ class GlslangWrapperVk ...@@ -45,6 +45,7 @@ class GlslangWrapperVk
static angle::Result TransformSpirV(vk::Context *context, static angle::Result TransformSpirV(vk::Context *context,
const GlslangSpirvOptions &options, const GlslangSpirvOptions &options,
gl::ShaderType shaderType,
const ShaderInterfaceVariableInfoMap &variableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
const SpirvBlob &initialSpirvBlob, const SpirvBlob &initialSpirvBlob,
SpirvBlob *shaderCodeOut); SpirvBlob *shaderCodeOut);
......
...@@ -25,7 +25,7 @@ namespace ...@@ -25,7 +25,7 @@ namespace
{ {
bool ValidateTransformedSpirV(ContextVk *contextVk, bool ValidateTransformedSpirV(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
ProgramExecutableVk *executableVk, const ShaderInterfaceVariableInfoMap &variableInfoMap,
const gl::ShaderMap<SpirvBlob> &spirvBlobs) const gl::ShaderMap<SpirvBlob> &spirvBlobs)
{ {
for (gl::ShaderType shaderType : linkedShaderStages) for (gl::ShaderType shaderType : linkedShaderStages)
...@@ -35,9 +35,9 @@ bool ValidateTransformedSpirV(ContextVk *contextVk, ...@@ -35,9 +35,9 @@ bool ValidateTransformedSpirV(ContextVk *contextVk,
options.removeDebugInfo = true; options.removeDebugInfo = true;
SpirvBlob transformed; SpirvBlob transformed;
if (GlslangWrapperVk::TransformSpirV( if (GlslangWrapperVk::TransformSpirV(contextVk, options, shaderType, variableInfoMap,
contextVk, options, executableVk->getShaderInterfaceVariableInfoMap()[shaderType], spirvBlobs[shaderType],
spirvBlobs[shaderType], &transformed) != angle::Result::Continue) &transformed) != angle::Result::Continue)
{ {
return false; return false;
} }
...@@ -58,7 +58,7 @@ ShaderInfo::~ShaderInfo() = default; ...@@ -58,7 +58,7 @@ ShaderInfo::~ShaderInfo() = default;
angle::Result ShaderInfo::initShaders(ContextVk *contextVk, angle::Result ShaderInfo::initShaders(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
ProgramExecutableVk *executableVk) const ShaderInterfaceVariableInfoMap &variableInfoMap)
{ {
ASSERT(!valid()); ASSERT(!valid());
...@@ -66,7 +66,7 @@ angle::Result ShaderInfo::initShaders(ContextVk *contextVk, ...@@ -66,7 +66,7 @@ angle::Result ShaderInfo::initShaders(ContextVk *contextVk,
shaderSources, &mSpirvBlobs)); shaderSources, &mSpirvBlobs));
// Assert that SPIR-V transformation is correct, even if the test never issues a draw call. // Assert that SPIR-V transformation is correct, even if the test never issues a draw call.
ASSERT(ValidateTransformedSpirV(contextVk, linkedShaderStages, executableVk, mSpirvBlobs)); ASSERT(ValidateTransformedSpirV(contextVk, linkedShaderStages, variableInfoMap, mSpirvBlobs));
mIsInitialized = true; mIsInitialized = true;
return angle::Result::Continue; return angle::Result::Continue;
...@@ -118,10 +118,8 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk, ...@@ -118,10 +118,8 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo, const ShaderInfo &shaderInfo,
ProgramTransformOptions optionBits, ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk) const ShaderInterfaceVariableInfoMap &variableInfoMap)
{ {
const ShaderMapInterfaceVariableInfoMap &variableInfoMap =
executableVk->getShaderInterfaceVariableInfoMap();
const gl::ShaderMap<SpirvBlob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs(); const gl::ShaderMap<SpirvBlob> &originalSpirvBlobs = shaderInfo.getSpirvBlobs();
const SpirvBlob &originalSpirvBlob = originalSpirvBlobs[shaderType]; const SpirvBlob &originalSpirvBlob = originalSpirvBlobs[shaderType];
gl::ShaderMap<SpirvBlob> transformedSpirvBlobs; gl::ShaderMap<SpirvBlob> transformedSpirvBlobs;
...@@ -133,7 +131,7 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk, ...@@ -133,7 +131,7 @@ angle::Result ProgramInfo::initProgram(ContextVk *contextVk,
shaderType == gl::ShaderType::Fragment && optionBits.removeEarlyFragmentTestsOptimization; shaderType == gl::ShaderType::Fragment && optionBits.removeEarlyFragmentTestsOptimization;
options.removeDebugInfo = !contextVk->getRenderer()->getEnableValidationLayers(); options.removeDebugInfo = !contextVk->getRenderer()->getEnableValidationLayers();
ANGLE_TRY(GlslangWrapperVk::TransformSpirV(contextVk, options, variableInfoMap[shaderType], ANGLE_TRY(GlslangWrapperVk::TransformSpirV(contextVk, options, shaderType, variableInfoMap,
originalSpirvBlob, &transformedSpirvBlob)); originalSpirvBlob, &transformedSpirvBlob));
ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[shaderType].get(), ANGLE_TRY(vk::InitShaderAndSerial(contextVk, &mShaders[shaderType].get(),
transformedSpirvBlob.data(), transformedSpirvBlob.data(),
...@@ -222,29 +220,29 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream * ...@@ -222,29 +220,29 @@ std::unique_ptr<rx::LinkEvent> ProgramExecutableVk::load(gl::BinaryInputStream *
for (size_t i = 0; i < variableInfoMapSize; ++i) for (size_t i = 0; i < variableInfoMapSize; ++i)
{ {
const std::string variableName = stream->readString(); const std::string variableName = stream->readString();
ShaderInterfaceVariableInfo *info = &mVariableInfoMap[shaderType][variableName]; ShaderInterfaceVariableInfo &info = mVariableInfoMap.add(shaderType, variableName);
info->descriptorSet = stream->readInt<uint32_t>(); info.descriptorSet = stream->readInt<uint32_t>();
info->binding = stream->readInt<uint32_t>(); info.binding = stream->readInt<uint32_t>();
info->location = stream->readInt<uint32_t>(); info.location = stream->readInt<uint32_t>();
info->component = stream->readInt<uint32_t>(); info.component = stream->readInt<uint32_t>();
// PackedEnumBitSet uses uint8_t // PackedEnumBitSet uses uint8_t
info->activeStages = gl::ShaderBitSet(stream->readInt<uint8_t>()); info.activeStages = gl::ShaderBitSet(stream->readInt<uint8_t>());
info->xfb.buffer = stream->readInt<uint32_t>(); info.xfb.buffer = stream->readInt<uint32_t>();
info->xfb.offset = stream->readInt<uint32_t>(); info.xfb.offset = stream->readInt<uint32_t>();
info->xfb.stride = stream->readInt<uint32_t>(); info.xfb.stride = stream->readInt<uint32_t>();
info->fieldXfb.resize(stream->readInt<size_t>()); info.fieldXfb.resize(stream->readInt<size_t>());
for (ShaderInterfaceVariableXfbInfo &xfb : info->fieldXfb) for (ShaderInterfaceVariableXfbInfo &xfb : info.fieldXfb)
{ {
xfb.buffer = stream->readInt<uint32_t>(); xfb.buffer = stream->readInt<uint32_t>();
xfb.offset = stream->readInt<uint32_t>(); xfb.offset = stream->readInt<uint32_t>();
xfb.stride = stream->readInt<uint32_t>(); xfb.stride = stream->readInt<uint32_t>();
} }
info->useRelaxedPrecision = stream->readBool(); info.useRelaxedPrecision = stream->readBool();
info->varyingIsInput = stream->readBool(); info.varyingIsInput = stream->readBool();
info->varyingIsOutput = stream->readBool(); info.varyingIsOutput = stream->readBool();
info->attributeComponentCount = stream->readInt<uint8_t>(); info.attributeComponentCount = stream->readInt<uint8_t>();
info->attributeLocationCount = stream->readInt<uint8_t>(); info.attributeLocationCount = stream->readInt<uint8_t>();
} }
} }
...@@ -255,41 +253,41 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream) ...@@ -255,41 +253,41 @@ void ProgramExecutableVk::save(gl::BinaryOutputStream *stream)
{ {
for (gl::ShaderType shaderType : gl::AllShaderTypes()) for (gl::ShaderType shaderType : gl::AllShaderTypes())
{ {
stream->writeInt(mVariableInfoMap[shaderType].size()); stream->writeInt(mVariableInfoMap.variableCount(shaderType));
for (const auto &it : mVariableInfoMap[shaderType]) for (const auto &it : mVariableInfoMap.getIterator(shaderType))
{ {
stream->writeString(it.first); const std::string &name = it.first;
stream->writeInt(it.second.descriptorSet); const ShaderInterfaceVariableInfo &info = it.second;
stream->writeInt(it.second.binding);
stream->writeInt(it.second.location); stream->writeString(name);
stream->writeInt(it.second.component); stream->writeInt(info.descriptorSet);
stream->writeInt(info.binding);
stream->writeInt(info.location);
stream->writeInt(info.component);
// PackedEnumBitSet uses uint8_t // PackedEnumBitSet uses uint8_t
stream->writeInt(it.second.activeStages.bits()); stream->writeInt(info.activeStages.bits());
stream->writeInt(it.second.xfb.buffer); stream->writeInt(info.xfb.buffer);
stream->writeInt(it.second.xfb.offset); stream->writeInt(info.xfb.offset);
stream->writeInt(it.second.xfb.stride); stream->writeInt(info.xfb.stride);
stream->writeInt(it.second.fieldXfb.size()); stream->writeInt(info.fieldXfb.size());
for (const ShaderInterfaceVariableXfbInfo &xfb : it.second.fieldXfb) for (const ShaderInterfaceVariableXfbInfo &xfb : info.fieldXfb)
{ {
stream->writeInt(xfb.buffer); stream->writeInt(xfb.buffer);
stream->writeInt(xfb.offset); stream->writeInt(xfb.offset);
stream->writeInt(xfb.stride); stream->writeInt(xfb.stride);
} }
stream->writeBool(it.second.useRelaxedPrecision); stream->writeBool(info.useRelaxedPrecision);
stream->writeBool(it.second.varyingIsInput); stream->writeBool(info.varyingIsInput);
stream->writeBool(it.second.varyingIsOutput); stream->writeBool(info.varyingIsOutput);
stream->writeInt(it.second.attributeComponentCount); stream->writeInt(info.attributeComponentCount);
stream->writeInt(it.second.attributeLocationCount); stream->writeInt(info.attributeLocationCount);
} }
} }
} }
void ProgramExecutableVk::clearVariableInfoMap() void ProgramExecutableVk::clearVariableInfoMap()
{ {
for (const gl::ShaderType shaderType : gl::AllShaderTypes()) mVariableInfoMap.clear();
{
mVariableInfoMap[shaderType].clear();
}
} }
ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState, ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState,
...@@ -454,7 +452,7 @@ void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc( ...@@ -454,7 +452,7 @@ void ProgramExecutableVk::addInterfaceBlockDescriptorSetDesc(
} }
const std::string blockName = block.mappedName; const std::string blockName = block.mappedName;
const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, blockName);
descOut->update(info.binding, descType, arraySize, gl_vk::kShaderStageMap[shaderType], descOut->update(info.binding, descType, arraySize, gl_vk::kShaderStageMap[shaderType],
nullptr); nullptr);
...@@ -472,7 +470,7 @@ void ProgramExecutableVk::addAtomicCounterBufferDescriptorSetDesc( ...@@ -472,7 +470,7 @@ void ProgramExecutableVk::addAtomicCounterBufferDescriptorSetDesc(
} }
std::string blockName(sh::vk::kAtomicCountersBlockName); std::string blockName(sh::vk::kAtomicCountersBlockName);
const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, blockName);
if (!info.activeStages[shaderType]) if (!info.activeStages[shaderType])
{ {
...@@ -529,7 +527,7 @@ void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable ...@@ -529,7 +527,7 @@ void ProgramExecutableVk::addImageDescriptorSetDesc(const gl::ProgramExecutable
} }
GetImageNameWithoutIndices(&imageName); GetImageNameWithoutIndices(&imageName);
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][imageName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, imageName);
VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType]; VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType];
const VkDescriptorType descType = imageBinding.textureType == gl::TextureType::Buffer const VkDescriptorType descType = imageBinding.textureType == gl::TextureType::Buffer
...@@ -586,7 +584,7 @@ void ProgramExecutableVk::addTextureDescriptorSetDesc( ...@@ -586,7 +584,7 @@ void ProgramExecutableVk::addTextureDescriptorSetDesc(
continue; continue;
} }
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][samplerName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, samplerName);
VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType]; VkShaderStageFlags activeStages = gl_vk::kShaderStageMap[shaderType];
// TODO: https://issuetracker.google.com/issues/158215272: how do we handle array of // TODO: https://issuetracker.google.com/issues/158215272: how do we handle array of
...@@ -696,7 +694,7 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -696,7 +694,7 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
if (programVk) if (programVk)
{ {
ANGLE_TRY(programVk->initGraphicsShaderProgram(contextVk, shaderType, mTransformOptions, ANGLE_TRY(programVk->initGraphicsShaderProgram(contextVk, shaderType, mTransformOptions,
&programInfo, this)); &programInfo, mVariableInfoMap));
} }
} }
...@@ -730,7 +728,7 @@ angle::Result ProgramExecutableVk::getComputePipeline(ContextVk *contextVk, ...@@ -730,7 +728,7 @@ angle::Result ProgramExecutableVk::getComputePipeline(ContextVk *contextVk,
ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Compute); ProgramVk *programVk = getShaderProgram(glState, gl::ShaderType::Compute);
ASSERT(programVk); ASSERT(programVk);
ProgramInfo &programInfo = getComputeProgramInfo(); ProgramInfo &programInfo = getComputeProgramInfo();
ANGLE_TRY(programVk->initComputeProgram(contextVk, &programInfo, this)); ANGLE_TRY(programVk->initComputeProgram(contextVk, &programInfo, mVariableInfoMap));
vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram(); vk::ShaderProgramHelper *shaderProgram = programInfo.getShaderProgram();
ASSERT(shaderProgram); ASSERT(shaderProgram);
...@@ -807,7 +805,8 @@ angle::Result ProgramExecutableVk::createPipelineLayout( ...@@ -807,7 +805,8 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
for (const gl::ShaderType shaderType : linkedShaderStages) for (const gl::ShaderType shaderType : linkedShaderStages)
{ {
const std::string uniformBlockName = kDefaultUniformNames[shaderType]; const std::string uniformBlockName = kDefaultUniformNames[shaderType];
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][uniformBlockName]; const ShaderInterfaceVariableInfo &info =
mVariableInfoMap.get(shaderType, uniformBlockName);
if (!info.activeStages[shaderType]) if (!info.activeStages[shaderType])
{ {
continue; continue;
...@@ -827,9 +826,8 @@ angle::Result ProgramExecutableVk::createPipelineLayout( ...@@ -827,9 +826,8 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
programStates[gl::ShaderType::Vertex]->getExecutable(); programStates[gl::ShaderType::Vertex]->getExecutable();
size_t xfbBufferCount = executable.getTransformFeedbackBufferCount(); size_t xfbBufferCount = executable.getTransformFeedbackBufferCount();
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback); TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback);
transformFeedbackVk->updateDescriptorSetLayout(contextVk, transformFeedbackVk->updateDescriptorSetLayout(contextVk, mVariableInfoMap, xfbBufferCount,
mVariableInfoMap[gl::ShaderType::Vertex], &uniformsAndXfbSetDesc);
xfbBufferCount, &uniformsAndXfbSetDesc);
} }
ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout( ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
...@@ -924,32 +922,36 @@ void ProgramExecutableVk::resolvePrecisionMismatch(const gl::ProgramMergedVaryin ...@@ -924,32 +922,36 @@ void ProgramExecutableVk::resolvePrecisionMismatch(const gl::ProgramMergedVaryin
{ {
for (const gl::ProgramVaryingRef &mergedVarying : mergedVaryings) for (const gl::ProgramVaryingRef &mergedVarying : mergedVaryings)
{ {
if (mergedVarying.frontShader && mergedVarying.backShader) if (!mergedVarying.frontShader || !mergedVarying.backShader)
{ {
continue;
}
GLenum frontPrecision = mergedVarying.frontShader->precision; GLenum frontPrecision = mergedVarying.frontShader->precision;
GLenum backPrecision = mergedVarying.backShader->precision; GLenum backPrecision = mergedVarying.backShader->precision;
if (frontPrecision != backPrecision) if (frontPrecision == backPrecision)
{ {
ShaderInterfaceVariableInfo *info = continue;
&mVariableInfoMap[mergedVarying.frontShaderStage] }
[mergedVarying.frontShader->mappedName];
ASSERT(frontPrecision >= GL_LOW_FLOAT && frontPrecision <= GL_HIGH_INT); ASSERT(frontPrecision >= GL_LOW_FLOAT && frontPrecision <= GL_HIGH_INT);
ASSERT(backPrecision >= GL_LOW_FLOAT && backPrecision <= GL_HIGH_INT); ASSERT(backPrecision >= GL_LOW_FLOAT && backPrecision <= GL_HIGH_INT);
if (frontPrecision > backPrecision) if (frontPrecision > backPrecision)
{ {
// The output is higher precision than the input // The output is higher precision than the input
info->varyingIsOutput = true; ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(
info->useRelaxedPrecision = true; mergedVarying.frontShaderStage, mergedVarying.frontShader->mappedName);
info.varyingIsOutput = true;
info.useRelaxedPrecision = true;
} }
else if (backPrecision > frontPrecision) else
{ {
// The output is lower precision than the input, adjust the input // The output is lower precision than the input, adjust the input
info = &mVariableInfoMap[mergedVarying.backShaderStage] ASSERT(backPrecision > frontPrecision);
[mergedVarying.backShader->mappedName]; ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(
info->varyingIsInput = true; mergedVarying.backShaderStage, mergedVarying.backShader->mappedName);
info->useRelaxedPrecision = true; info.varyingIsInput = true;
} info.useRelaxedPrecision = true;
}
} }
} }
} }
...@@ -961,7 +963,7 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet( ...@@ -961,7 +963,7 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet(
ContextVk *contextVk) ContextVk *contextVk)
{ {
const std::string uniformBlockName = kDefaultUniformNames[shaderType]; const std::string uniformBlockName = kDefaultUniformNames[shaderType];
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][uniformBlockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, uniformBlockName);
if (!info.activeStages[shaderType]) if (!info.activeStages[shaderType])
{ {
return; return;
...@@ -1035,7 +1037,8 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet( ...@@ -1035,7 +1037,8 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet(
continue; continue;
} }
ShaderInterfaceVariableInfo info = mVariableInfoMap[shaderType][block.mappedName]; const ShaderInterfaceVariableInfo &info =
mVariableInfoMap.get(shaderType, block.mappedName);
uint32_t binding = info.binding; uint32_t binding = info.binding;
uint32_t arrayElement = block.isArray ? block.arrayElement : 0; uint32_t arrayElement = block.isArray ? block.arrayElement : 0;
...@@ -1110,7 +1113,7 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1110,7 +1113,7 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
mDescriptorSets[ToUnderlying(DescriptorSetIndex::ShaderResource)]; mDescriptorSets[ToUnderlying(DescriptorSetIndex::ShaderResource)];
std::string blockName(sh::vk::kAtomicCountersBlockName); std::string blockName(sh::vk::kAtomicCountersBlockName);
const ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][blockName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, blockName);
if (!info.activeStages[shaderType]) if (!info.activeStages[shaderType])
{ {
...@@ -1196,9 +1199,9 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1196,9 +1199,9 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
} }
angle::Result ProgramExecutableVk::updateImagesDescriptorSet( angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
ContextVk *contextVk,
const gl::ProgramExecutable &executable, const gl::ProgramExecutable &executable,
const gl::ShaderType shaderType, const gl::ShaderType shaderType)
ContextVk *contextVk)
{ {
const gl::State &glState = contextVk->getState(); const gl::State &glState = contextVk->getState();
RendererVk *renderer = contextVk->getRenderer(); RendererVk *renderer = contextVk->getRenderer();
...@@ -1283,7 +1286,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1283,7 +1286,8 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
const vk::BufferView *view = nullptr; const vk::BufferView *view = nullptr;
ANGLE_TRY(textureVk->getBufferViewAndRecordUse(contextVk, format, &view)); ANGLE_TRY(textureVk->getBufferViewAndRecordUse(contextVk, format, &view));
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][mappedImageName]; const ShaderInterfaceVariableInfo &info =
mVariableInfoMap.get(shaderType, mappedImageName);
writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfos[arrayElement].pNext = nullptr; writeInfos[arrayElement].pNext = nullptr;
...@@ -1317,11 +1321,10 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet( ...@@ -1317,11 +1321,10 @@ angle::Result ProgramExecutableVk::updateImagesDescriptorSet(
imageInfos[arrayElement].imageView = imageView->getHandle(); imageInfos[arrayElement].imageView = imageView->getHandle();
imageInfos[arrayElement].imageLayout = image->getCurrentLayout(); imageInfos[arrayElement].imageLayout = image->getCurrentLayout();
ShaderInterfaceVariableInfoMap &variableInfoMap = mVariableInfoMap[shaderType];
const std::string imageName = useOldRewriteStructSamplers const std::string imageName = useOldRewriteStructSamplers
? GetMappedSamplerNameOld(imageUniform.name) ? GetMappedSamplerNameOld(imageUniform.name)
: GlslangGetMappedSamplerName(imageUniform.name); : GlslangGetMappedSamplerName(imageUniform.name);
ShaderInterfaceVariableInfo &info = variableInfoMap[imageName]; const ShaderInterfaceVariableInfo &info = mVariableInfoMap.get(shaderType, imageName);
writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfos[arrayElement].pNext = nullptr; writeInfos[arrayElement].pNext = nullptr;
...@@ -1366,12 +1369,7 @@ angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet( ...@@ -1366,12 +1369,7 @@ angle::Result ProgramExecutableVk::updateShaderResourcesDescriptorSet(
programState->getShaderStorageBlocks(), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)); programState->getShaderStorageBlocks(), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
ANGLE_TRY(updateAtomicCounterBuffersDescriptorSet(*programState, shaderType, contextVk, ANGLE_TRY(updateAtomicCounterBuffersDescriptorSet(*programState, shaderType, contextVk,
resourceUseList, commandBufferHelper)); resourceUseList, commandBufferHelper));
angle::Result status = ANGLE_TRY(updateImagesDescriptorSet(contextVk, programState->getExecutable(), shaderType));
updateImagesDescriptorSet(programState->getExecutable(), shaderType, contextVk);
if (status != angle::Result::Continue)
{
return status;
}
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1426,7 +1424,7 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl( ...@@ -1426,7 +1424,7 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl(
{ {
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback); TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(transformFeedback);
transformFeedbackVk->initDescriptorSet( transformFeedbackVk->initDescriptorSet(
contextVk, executable.getTransformFeedbackBufferCount(), contextVk, mVariableInfoMap, executable.getTransformFeedbackBufferCount(),
mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]); mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]);
} }
return; return;
...@@ -1434,7 +1432,8 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl( ...@@ -1434,7 +1432,8 @@ void ProgramExecutableVk::updateTransformFeedbackDescriptorSetImpl(
TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(glState.getCurrentTransformFeedback()); TransformFeedbackVk *transformFeedbackVk = vk::GetImpl(glState.getCurrentTransformFeedback());
transformFeedbackVk->updateDescriptorSet( transformFeedbackVk->updateDescriptorSet(
contextVk, programState, mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]); contextVk, programState, mVariableInfoMap,
mDescriptorSets[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]);
} }
angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contextVk) angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contextVk)
...@@ -1529,7 +1528,8 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1529,7 +1528,8 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
const std::string samplerName = const std::string samplerName =
GlslangGetMappedSamplerName(samplerUniform.name); GlslangGetMappedSamplerName(samplerUniform.name);
ShaderInterfaceVariableInfo &info = mVariableInfoMap[shaderType][samplerName]; const ShaderInterfaceVariableInfo &info =
mVariableInfoMap.get(shaderType, samplerName);
writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfos[arrayElement].pNext = nullptr; writeInfos[arrayElement].pNext = nullptr;
...@@ -1579,12 +1579,12 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex ...@@ -1579,12 +1579,12 @@ angle::Result ProgramExecutableVk::updateTexturesDescriptorSet(ContextVk *contex
{ {
imageInfos[arrayElement].sampler = textureVk->getSampler().get().getHandle(); imageInfos[arrayElement].sampler = textureVk->getSampler().get().getHandle();
} }
ShaderInterfaceVariableInfoMap &variableInfoMap = mVariableInfoMap[shaderType];
const std::string samplerName = const std::string samplerName =
contextVk->getRenderer()->getFeatures().forceOldRewriteStructSamplers.enabled contextVk->getRenderer()->getFeatures().forceOldRewriteStructSamplers.enabled
? GetMappedSamplerNameOld(samplerUniform.name) ? GetMappedSamplerNameOld(samplerUniform.name)
: GlslangGetMappedSamplerName(samplerUniform.name); : GlslangGetMappedSamplerName(samplerUniform.name);
ShaderInterfaceVariableInfo &info = variableInfoMap[samplerName]; const ShaderInterfaceVariableInfo &info =
mVariableInfoMap.get(shaderType, samplerName);
writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfos[arrayElement].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writeInfos[arrayElement].pNext = nullptr; writeInfos[arrayElement].pNext = nullptr;
......
...@@ -32,7 +32,7 @@ class ShaderInfo final : angle::NonCopyable ...@@ -32,7 +32,7 @@ class ShaderInfo final : angle::NonCopyable
angle::Result initShaders(ContextVk *contextVk, angle::Result initShaders(ContextVk *contextVk,
const gl::ShaderBitSet &linkedShaderStages, const gl::ShaderBitSet &linkedShaderStages,
const gl::ShaderMap<std::string> &shaderSources, const gl::ShaderMap<std::string> &shaderSources,
ProgramExecutableVk *executableVk); const ShaderInterfaceVariableInfoMap &variableInfoMap);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
ANGLE_INLINE bool valid() const { return mIsInitialized; } ANGLE_INLINE bool valid() const { return mIsInitialized; }
...@@ -69,7 +69,7 @@ class ProgramInfo final : angle::NonCopyable ...@@ -69,7 +69,7 @@ class ProgramInfo final : angle::NonCopyable
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
const ShaderInfo &shaderInfo, const ShaderInfo &shaderInfo,
ProgramTransformOptions optionBits, ProgramTransformOptions optionBits,
ProgramExecutableVk *executableVk); const ShaderInterfaceVariableInfoMap &variableInfoMap);
void release(ContextVk *contextVk); void release(ContextVk *contextVk);
ANGLE_INLINE bool valid(const gl::ShaderType shaderType) const ANGLE_INLINE bool valid(const gl::ShaderType shaderType) const
...@@ -110,10 +110,6 @@ class ProgramExecutableVk ...@@ -110,10 +110,6 @@ class ProgramExecutableVk
std::unique_ptr<rx::LinkEvent> load(gl::BinaryInputStream *stream); std::unique_ptr<rx::LinkEvent> load(gl::BinaryInputStream *stream);
void clearVariableInfoMap(); void clearVariableInfoMap();
ShaderMapInterfaceVariableInfoMap &getShaderInterfaceVariableInfoMap()
{
return mVariableInfoMap;
}
ProgramVk *getShaderProgram(const gl::State &glState, gl::ShaderType shaderType) const; ProgramVk *getShaderProgram(const gl::State &glState, gl::ShaderType shaderType) const;
...@@ -229,9 +225,9 @@ class ProgramExecutableVk ...@@ -229,9 +225,9 @@ class ProgramExecutableVk
ContextVk *contextVk, ContextVk *contextVk,
vk::ResourceUseList *resourceUseList, vk::ResourceUseList *resourceUseList,
vk::CommandBufferHelper *commandBufferHelper); vk::CommandBufferHelper *commandBufferHelper);
angle::Result updateImagesDescriptorSet(const gl::ProgramExecutable &executable, angle::Result updateImagesDescriptorSet(ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ProgramExecutable &executable,
ContextVk *contextVk); const gl::ShaderType shaderType);
angle::Result initDynamicDescriptorPools(ContextVk *contextVk, angle::Result initDynamicDescriptorPools(ContextVk *contextVk,
vk::DescriptorSetLayoutDesc &descriptorSetLayoutDesc, vk::DescriptorSetLayoutDesc &descriptorSetLayoutDesc,
DescriptorSetIndex descriptorSetIndex, DescriptorSetIndex descriptorSetIndex,
...@@ -268,7 +264,7 @@ class ProgramExecutableVk ...@@ -268,7 +264,7 @@ class ProgramExecutableVk
// TODO: http://anglebug.com/4524: Need a different hash key than a string, // TODO: http://anglebug.com/4524: Need a different hash key than a string,
// since that's slow to calculate. // 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 // 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. // 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, ...@@ -84,7 +84,7 @@ angle::Result ProgramPipelineVk::link(const gl::Context *glContext,
GlslangAssignLocations(options, glProgram->getState().getExecutable(), shaderType, GlslangAssignLocations(options, glProgram->getState().getExecutable(), shaderType,
frontShaderType, &glslangProgramInterfaceInfo, frontShaderType, &glslangProgramInterfaceInfo,
&mExecutable.getShaderInterfaceVariableInfoMap()); &mExecutable.mVariableInfoMap);
frontShaderType = shaderType; frontShaderType = shaderType;
} }
} }
......
...@@ -274,8 +274,9 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context, ...@@ -274,8 +274,9 @@ std::unique_ptr<LinkEvent> ProgramVk::link(const gl::Context *context,
&mExecutable.mVariableInfoMap); &mExecutable.mVariableInfoMap);
// Compile the shaders. // Compile the shaders.
angle::Result status = mOriginalShaderInfo.initShaders( angle::Result status =
contextVk, mState.getExecutable().getLinkedShaderStages(), shaderSources, &mExecutable); mOriginalShaderInfo.initShaders(contextVk, mState.getExecutable().getLinkedShaderStages(),
shaderSources, mExecutable.mVariableInfoMap);
if (status != angle::Result::Continue) if (status != angle::Result::Continue)
{ {
return std::make_unique<LinkEventDone>(status); return std::make_unique<LinkEventDone>(status);
......
...@@ -145,22 +145,24 @@ class ProgramVk : public ProgramImpl ...@@ -145,22 +145,24 @@ class ProgramVk : public ProgramImpl
const gl::ProgramExecutable &glExecutable, const gl::ProgramExecutable &glExecutable,
gl::ShaderMap<VkDeviceSize> &uniformOffsets) const; gl::ShaderMap<VkDeviceSize> &uniformOffsets) const;
ANGLE_INLINE angle::Result initGraphicsShaderProgram(ContextVk *contextVk, ANGLE_INLINE angle::Result initGraphicsShaderProgram(
ContextVk *contextVk,
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
ProgramTransformOptions optionBits, ProgramTransformOptions optionBits,
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) const ShaderInterfaceVariableInfoMap &variableInfoMap)
{ {
return initProgram(contextVk, shaderType, optionBits, programInfo, executableVk); return initProgram(contextVk, shaderType, optionBits, programInfo, variableInfoMap);
} }
ANGLE_INLINE angle::Result initComputeProgram(ContextVk *contextVk, ANGLE_INLINE angle::Result initComputeProgram(
ContextVk *contextVk,
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) const ShaderInterfaceVariableInfoMap &variableInfoMap)
{ {
ProgramTransformOptions optionBits = {}; ProgramTransformOptions optionBits = {};
return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo, return initProgram(contextVk, gl::ShaderType::Compute, optionBits, programInfo,
executableVk); variableInfoMap);
} }
GlslangProgramInterfaceInfo &getGlslangProgramInterfaceInfo() GlslangProgramInterfaceInfo &getGlslangProgramInterfaceInfo()
...@@ -194,7 +196,7 @@ class ProgramVk : public ProgramImpl ...@@ -194,7 +196,7 @@ class ProgramVk : public ProgramImpl
const gl::ShaderType shaderType, const gl::ShaderType shaderType,
ProgramTransformOptions optionBits, ProgramTransformOptions optionBits,
ProgramInfo *programInfo, ProgramInfo *programInfo,
ProgramExecutableVk *executableVk) const ShaderInterfaceVariableInfoMap &variableInfoMap)
{ {
ASSERT(mOriginalShaderInfo.valid()); ASSERT(mOriginalShaderInfo.valid());
...@@ -203,7 +205,7 @@ class ProgramVk : public ProgramImpl ...@@ -203,7 +205,7 @@ class ProgramVk : public ProgramImpl
if (!programInfo->valid(shaderType)) if (!programInfo->valid(shaderType))
{ {
ANGLE_TRY(programInfo->initProgram(contextVk, shaderType, mOriginalShaderInfo, ANGLE_TRY(programInfo->initProgram(contextVk, shaderType, mOriginalShaderInfo,
optionBits, executableVk)); optionBits, variableInfoMap));
} }
ASSERT(programInfo->valid(shaderType)); ASSERT(programInfo->valid(shaderType));
......
...@@ -203,7 +203,7 @@ angle::Result TransformFeedbackVk::bindIndexedBuffer( ...@@ -203,7 +203,7 @@ angle::Result TransformFeedbackVk::bindIndexedBuffer(
void TransformFeedbackVk::updateDescriptorSetLayout( void TransformFeedbackVk::updateDescriptorSetLayout(
ContextVk *contextVk, ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const vk::DescriptorSetLayoutDesc *descSetLayoutOut) const
{ {
...@@ -213,7 +213,8 @@ void TransformFeedbackVk::updateDescriptorSetLayout( ...@@ -213,7 +213,8 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex) for (uint32_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{ {
const std::string bufferName = GetXfbBufferName(bufferIndex); const std::string bufferName = GetXfbBufferName(bufferIndex);
const ShaderInterfaceVariableInfo &info = vsVariableInfoMap[bufferName]; const ShaderInterfaceVariableInfo &info =
variableInfoMap.get(gl::ShaderType::Vertex, bufferName);
descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, descSetLayoutOut->update(info.binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
VK_SHADER_STAGE_VERTEX_BIT, nullptr); VK_SHADER_STAGE_VERTEX_BIT, nullptr);
...@@ -221,6 +222,7 @@ void TransformFeedbackVk::updateDescriptorSetLayout( ...@@ -221,6 +222,7 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
} }
void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk, void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
VkDescriptorSet descSet) const VkDescriptorSet descSet) const
{ {
...@@ -239,11 +241,12 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk, ...@@ -239,11 +241,12 @@ void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
bufferInfo.range = VK_WHOLE_SIZE; bufferInfo.range = VK_WHOLE_SIZE;
} }
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet); writeDescriptorSet(contextVk, variableInfoMap, xfbBufferCount, descriptorBufferInfo, descSet);
} }
void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState, const gl::ProgramState &programState,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
VkDescriptorSet descSet) const VkDescriptorSet descSet) const
{ {
if (!contextVk->getFeatures().emulateTransformFeedback.enabled) if (!contextVk->getFeatures().emulateTransformFeedback.enabled)
...@@ -272,7 +275,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk, ...@@ -272,7 +275,7 @@ void TransformFeedbackVk::updateDescriptorSet(ContextVk *contextVk,
ASSERT(bufferInfo.range != 0); ASSERT(bufferInfo.range != 0);
} }
writeDescriptorSet(contextVk, xfbBufferCount, descriptorBufferInfo, descSet); writeDescriptorSet(contextVk, variableInfoMap, xfbBufferCount, descriptorBufferInfo, descSet);
} }
void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk, void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
...@@ -314,15 +317,16 @@ void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk, ...@@ -314,15 +317,16 @@ void TransformFeedbackVk::getBufferOffsets(ContextVk *contextVk,
} }
void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk, void TransformFeedbackVk::writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo, VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const VkDescriptorSet descSet) const
{ {
ProgramExecutableVk *executableVk = contextVk->getExecutable(); ASSERT(contextVk->getFeatures().emulateTransformFeedback.enabled);
ShaderMapInterfaceVariableInfoMap variableInfoMap =
executableVk->getShaderInterfaceVariableInfoMap();
const std::string bufferName = GetXfbBufferName(0); const std::string bufferName = GetXfbBufferName(0);
ShaderInterfaceVariableInfo &info = variableInfoMap[gl::ShaderType::Vertex][bufferName]; const ShaderInterfaceVariableInfo &info =
variableInfoMap.get(gl::ShaderType::Vertex, bufferName);
VkWriteDescriptorSet &writeDescriptorInfo = contextVk->allocWriteDescriptorSet(); VkWriteDescriptorSet &writeDescriptorInfo = contextVk->allocWriteDescriptorSet();
writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeDescriptorInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
......
...@@ -44,14 +44,16 @@ class TransformFeedbackVk : public TransformFeedbackImpl ...@@ -44,14 +44,16 @@ class TransformFeedbackVk : public TransformFeedbackImpl
const gl::OffsetBindingPointer<gl::Buffer> &binding) override; const gl::OffsetBindingPointer<gl::Buffer> &binding) override;
void updateDescriptorSetLayout(ContextVk *contextVk, void updateDescriptorSetLayout(ContextVk *contextVk,
ShaderInterfaceVariableInfoMap &vsVariableInfoMap, const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const; vk::DescriptorSetLayoutDesc *descSetLayoutOut) const;
void initDescriptorSet(ContextVk *contextVk, void initDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
VkDescriptorSet descSet) const; VkDescriptorSet descSet) const;
void updateDescriptorSet(ContextVk *contextVk, void updateDescriptorSet(ContextVk *contextVk,
const gl::ProgramState &programState, const gl::ProgramState &programState,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
VkDescriptorSet descSet) const; VkDescriptorSet descSet) const;
void getBufferOffsets(ContextVk *contextVk, void getBufferOffsets(ContextVk *contextVk,
GLint drawCallFirstVertex, GLint drawCallFirstVertex,
...@@ -94,6 +96,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl ...@@ -94,6 +96,7 @@ class TransformFeedbackVk : public TransformFeedbackImpl
private: private:
void writeDescriptorSet(ContextVk *contextVk, void writeDescriptorSet(ContextVk *contextVk,
const ShaderInterfaceVariableInfoMap &variableInfoMap,
size_t xfbBufferCount, size_t xfbBufferCount,
VkDescriptorBufferInfo *pBufferInfo, VkDescriptorBufferInfo *pBufferInfo,
VkDescriptorSet descSet) const; 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