Commit 8b74bdc2 by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Refactor glslang wrapper's varying location assignment

Instead of multiple ifs that test for various combination of shader stages and calling AssignVaryingLocations for the appropriate pairs, that function loops over all stages and assigns a location to the varying in any stage it is active. This change will help keep this code simpler with the introduction of tessellation shaders. Bug: angleproject:3571 Change-Id: Iaf3ee67990bd219080314237b314bd2770a43085 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1961096Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 19868b7e
......@@ -714,15 +714,10 @@ void AssignOutputLocations(const gl::ProgramState &programState,
void AssignVaryingLocations(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
gl::ShaderType outStage,
gl::ShaderType inStage,
gl::ShaderMap<IntermediateShaderSource> *shaderSources,
XfbBufferMap *xfbBufferMap)
{
IntermediateShaderSource *outStageSource = &(*shaderSources)[outStage];
IntermediateShaderSource *inStageSource = &(*shaderSources)[inStage];
// Assign varying locations.
for (const gl::PackedVaryingRegister &varyingReg : resources.varyingPacking.getRegisterList())
{
......@@ -741,14 +736,6 @@ void AssignVaryingLocations(const gl::ProgramState &programState,
continue;
}
std::string locationString = "location = " + Str(varyingReg.registerRow);
if (varyingReg.registerColumn > 0)
{
ASSERT(!varying.varying->isStruct());
ASSERT(!gl::IsMatrixType(varying.varying->type));
locationString += ", component = " + Str(varyingReg.registerColumn);
}
// In the following:
//
// struct S { vec4 field; };
......@@ -759,34 +746,57 @@ void AssignVaryingLocations(const gl::ProgramState &programState,
const std::string &name =
varying.isStructField() ? varying.parentStructName : varying.varying->name;
// Varyings are from multiple shader stages
// To match pair of (out - in) qualifier, varying should be in the pair of shader source
if (!varying.shaderStages.test(outStage) || !varying.shaderStages.test(inStage))
std::string locationString = "location = " + Str(varyingReg.registerRow);
if (varyingReg.registerColumn > 0)
{
// Pair can be unmatching at transform feedback case,
// But it requires qualifier.
if (!varying.vertexOnly())
continue;
ASSERT(!varying.varying->isStruct());
ASSERT(!gl::IsMatrixType(varying.varying->type));
locationString += ", component = " + Str(varyingReg.registerColumn);
}
std::string *layoutSpecifier = &locationString;
std::string xfbSpecifier;
XfbBufferMap::iterator iter;
iter = xfbBufferMap->find(name);
if (iter != xfbBufferMap->end())
{
XFBBufferInfo item = iter->second;
const std::string xfbSpecifier =
"xfb_buffer = " + Str(item.index) + ", xfb_offset = " + Str(item.offset) +
", xfb_stride = " + Str(item.stride) + ", " + locationString;
outStageSource->insertLayoutSpecifier(name, xfbSpecifier);
xfbSpecifier = "xfb_buffer = " + Str(item.index) +
", xfb_offset = " + Str(item.offset) +
", xfb_stride = " + Str(item.stride) + ", " + locationString;
layoutSpecifier = &xfbSpecifier;
}
else
for (const gl::ShaderType stage : gl::kAllGraphicsShaderTypes)
{
outStageSource->insertLayoutSpecifier(name, locationString);
}
inStageSource->insertLayoutSpecifier(name, locationString);
IntermediateShaderSource *shaderSource = &(*shaderSources)[stage];
if (shaderSource->empty())
{
ASSERT(!varying.shaderStages[stage]);
continue;
}
if (!varying.shaderStages[stage])
{
// If not active in this stage, remove the varying declaration. Imagine the
// following scenario:
//
// - VS: declare out varying used for transform feedback
// - FS: declare corresponding in varying which is not active
//
// Then varying.shaderStages would only contain Vertex, but the varying is not
// present in the list of inactive varyings since it _is_ active in some stages.
// As a result, we remove the varying from any stage that's not active.
// CleanupUnusedEntities will remove the varyings that are inactive in all stages.
shaderSource->eraseLayoutAndQualifierSpecifiers(name, "");
continue;
}
outStageSource->insertQualifierSpecifier(name, "");
inStageSource->insertQualifierSpecifier(name, "");
shaderSource->insertLayoutSpecifier(
name, stage == gl::ShaderType::Fragment ? locationString : *layoutSpecifier);
shaderSource->insertQualifierSpecifier(name, "");
}
}
// Substitute layout and qualifier strings for the position varying. Use the first free
......@@ -797,11 +807,11 @@ void AssignVaryingLocations(const gl::ProgramState &programState,
<< (resources.varyingPacking.getMaxSemanticIndex() + kANGLEPositionLocationOffset);
const std::string layout = layoutStream.str();
outStageSource->insertLayoutSpecifier(kVaryingName, layout);
inStageSource->insertLayoutSpecifier(kVaryingName, layout);
outStageSource->insertQualifierSpecifier(kVaryingName, "");
inStageSource->insertQualifierSpecifier(kVaryingName, "");
for (IntermediateShaderSource &shaderSource : *shaderSources)
{
shaderSource.insertLayoutSpecifier(kVaryingName, layout);
shaderSource.insertQualifierSpecifier(kVaryingName, "");
}
}
void AssignUniformBindings(const GlslangSourceOptions &options,
......@@ -1208,7 +1218,8 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
IntermediateShaderSource *vertexSource = &intermediateSources[gl::ShaderType::Vertex];
IntermediateShaderSource *fragmentSource = &intermediateSources[gl::ShaderType::Fragment];
IntermediateShaderSource *geometrySource = &intermediateSources[gl::ShaderType::Geometry];
IntermediateShaderSource *computeSource = &intermediateSources[gl::ShaderType::Compute];
XfbBufferMap xfbBufferMap;
// Write transform feedback output code.
......@@ -1233,32 +1244,24 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
}
}
if (!geometrySource->empty())
// Assign outputs to the fragment shader, if any.
if (!fragmentSource->empty())
{
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(programState, resources, gl::ShaderType::Geometry,
gl::ShaderType::Fragment, &intermediateSources, &xfbBufferMap);
if (!vertexSource->empty())
{
AssignAttributeLocations(programState, vertexSource);
AssignVaryingLocations(programState, resources, gl::ShaderType::Vertex,
gl::ShaderType::Geometry, &intermediateSources, &xfbBufferMap);
}
}
else if (!vertexSource->empty())
// Assign attributes to the vertex shader, if any.
if (!vertexSource->empty())
{
AssignAttributeLocations(programState, vertexSource);
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(programState, resources, gl::ShaderType::Vertex,
gl::ShaderType::Fragment, &intermediateSources, &xfbBufferMap);
}
else if (!fragmentSource->empty())
if (computeSource->empty())
{
AssignAttributeLocations(programState, fragmentSource);
AssignOutputLocations(programState, fragmentSource);
AssignVaryingLocations(programState, resources, gl::ShaderType::Vertex,
gl::ShaderType::Fragment, &intermediateSources, &xfbBufferMap);
// Assign varying locations.
AssignVaryingLocations(programState, resources, &intermediateSources, &xfbBufferMap);
}
AssignUniformBindings(options, &intermediateSources);
AssignTextureBindings(options, useOldRewriteStructSamplers, programState, &intermediateSources);
AssignNonTextureBindings(options, programState, &intermediateSources);
......
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