Commit d06feeac by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Generate xfb support code in SPIR-V for extension path

The only piece of code that's needed to be generated for the extension path is the following, at the right spot (right before depth correction and pre-rotation): ANGLEXfbPosition = gl_Position; The SPIR-V transformer already has gl_Position loaded for depth correction and pre-rotation, so this change simply adds an OpStore to ANGLEXfbPosition. As a result of this change, @@ XFB-OUT @@ is no longer emitted if the transform feedback extension is supported. With the above code now placed correctly for geometry shaders, transform feedback tests for geometry shaders are enabled. Bug: angleproject:3606 Change-Id: I13a7956ab62a1a6b4196ff999442b99b50226c0f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2617659 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8f5ca266
...@@ -881,9 +881,12 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root, ...@@ -881,9 +881,12 @@ bool TranslatorVulkan::translateImpl(TIntermBlock *root,
} }
// Append a macro for transform feedback substitution prior to modifying depth. // Append a macro for transform feedback substitution prior to modifying depth.
if (!AppendTransformFeedbackOutputToMain(this, root, &getSymbolTable())) if (compileOptions & SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE)
{ {
return false; if (!AppendTransformFeedbackOutputToMain(this, root, &getSymbolTable()))
{
return false;
}
} }
} }
......
...@@ -526,35 +526,6 @@ bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg, bool ...@@ -526,35 +526,6 @@ bool IsFirstRegisterOfVarying(const gl::PackedVaryingRegister &varyingReg, bool
return true; return true;
} }
// Calculates XFB layout qualifier arguments for each tranform feedback varying. Stores calculated
// values for the SPIR-V transformation.
void GenerateTransformFeedbackExtensionOutputs(const gl::ProgramState &programState,
std::string *xfbShaderSource)
{
const std::vector<gl::TransformFeedbackVarying> &tfVaryings =
programState.getLinkedTransformFeedbackVaryings();
std::string xfbOut;
for (uint32_t varyingIndex = 0; varyingIndex < tfVaryings.size(); ++varyingIndex)
{
const gl::TransformFeedbackVarying &tfVarying = tfVaryings[varyingIndex];
const std::string &tfVaryingName = tfVarying.mappedName;
if (tfVaryingName == "gl_Position")
{
ASSERT(tfVarying.isBuiltIn());
// Add initialization code for the position varying.
xfbOut = sh::vk::kXfbExtensionPositionOutName;
xfbOut += " = " + tfVaryingName + ";\n";
break;
}
}
*xfbShaderSource = SubstituteTransformFeedbackMarkers(*xfbShaderSource, xfbOut);
}
void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable, void AssignAttributeLocations(const gl::ProgramExecutable &programExecutable,
gl::ShaderType shaderType, gl::ShaderType shaderType,
ShaderInterfaceVariableInfoMap *variableInfoMapOut) ShaderInterfaceVariableInfoMap *variableInfoMapOut)
...@@ -1727,6 +1698,7 @@ class SpirvTransformer final : public SpirvTransformerBase ...@@ -1727,6 +1698,7 @@ class SpirvTransformer final : public SpirvTransformerBase
void writeOutputPrologue(); void writeOutputPrologue();
void preRotateXY(uint32_t xId, uint32_t yId, uint32_t *rotatedXIdOut, uint32_t *rotatedYIdOut); void preRotateXY(uint32_t xId, uint32_t yId, uint32_t *rotatedXIdOut, uint32_t *rotatedYIdOut);
void transformZToVulkanClipSpace(uint32_t zId, uint32_t wId, uint32_t *correctedZIdOut); void transformZToVulkanClipSpace(uint32_t zId, uint32_t wId, uint32_t *correctedZIdOut);
void writeTransformFeedbackExtensionOutput(uint32_t positionId);
// Special flags: // Special flags:
GlslangSpirvOptions mOptions; GlslangSpirvOptions mOptions;
...@@ -1776,6 +1748,9 @@ class SpirvTransformer final : public SpirvTransformerBase ...@@ -1776,6 +1748,9 @@ class SpirvTransformer final : public SpirvTransformerBase
PerVertexData mOutputPerVertex; PerVertexData mOutputPerVertex;
PerVertexData mInputPerVertex; PerVertexData mInputPerVertex;
// Ids needed to generate transform feedback support code.
uint32_t mTransformFeedbackExtensionPositionId = 0;
// A handful of ids that are used to generate gl_Position transformation code (for pre-rotation // A handful of ids that are used to generate gl_Position transformation code (for pre-rotation
// or depth correction). These IDs are used to load/store gl_Position and apply modifications // or depth correction). These IDs are used to load/store gl_Position and apply modifications
// and swizzles. // and swizzles.
...@@ -2177,6 +2152,12 @@ void SpirvTransformer::writeOutputPrologue() ...@@ -2177,6 +2152,12 @@ void SpirvTransformer::writeOutputPrologue()
writeAccessChain(positionPointerId, mVec4OutTypePointerId, mOutputPerVertexId, mInt0Id); writeAccessChain(positionPointerId, mVec4OutTypePointerId, mOutputPerVertexId, mInt0Id);
writeLoad(positionId, mVec4Id, positionPointerId); writeLoad(positionId, mVec4Id, positionPointerId);
if (mOptions.isTransformFeedbackStage && mTransformFeedbackExtensionPositionId != 0)
{
writeTransformFeedbackExtensionOutput(positionId);
}
writeCompositeExtract(xId, mFloatId, positionId, 0); writeCompositeExtract(xId, mFloatId, positionId, 0);
writeCompositeExtract(yId, mFloatId, positionId, 1); writeCompositeExtract(yId, mFloatId, positionId, 1);
writeCompositeExtract(zId, mFloatId, positionId, 2); writeCompositeExtract(zId, mFloatId, positionId, 2);
...@@ -2258,6 +2239,11 @@ void SpirvTransformer::transformZToVulkanClipSpace(uint32_t zId, ...@@ -2258,6 +2239,11 @@ void SpirvTransformer::transformZToVulkanClipSpace(uint32_t zId,
writeFMul(*correctedZIdOut, mFloatId, zPlusWId, mFloatHalfId); writeFMul(*correctedZIdOut, mFloatId, zPlusWId, mFloatHalfId);
} }
void SpirvTransformer::writeTransformFeedbackExtensionOutput(uint32_t positionId)
{
writeStore(mTransformFeedbackExtensionPositionId, positionId);
}
void SpirvTransformer::visitDecorate(const uint32_t *instruction) void SpirvTransformer::visitDecorate(const uint32_t *instruction)
{ {
// SPIR-V 1.0 Section 3.32 Instructions, OpDecorate // SPIR-V 1.0 Section 3.32 Instructions, OpDecorate
...@@ -2570,6 +2556,13 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction) ...@@ -2570,6 +2556,13 @@ void SpirvTransformer::visitVariable(const uint32_t *instruction)
info.activeStages[mOptions.shaderType]) info.activeStages[mOptions.shaderType])
{ {
mHasTransformFeedbackOutput = true; mHasTransformFeedbackOutput = true;
// If this is the special ANGLEXfbPosition variable, remember its id to be used for the
// ANGLEXfbPosition = gl_Position; assignment code generation.
if (strcmp(name, sh::vk::kXfbExtensionPositionOutName) == 0)
{
mTransformFeedbackExtensionPositionId = id;
}
} }
} }
...@@ -4456,26 +4449,15 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -4456,26 +4449,15 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
gl::ShaderType xfbStage = programState.getAttachedTransformFeedbackStage(); gl::ShaderType xfbStage = programState.getAttachedTransformFeedbackStage();
std::string *xfbSource = &(*shaderSourcesOut)[xfbStage]; std::string *xfbSource = &(*shaderSourcesOut)[xfbStage];
// Write transform feedback output code. // Write transform feedback output code for emulation path
if (!xfbSource->empty()) if (xfbStage == gl::ShaderType::Vertex && !xfbSource->empty() &&
options.emulateTransformFeedback)
{ {
if (!programState.getLinkedTransformFeedbackVaryings().empty()) if (!programState.getLinkedTransformFeedbackVaryings().empty())
{ {
if (options.supportsTransformFeedbackExtension) GenerateTransformFeedbackEmulationOutputs(options, xfbStage, programState,
{ programInterfaceInfo, xfbSource,
GenerateTransformFeedbackExtensionOutputs(programState, xfbSource); variableInfoMapOut);
}
else if (options.emulateTransformFeedback)
{
ASSERT(xfbStage == gl::ShaderType::Vertex);
GenerateTransformFeedbackEmulationOutputs(options, xfbStage, programState,
programInterfaceInfo, xfbSource,
variableInfoMapOut);
}
else
{
*xfbSource = SubstituteTransformFeedbackMarkers(*xfbSource, "");
}
} }
else else
{ {
...@@ -4483,18 +4465,6 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options, ...@@ -4483,18 +4465,6 @@ void GlslangGetShaderSource(const GlslangSourceOptions &options,
} }
} }
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;
for (const gl::ShaderType shaderType : programState.getExecutable().getLinkedShaderStages()) for (const gl::ShaderType shaderType : programState.getExecutable().getLinkedShaderStages())
......
...@@ -91,7 +91,8 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte ...@@ -91,7 +91,8 @@ std::shared_ptr<WaitableCompileEvent> ShaderVk::compile(const gl::Context *conte
{ {
compileOptions |= SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE; compileOptions |= SH_ADD_VULKAN_XFB_EXTENSION_SUPPORT_CODE;
} }
else if (contextVk->getFeatures().emulateTransformFeedback.enabled) else if (mState.getShaderType() == gl::ShaderType::Vertex &&
contextVk->getFeatures().emulateTransformFeedback.enabled)
{ {
compileOptions |= SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE; compileOptions |= SH_ADD_VULKAN_XFB_EMULATION_SUPPORT_CODE;
} }
......
...@@ -921,6 +921,7 @@ void RendererVk::ensureCapsInitialized() const ...@@ -921,6 +921,7 @@ void RendererVk::ensureCapsInitialized() const
{ {
// TODO: geometry shader support is incomplete. http://anglebug.com/3571 // TODO: geometry shader support is incomplete. http://anglebug.com/3571
mNativeExtensions.geometryShader = mNativeExtensions.geometryShader =
mFeatures.supportsTransformFeedbackExtension.enabled &&
mFeatures.exposeNonConformantExtensionsAndVersions.enabled; mFeatures.exposeNonConformantExtensionsAndVersions.enabled;
mNativeCaps.maxFramebufferLayers = LimitToInt(limitsVk.maxFramebufferLayers); mNativeCaps.maxFramebufferLayers = LimitToInt(limitsVk.maxFramebufferLayers);
mNativeCaps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT; mNativeCaps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
......
...@@ -186,8 +186,6 @@ ...@@ -186,8 +186,6 @@
// Geometry shader support: // Geometry shader support:
5430 VULKAN : dEQP-GLES31.functional.geometry_shading.query.primitives_generated_* = FAIL 5430 VULKAN : dEQP-GLES31.functional.geometry_shading.query.primitives_generated_* = FAIL
5452 VULKAN : dEQP-GLES31.functional.geometry_shading.layered.layer_provoking_vertex_* = FAIL 5452 VULKAN : dEQP-GLES31.functional.geometry_shading.layered.layer_provoking_vertex_* = FAIL
3571 VULKAN : dEQP-GLES31.functional.geometry_shading.*transform_feedback* = SKIP
3571 VULKAN : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.*geo* = SKIP
//// ////
//// AMD Vulkan expectations //// AMD Vulkan expectations
......
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