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