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)
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 egl
......
......@@ -246,6 +246,7 @@ enum class SrgbOverride
};
ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
} // namespace gl
......
......@@ -1276,6 +1276,19 @@ ShaderType ProgramState::getLastAttachedShaderStageType() const
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)
: mSerial(factory->generateSerial()),
mProgram(factory->createProgram(mState)),
......
......@@ -372,6 +372,8 @@ class ProgramState final : angle::NonCopyable
int getBaseInstanceLocation() const { return mBaseInstanceLocation; }
ShaderType getAttachedTransformFeedbackStage() const;
private:
friend class MemoryProgramCache;
friend class Program;
......
......@@ -538,4 +538,17 @@ bool ProgramExecutable::isYUVOutput() const
{
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
......@@ -152,6 +152,8 @@ class ProgramExecutable final : public angle::Subject
: mLinkedGraphicsShaderStages.count();
}
ShaderType getLinkedTransformFeedbackStage() const;
// 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
// actual draw/dispatch call.
......
......@@ -466,7 +466,7 @@ bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg)
// values for the SPIR-V transformation.
void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,
std::string *vertexShader,
std::string *xfbShaderSource,
uint32_t *locationsUsedForXfbExtensionOut)
{
const std::vector<gl::TransformFeedbackVarying> &tfVaryings =
......@@ -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,
......@@ -3664,11 +3664,12 @@ void GlslangAssignLocations(const GlslangSourceOptions &options,
programInterfaceInfo, variableInfoMapOut);
if (!programExecutable.getLinkedTransformFeedbackVaryings().empty() &&
options.supportsTransformFeedbackExtension && (shaderType == gl::ShaderType::Vertex))
options.supportsTransformFeedbackExtension &&
(shaderType == programExecutable.getLinkedTransformFeedbackStage()))
{
AssignTransformFeedbackExtensionQualifiers(
programExecutable, programInterfaceInfo->locationsUsedForXfbExtension,
gl::ShaderType::Vertex, &(*variableInfoMapOut)[gl::ShaderType::Vertex]);
programExecutable, programInterfaceInfo->locationsUsedForXfbExtension, shaderType,
&(*variableInfoMapOut)[shaderType]);
}
}
......@@ -3693,34 +3694,48 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
(*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.
if (!vertexSource->empty())
if (!xfbSource->empty())
{
if (programState.getLinkedTransformFeedbackVaryings().empty())
{
*vertexSource = SubstituteTransformFeedbackMarkers(*vertexSource, "", "");
}
else
if (!programState.getLinkedTransformFeedbackVaryings().empty())
{
if (options.supportsTransformFeedbackExtension)
{
GenerateTransformFeedbackExtensionOutputs(
programState, resources, vertexSource,
programState, resources, xfbSource,
&programInterfaceInfo->locationsUsedForXfbExtension);
}
else if (options.emulateTransformFeedback)
{
GenerateTransformFeedbackEmulationOutputs(
options, programState, programInterfaceInfo, vertexSource,
&(*variableInfoMapOut)[gl::ShaderType::Vertex]);
ASSERT(xfbStage == gl::ShaderType::Vertex);
GenerateTransformFeedbackEmulationOutputs(options, programState,
programInterfaceInfo, xfbSource,
&(*variableInfoMapOut)[xfbStage]);
}
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;
......
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