Commit aa8b10ae by Charlie Lao Committed by Commit Bot

Vulkan: Avoid driver call when yflip changed but shader not using it

If shader is not using yflip, don't get into driver to ask for a new pipeline program just because yflip has changed. Instead try to use the non-yflipped program. Bug: b/173461931 Change-Id: If938f5dc0632529c4f5e477fcb0c67bf58a1f3d0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2549538Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
parent 9041ca0c
...@@ -1085,6 +1085,11 @@ angle::Result ContextVk::handleDirtyGraphicsPipeline(const gl::Context *context, ...@@ -1085,6 +1085,11 @@ angle::Result ContextVk::handleDirtyGraphicsPipeline(const gl::Context *context,
{ {
const vk::GraphicsPipelineDesc *descPtr; const vk::GraphicsPipelineDesc *descPtr;
// The desc's surface rotation specialization constant depends on both program's
// specConstUsageBits and drawable. We need to update it if program has changed.
SpecConstUsageBits usageBits = getCurrentProgramSpecConstUsageBits();
updateGraphicsPipelineDescWithSpecConstUsageBits(usageBits);
// Draw call shader patching, shader compilation, and pipeline cache query. // Draw call shader patching, shader compilation, and pipeline cache query.
ANGLE_TRY(mExecutable->getGraphicsPipeline( ANGLE_TRY(mExecutable->getGraphicsPipeline(
this, mCurrentDrawMode, *mGraphicsPipelineDesc, this, mCurrentDrawMode, *mGraphicsPipelineDesc,
...@@ -3121,22 +3126,46 @@ void ContextVk::updateFlipViewportReadFramebuffer(const gl::State &glState) ...@@ -3121,22 +3126,46 @@ void ContextVk::updateFlipViewportReadFramebuffer(const gl::State &glState)
mFlipViewportForReadFramebuffer = readFramebuffer->isDefault(); mFlipViewportForReadFramebuffer = readFramebuffer->isDefault();
} }
void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState) SpecConstUsageBits ContextVk::getCurrentProgramSpecConstUsageBits() const
{ {
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); SpecConstUsageBits usageBits;
mCurrentRotationDrawFramebuffer = if (mState.getProgram())
DetermineSurfaceRotation(drawFramebuffer, mCurrentWindowSurface); {
usageBits = mState.getProgram()->getState().getSpecConstUsageBits();
}
else if (mState.getProgramPipeline())
{
usageBits = mState.getProgramPipeline()->getState().getSpecConstUsageBits();
}
return usageBits;
}
// DetermineSurfaceRotation() does not encode yflip information. Shader code uses void ContextVk::updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits)
// SurfaceRotation specialization constant to determine yflip as well. We add yflip information {
// to the SurfaceRotation here so the shader does yflip properly.
SurfaceRotation rotationAndFlip = mCurrentRotationDrawFramebuffer; SurfaceRotation rotationAndFlip = mCurrentRotationDrawFramebuffer;
if (isViewportFlipEnabledForDrawFBO()) ASSERT(ToUnderlying(rotationAndFlip) < ToUnderlying(SurfaceRotation::FlippedIdentity));
bool yFlipped =
isViewportFlipEnabledForDrawFBO() && usageBits.test(sh::vk::SpecConstUsage::YFlip);
// If program is not using rotation at all, we force it to use the Identity or FlippedIdentity
// slot to improve the program cache hit rate
if (!usageBits.test(sh::vk::SpecConstUsage::Rotation))
{ {
ASSERT(ToUnderlying(rotationAndFlip) < ToUnderlying(SurfaceRotation::FlippedIdentity)); rotationAndFlip = yFlipped ? SurfaceRotation::FlippedIdentity : SurfaceRotation::Identity;
}
else if (yFlipped)
{
// DetermineSurfaceRotation() does not encode yflip information. Shader code uses
// SurfaceRotation specialization constant to determine yflip as well. We add yflip
// information to the SurfaceRotation here so the shader does yflip properly.
rotationAndFlip = static_cast<SurfaceRotation>( rotationAndFlip = static_cast<SurfaceRotation>(
ToUnderlying(SurfaceRotation::FlippedIdentity) + ToUnderlying(rotationAndFlip)); ToUnderlying(SurfaceRotation::FlippedIdentity) + ToUnderlying(rotationAndFlip));
} }
else
{
// If program is not using yflip, then we just use the non-flipped slot to increase the
// chance of pipeline program cache hit even if drawable is yflipped.
}
if (rotationAndFlip != mGraphicsPipelineDesc->getSurfaceRotation()) if (rotationAndFlip != mGraphicsPipelineDesc->getSurfaceRotation())
{ {
...@@ -3147,6 +3176,16 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState) ...@@ -3147,6 +3176,16 @@ void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState)
} }
} }
void ContextVk::updateSurfaceRotationDrawFramebuffer(const gl::State &glState)
{
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
mCurrentRotationDrawFramebuffer =
DetermineSurfaceRotation(drawFramebuffer, mCurrentWindowSurface);
SpecConstUsageBits usageBits = getCurrentProgramSpecConstUsageBits();
updateGraphicsPipelineDescWithSpecConstUsageBits(usageBits);
}
void ContextVk::updateSurfaceRotationReadFramebuffer(const gl::State &glState) void ContextVk::updateSurfaceRotationReadFramebuffer(const gl::State &glState)
{ {
gl::Framebuffer *readFramebuffer = glState.getReadFramebuffer(); gl::Framebuffer *readFramebuffer = glState.getReadFramebuffer();
......
...@@ -861,6 +861,9 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -861,6 +861,9 @@ class ContextVk : public ContextImpl, public vk::Context
void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples); void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
void updateRasterizationSamples(const uint32_t rasterizationSamples); void updateRasterizationSamples(const uint32_t rasterizationSamples);
SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const;
void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits);
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers; std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
......
...@@ -288,20 +288,6 @@ ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState, ...@@ -288,20 +288,6 @@ ProgramVk *ProgramExecutableVk::getShaderProgram(const gl::State &glState,
return nullptr; return nullptr;
} }
SpecConstUsageBits ProgramExecutableVk::getSpecConstUsageBits() const
{
if (mProgram)
{
return mProgram->getState().getSpecConstUsageBits();
}
else if (mProgramPipeline)
{
return mProgramPipeline->getState().getSpecConstUsageBits();
}
return SpecConstUsageBits();
}
// TODO: http://anglebug.com/3570: Move/Copy all of the necessary information into // TODO: http://anglebug.com/3570: Move/Copy all of the necessary information into
// the ProgramExecutable, so this function can be removed. // the ProgramExecutable, so this function can be removed.
void ProgramExecutableVk::fillProgramStateMap( void ProgramExecutableVk::fillProgramStateMap(
...@@ -677,11 +663,10 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline( ...@@ -677,11 +663,10 @@ angle::Result ProgramExecutableVk::getGraphicsPipeline(
ASSERT(glExecutable && !glExecutable->isCompute()); ASSERT(glExecutable && !glExecutable->isCompute());
mTransformOptions.enableLineRasterEmulation = contextVk->isBresenhamEmulationEnabled(mode); mTransformOptions.enableLineRasterEmulation = contextVk->isBresenhamEmulationEnabled(mode);
mTransformOptions.surfaceRotation = static_cast<uint8_t>(desc.getSurfaceRotation()); mTransformOptions.surfaceRotation = ToUnderlying(desc.getSurfaceRotation());
// This must be called after mTransformOptions have been set. // This must be called after mTransformOptions have been set.
ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptions); ProgramInfo &programInfo = getGraphicsProgramInfo(mTransformOptions);
for (const gl::ShaderType shaderType : glExecutable->getLinkedShaderStages()) for (const gl::ShaderType shaderType : glExecutable->getLinkedShaderStages())
{ {
ProgramVk *programVk = getShaderProgram(glState, shaderType); ProgramVk *programVk = getShaderProgram(glState, shaderType);
......
...@@ -181,8 +181,6 @@ class ProgramExecutableVk ...@@ -181,8 +181,6 @@ class ProgramExecutableVk
const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; } const PerfCounters getObjectPerfCounters() const { return mObjectPerfCounters; }
SpecConstUsageBits getSpecConstUsageBits() const;
private: private:
friend class ProgramVk; friend class ProgramVk;
friend class ProgramPipelineVk; friend class ProgramPipelineVk;
......
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