Commit f6df8692 by Jamie Madill Committed by Commit Bot

Vulkan: Support XFB in non-Vertex stages.

This updates the code in several places to support Geometry and Tessellation Evaluation shaders to output transform feedback. Does not turn on any new tests but enables support for XFB when we turn on GS/TS. Bug: angleproject:3571 Bug: angleproject:3572 Change-Id: I6dcb768f2df4eeee81a4a500e999fcf16716f58f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2581941Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 8707811d
...@@ -1150,6 +1150,19 @@ ShaderType GetShaderTypeFromBitfield(size_t singleShaderType) ...@@ -1150,6 +1150,19 @@ ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
return ShaderType::InvalidEnum; return ShaderType::InvalidEnum;
} }
} }
bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
{
switch (shaderType)
{
case ShaderType::Vertex:
case ShaderType::Geometry:
case ShaderType::TessEvaluation:
return true;
default:
return false;
}
}
} // namespace gl } // namespace gl
namespace egl namespace egl
......
...@@ -246,6 +246,7 @@ enum class SrgbOverride ...@@ -246,6 +246,7 @@ enum class SrgbOverride
}; };
ShaderType GetShaderTypeFromBitfield(size_t singleShaderType); ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
} // namespace gl } // namespace gl
......
...@@ -1276,6 +1276,19 @@ ShaderType ProgramState::getLastAttachedShaderStageType() const ...@@ -1276,6 +1276,19 @@ ShaderType ProgramState::getLastAttachedShaderStageType() const
return ShaderType::InvalidEnum; return ShaderType::InvalidEnum;
} }
ShaderType ProgramState::getAttachedTransformFeedbackStage() const
{
if (mAttachedShaders[ShaderType::Geometry])
{
return ShaderType::Geometry;
}
if (mAttachedShaders[ShaderType::TessEvaluation])
{
return ShaderType::TessEvaluation;
}
return ShaderType::Vertex;
}
Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle) Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle)
: mSerial(factory->generateSerial()), : mSerial(factory->generateSerial()),
mProgram(factory->createProgram(mState)), mProgram(factory->createProgram(mState)),
......
...@@ -372,6 +372,8 @@ class ProgramState final : angle::NonCopyable ...@@ -372,6 +372,8 @@ class ProgramState final : angle::NonCopyable
int getBaseInstanceLocation() const { return mBaseInstanceLocation; } int getBaseInstanceLocation() const { return mBaseInstanceLocation; }
ShaderType getAttachedTransformFeedbackStage() const;
private: private:
friend class MemoryProgramCache; friend class MemoryProgramCache;
friend class Program; friend class Program;
......
...@@ -538,4 +538,17 @@ bool ProgramExecutable::isYUVOutput() const ...@@ -538,4 +538,17 @@ bool ProgramExecutable::isYUVOutput() const
{ {
return !isCompute() && mYUVOutput; return !isCompute() && mYUVOutput;
} }
ShaderType ProgramExecutable::getLinkedTransformFeedbackStage() const
{
if (mLinkedGraphicsShaderStages[ShaderType::Geometry])
{
return ShaderType::Geometry;
}
if (mLinkedGraphicsShaderStages[ShaderType::TessEvaluation])
{
return ShaderType::TessEvaluation;
}
return ShaderType::Vertex;
}
} // namespace gl } // namespace gl
...@@ -152,6 +152,8 @@ class ProgramExecutable final : public angle::Subject ...@@ -152,6 +152,8 @@ class ProgramExecutable final : public angle::Subject
: mLinkedGraphicsShaderStages.count(); : mLinkedGraphicsShaderStages.count();
} }
ShaderType getLinkedTransformFeedbackStage() const;
// A PPO can have both graphics and compute programs attached, so // A PPO can have both graphics and compute programs attached, so
// we don't know if the PPO is a 'graphics' or 'compute' PPO until the // we don't know if the PPO is a 'graphics' or 'compute' PPO until the
// actual draw/dispatch call. // actual draw/dispatch call.
......
...@@ -466,7 +466,7 @@ bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg) ...@@ -466,7 +466,7 @@ bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg)
// values for the SPIR-V transformation. // values for the SPIR-V transformation.
void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programState, void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources, const gl::ProgramLinkedResources &resources,
std::string *vertexShader, std::string *xfbShaderSource,
uint32_t *locationsUsedForXfbExtensionOut) uint32_t *locationsUsedForXfbExtensionOut)
{ {
const std::vector<gl::TransformFeedbackVarying> &tfVaryings = const std::vector<gl::TransformFeedbackVarying> &tfVaryings =
...@@ -502,7 +502,7 @@ void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programSt ...@@ -502,7 +502,7 @@ void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programSt
} }
} }
*vertexShader = SubstituteTransformFeedbackMarkers(*vertexShader, xfbDecl, xfbOut); *xfbShaderSource = SubstituteTransformFeedbackMarkers(*xfbShaderSource, xfbDecl, xfbOut);
} }
void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable, void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
...@@ -3664,11 +3664,12 @@ void GlslangAssignLocations(const GlslangSourceOptions &options, ...@@ -3664,11 +3664,12 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
programInterfaceInfo, variableInfoMapOut); programInterfaceInfo, variableInfoMapOut);
if (!programExecutable.getLinkedTransformFeedbackVaryings().empty() && if (!programExecutable.getLinkedTransformFeedbackVaryings().empty() &&
options.supportsTransformFeedbackExtension && (shaderType == gl::ShaderType::Vertex)) options.supportsTransformFeedbackExtension &&
(shaderType == programExecutable.getLinkedTransformFeedbackStage()))
{ {
AssignTransformFeedbackExtensionQualifiers( AssignTransformFeedbackExtensionQualifiers(
programExecutable, programInterfaceInfo->locationsUsedForXfbExtension, programExecutable, programInterfaceInfo->locationsUsedForXfbExtension, shaderType,
gl::ShaderType::Vertex, &(*variableInfoMapOut)[gl::ShaderType::Vertex]); &(*variableInfoMapOut)[shaderType]);
} }
} }
...@@ -3693,34 +3694,48 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -3693,34 +3694,48 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
(*shaderSourcesOut)[shaderType] = glShader ? glShader->getTranslatedSource() : ""; (*shaderSourcesOut)[shaderType] = glShader ? glShader->getTranslatedSource() : "";
} }
std::string *vertexSource = &(*shaderSourcesOut)[gl::ShaderType::Vertex]; gl::ShaderType xfbStage = programState.getAttachedTransformFeedbackStage();
std::string *xfbSource = &(*shaderSourcesOut)[xfbStage];
// Write transform feedback output code. // Write transform feedback output code.
if (!vertexSource->empty()) if (!xfbSource->empty())
{ {
if (programState.getLinkedTransformFeedbackVaryings().empty()) if (!programState.getLinkedTransformFeedbackVaryings().empty())
{
*vertexSource = SubstituteTransformFeedbackMarkers(*vertexSource, "", "");
}
else
{ {
if (options.supportsTransformFeedbackExtension) if (options.supportsTransformFeedbackExtension)
{ {
GenerateTransformFeedbackExtensionOutputs( GenerateTransformFeedbackExtensionOutputs(
programState, resources, vertexSource, programState, resources, xfbSource,
&programInterfaceInfo->locationsUsedForXfbExtension); &programInterfaceInfo->locationsUsedForXfbExtension);
} }
else if (options.emulateTransformFeedback) else if (options.emulateTransformFeedback)
{ {
GenerateTransformFeedbackEmulationOutputs( ASSERT(xfbStage == gl::ShaderType::Vertex);
options, programState, programInterfaceInfo, vertexSource, GenerateTransformFeedbackEmulationOutputs(options, programState,
&(*variableInfoMapOut)[gl::ShaderType::Vertex]); programInterfaceInfo, xfbSource,
&(*variableInfoMapOut)[xfbStage]);
} }
else else
{ {
*vertexSource = SubstituteTransformFeedbackMarkers(*vertexSource, "", ""); *xfbSource = SubstituteTransformFeedbackMarkers(*xfbSource, "", "");
} }
} }
else
{
*xfbSource = SubstituteTransformFeedbackMarkers(*xfbSource, "", "");
}
}
std::string *tessEvalSources = &(*shaderSourcesOut)[gl::ShaderType::TessEvaluation];
if (xfbStage > gl::ShaderType::TessEvaluation && !tessEvalSources->empty())
{
*tessEvalSources = SubstituteTransformFeedbackMarkers(*tessEvalSources, "", "");
}
std::string *vertexSource = &(*shaderSourcesOut)[gl::ShaderType::Vertex];
if (xfbStage > gl::ShaderType::Vertex && !vertexSource->empty())
{
*vertexSource = SubstituteTransformFeedbackMarkers(*vertexSource, "", "");
} }
gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum; gl::ShaderType frontShaderType = gl::ShaderType::InvalidEnum;
......
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