Commit b8e056dd by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Have the translator output in/out qualifiers

Currently, when assigning varying locations, we assign in/out qualifiers based on whether the varying name is present between different shader stages. This is broken for separate shader objects as there is possibly no pair of shaders to be able to tell which is input and which is output (by trying to find the same varying in a stage before or after the shader). Bug: angleproject:3571 Change-Id: Id928a3eaa16e917c81bae0b3414c41842eb2b664 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1961993 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent e181f2f7
...@@ -1016,6 +1016,41 @@ inline bool IsStorageBuffer(TQualifier qualifier) ...@@ -1016,6 +1016,41 @@ inline bool IsStorageBuffer(TQualifier qualifier)
return qualifier == EvqBuffer; return qualifier == EvqBuffer;
} }
inline bool IsShaderIn(TQualifier qualifier)
{
switch (qualifier)
{
case EvqVertexIn:
case EvqGeometryIn:
case EvqFragmentIn:
case EvqAttribute:
case EvqVaryingIn:
case EvqSmoothIn:
case EvqFlatIn:
case EvqCentroidIn:
return true;
default:
return false;
}
}
inline bool IsShaderOut(TQualifier qualifier)
{
switch (qualifier)
{
case EvqVertexOut:
case EvqGeometryOut:
case EvqFragmentOut:
case EvqVaryingOut:
case EvqSmoothOut:
case EvqFlatOut:
case EvqCentroidOut:
return true;
default:
return false;
}
}
enum TLayoutImageInternalFormat enum TLayoutImageInternalFormat
{ {
EiifUnspecified, EiifUnspecified,
......
...@@ -85,14 +85,14 @@ class TOutputGLSLBase : public TIntermTraverser ...@@ -85,14 +85,14 @@ class TOutputGLSLBase : public TIntermTraverser
virtual void writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol); virtual void writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol);
bool structDeclared(const TStructure *structure) const; bool structDeclared(const TStructure *structure) const;
const char *mapQualifierToString(TQualifier qualifier);
private: private:
void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock); void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock);
void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock); void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock);
void writeBuiltInFunctionTriplet(Visit visit, TOperator op, bool useEmulatedFunction); void writeBuiltInFunctionTriplet(Visit visit, TOperator op, bool useEmulatedFunction);
const char *mapQualifierToString(TQualifier qualifier);
TInfoSinkBase &mObjSink; TInfoSinkBase &mObjSink;
bool mDeclaringVariable; bool mDeclaringVariable;
......
...@@ -164,8 +164,20 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier, ...@@ -164,8 +164,20 @@ void TOutputVulkanGLSL::writeQualifier(TQualifier qualifier,
name = type.getInterfaceBlock()->name(); name = type.getInterfaceBlock()->name();
} }
// The in/out qualifiers are calculated here so glslang wrapper doesn't need to guess them.
// The rest of the qualifiers are left to glslang wrapper to substitute as it emulates some
// with others.
const char *inOutQualifier = "";
if (IsShaderIn(qualifier) || IsShaderOut(qualifier))
{
inOutQualifier = mapQualifierToString(qualifier);
}
std::string memoryQualifiers = getMemoryQualifiers(type);
const char *separator = strcmp(inOutQualifier, "") == 0 || memoryQualifiers.empty() ? "" : " ";
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
out << "@@ QUALIFIER-" << name.data() << "(" << getMemoryQualifiers(type) << ") @@ "; out << "@@ QUALIFIER-" << name.data() << "(" << inOutQualifier << separator << memoryQualifiers
<< ") @@ ";
} }
void TOutputVulkanGLSL::writeVariableType(const TType &type, const TSymbol *symbol) void TOutputVulkanGLSL::writeVariableType(const TType &type, const TSymbol *symbol)
......
...@@ -317,7 +317,8 @@ void IntermediateShaderSource::insertLayoutSpecifier(const std::string &name, ...@@ -317,7 +317,8 @@ void IntermediateShaderSource::insertLayoutSpecifier(const std::string &name,
{ {
if (block.type == TokenType::Layout && block.text == name) if (block.type == TokenType::Layout && block.text == name)
{ {
const char *separator = specifier.empty() || block.args.empty() ? "" : ", "; ASSERT(!specifier.empty());
const char *separator = block.args.empty() ? "" : ", ";
block.type = TokenType::Text; block.type = TokenType::Text;
block.text = "layout(" + block.args + separator + specifier + ")"; block.text = "layout(" + block.args + separator + specifier + ")";
...@@ -335,7 +336,7 @@ void IntermediateShaderSource::insertQualifierSpecifier(const std::string &name, ...@@ -335,7 +336,7 @@ void IntermediateShaderSource::insertQualifierSpecifier(const std::string &name,
{ {
block.type = TokenType::Text; block.type = TokenType::Text;
block.text = specifier; block.text = specifier;
if (!specifier.empty() && !block.args.empty()) if (!block.args.empty())
{ {
block.text += " " + block.args; block.text += " " + block.args;
} }
...@@ -666,13 +667,11 @@ void AssignAttributeLocations(const gl::ProgramState &programState, ...@@ -666,13 +667,11 @@ void AssignAttributeLocations(const gl::ProgramState &programState,
// See corresponding code in OutputVulkanGLSL.cpp. // See corresponding code in OutputVulkanGLSL.cpp.
for (const sh::ShaderVariable &attribute : programState.getProgramInputs()) for (const sh::ShaderVariable &attribute : programState.getProgramInputs())
{ {
// Warning: If we end up supporting ES 3.0 shaders and up, Program::linkAttributes is
// going to bring us all attributes in this list instead of only the active ones.
ASSERT(attribute.active); ASSERT(attribute.active);
std::string locationString = "location = " + Str(attribute.location); std::string locationString = "location = " + Str(attribute.location);
shaderSource->insertLayoutSpecifier(attribute.name, locationString); shaderSource->insertLayoutSpecifier(attribute.name, locationString);
shaderSource->insertQualifierSpecifier(attribute.name, "in"); shaderSource->insertQualifierSpecifier(attribute.name, "");
} }
} }
...@@ -786,25 +785,8 @@ void AssignVaryingLocations(const gl::ProgramState &programState, ...@@ -786,25 +785,8 @@ void AssignVaryingLocations(const gl::ProgramState &programState,
} }
inStageSource->insertLayoutSpecifier(name, locationString); inStageSource->insertLayoutSpecifier(name, locationString);
const char *outQualifier = "out"; outStageSource->insertQualifierSpecifier(name, "");
const char *inQualifier = "in"; inStageSource->insertQualifierSpecifier(name, "");
switch (varying.interpolation)
{
case sh::INTERPOLATION_SMOOTH:
break;
case sh::INTERPOLATION_CENTROID:
outQualifier = "centroid out";
inQualifier = "centroid in";
break;
case sh::INTERPOLATION_FLAT:
outQualifier = "flat out";
inQualifier = "flat in";
break;
default:
UNREACHABLE();
}
outStageSource->insertQualifierSpecifier(name, outQualifier);
inStageSource->insertQualifierSpecifier(name, inQualifier);
} }
// Substitute layout and qualifier strings for the position varying. Use the first free // Substitute layout and qualifier strings for the position varying. Use the first free
...@@ -818,8 +800,8 @@ void AssignVaryingLocations(const gl::ProgramState &programState, ...@@ -818,8 +800,8 @@ void AssignVaryingLocations(const gl::ProgramState &programState,
outStageSource->insertLayoutSpecifier(kVaryingName, layout); outStageSource->insertLayoutSpecifier(kVaryingName, layout);
inStageSource->insertLayoutSpecifier(kVaryingName, layout); inStageSource->insertLayoutSpecifier(kVaryingName, layout);
outStageSource->insertQualifierSpecifier(kVaryingName, "out"); outStageSource->insertQualifierSpecifier(kVaryingName, "");
inStageSource->insertQualifierSpecifier(kVaryingName, "in"); inStageSource->insertQualifierSpecifier(kVaryingName, "");
} }
void AssignUniformBindings(const GlslangSourceOptions &options, void AssignUniformBindings(const GlslangSourceOptions &options,
......
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