Commit 357caadb by Jamie Madill Committed by Commit Bot

Vulkan: Optimize Attribute Change Perf (2/5)

This patch series optimizes programs that use the pattern: for (;;) { glVertexAttribPointer(...) glDraw(...) } Change 2: Micro-optimize XFB resume CPU overhead. We don't need to set resume on every new command buffer. We only need to set the dirty bit when we have an unexpected pause. In total the patch series reduces test iteration time by 25%. Test: DrawCallPerfBenchmark.Run/vulkan_attrib_change Bug: angleproject:5045 Bug: b/168493024 Change-Id: I8f6c68ff0513be4f405276e395d80bc1a185a061 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2409174 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 9b4cfd18
......@@ -694,16 +694,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_SHADER_RESOURCES);
if (getFeatures().supportsTransformFeedbackExtension.enabled ||
getFeatures().emulateTransformFeedback.enabled)
{
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS);
}
if (getFeatures().supportsTransformFeedbackExtension.enabled)
{
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_STATE);
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME);
}
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
mNewGraphicsCommandBufferDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
......@@ -713,12 +703,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mNewComputeCommandBufferDirtyBits.set(DIRTY_BIT_DESCRIPTOR_SETS);
mNewComputeCommandBufferDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS_BINDING);
mNewGraphicsPipelineDirtyBits.set(DIRTY_BIT_PIPELINE);
if (getFeatures().supportsTransformFeedbackExtension.enabled)
{
mNewGraphicsPipelineDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME);
}
mGraphicsDirtyBitHandlers[DIRTY_BIT_DEFAULT_ATTRIBS] =
&ContextVk::handleDirtyGraphicsDefaultAttribs;
mGraphicsDirtyBitHandlers[DIRTY_BIT_PIPELINE] = &ContextVk::handleDirtyGraphicsPipeline;
......@@ -1354,7 +1338,9 @@ angle::Result ContextVk::handleDirtyGraphicsPipeline(const gl::Context *context,
mGraphicsPipelineTransition.reset();
}
mRenderPassCommands->pauseTransformFeedbackIfStarted();
resumeTransformFeedbackIfStarted();
commandBuffer->bindGraphicsPipeline(mCurrentGraphicsPipeline->getPipeline());
// Update the queue serial for the pipeline object.
ASSERT(mCurrentGraphicsPipeline && mCurrentGraphicsPipeline->valid());
......@@ -1646,7 +1632,10 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackResume(
const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
mRenderPassCommands->resumeTransformFeedbackIfStarted();
if (mRenderPassCommands->isTransformFeedbackStarted())
{
mRenderPassCommands->resumeTransformFeedback();
}
return angle::Result::Continue;
}
......@@ -3194,6 +3183,17 @@ angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
updateSurfaceRotationReadFramebuffer(glState);
invalidateDriverUniforms();
const gl::ProgramExecutable *executable = mState.getProgramExecutable();
if (executable && executable->hasTransformFeedbackOutput() &&
mState.isTransformFeedbackActive())
{
onTransformFeedbackStateChanged();
if (getFeatures().supportsTransformFeedbackExtension.enabled)
{
mGraphicsDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME);
}
}
return angle::Result::Continue;
}
......@@ -3442,7 +3442,7 @@ void ContextVk::onTransformFeedbackStateChanged()
if (getFeatures().supportsTransformFeedbackExtension.enabled)
{
mGraphicsDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_STATE);
invalidateCurrentTransformFeedbackBuffers();
mGraphicsDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS);
}
else if (getFeatures().emulateTransformFeedback.enabled)
{
......@@ -3492,7 +3492,10 @@ void ContextVk::onEndTransformFeedback()
{
if (getFeatures().supportsTransformFeedbackExtension.enabled)
{
mRenderPassCommands->endTransformFeedback();
if (mRenderPassCommands->isTransformFeedbackStarted())
{
mRenderPassCommands->endTransformFeedback();
}
}
else if (getFeatures().emulateTransformFeedback.enabled)
{
......@@ -3508,6 +3511,7 @@ angle::Result ContextVk::onPauseTransformFeedback()
}
else if (getFeatures().emulateTransformFeedback.enabled)
{
invalidateCurrentTransformFeedbackBuffers();
return flushCommandsAndEndRenderPass();
}
return angle::Result::Continue;
......@@ -3676,6 +3680,16 @@ void ContextVk::writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOu
}
}
ANGLE_INLINE void ContextVk::resumeTransformFeedbackIfStarted()
{
if (mRenderPassCommands->isTransformFeedbackStarted())
{
ASSERT(getFeatures().supportsTransformFeedbackExtension.enabled);
mGraphicsDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME);
mRenderPassCommands->pauseTransformFeedback();
}
}
angle::Result ContextVk::handleDirtyGraphicsDriverUniforms(const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
......@@ -4664,6 +4678,8 @@ angle::Result ContextVk::flushCommandsAndEndRenderPass()
addOverlayUsedBuffersCount(mRenderPassCommands);
resumeTransformFeedbackIfStarted();
mRenderPassCommands->endRenderPass(this);
if (mRenderer->getFeatures().enableCommandProcessingThread.enabled)
......
......@@ -795,7 +795,7 @@ class ContextVk : public ContextImpl, public vk::Context
ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
{
mGraphicsDirtyBits |= mNewGraphicsPipelineDirtyBits;
mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE);
}
ANGLE_INLINE void invalidateCurrentComputePipeline()
......@@ -919,6 +919,7 @@ class ContextVk : public ContextImpl, public vk::Context
void populateTransformFeedbackBufferSet(
size_t bufferCount,
const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
void resumeTransformFeedbackIfStarted();
// DescriptorSet writes
template <typename T, const T *VkWriteDescriptorSet::*pInfo>
......@@ -964,7 +965,6 @@ class ContextVk : public ContextImpl, public vk::Context
DirtyBits mIndexedDirtyBitsMask;
DirtyBits mNewGraphicsCommandBufferDirtyBits;
DirtyBits mNewComputeCommandBufferDirtyBits;
DirtyBits mNewGraphicsPipelineDirtyBits;
// Cached back-end objects.
VertexArrayVk *mVertexArray;
......
......@@ -898,8 +898,6 @@ void CommandBufferHelper::restartRenderPassWithReadOnlyDepth(const Framebuffer &
void CommandBufferHelper::endRenderPass(ContextVk *contextVk)
{
pauseTransformFeedbackIfStarted();
if (mDepthStencilAttachmentIndex == kAttachmentIndexInvalid)
{
return;
......@@ -965,7 +963,7 @@ void CommandBufferHelper::beginTransformFeedback(size_t validBufferCount,
void CommandBufferHelper::endTransformFeedback()
{
ASSERT(mIsRenderPassCommandBuffer);
pauseTransformFeedbackIfStarted();
pauseTransformFeedback();
mValidTransformFeedbackBufferCount = 0;
}
......@@ -1164,13 +1162,10 @@ void CommandBufferHelper::releaseToContextQueue(ContextVk *contextVk)
contextVk->recycleCommandBuffer(this);
}
void CommandBufferHelper::resumeTransformFeedbackIfStarted()
void CommandBufferHelper::resumeTransformFeedback()
{
ASSERT(mIsRenderPassCommandBuffer);
if (mValidTransformFeedbackBufferCount == 0)
{
return;
}
ASSERT(isTransformFeedbackStarted());
uint32_t numCounterBuffers =
mRebindTransformFeedbackBuffers ? 0 : mValidTransformFeedbackBufferCount;
......@@ -1181,14 +1176,10 @@ void CommandBufferHelper::resumeTransformFeedbackIfStarted()
mTransformFeedbackCounterBuffers.data());
}
void CommandBufferHelper::pauseTransformFeedbackIfStarted()
void CommandBufferHelper::pauseTransformFeedback()
{
ASSERT(mIsRenderPassCommandBuffer);
if (mValidTransformFeedbackBufferCount == 0)
{
return;
}
ASSERT(isTransformFeedbackStarted());
mCommandBuffer.endTransformFeedback(mValidTransformFeedbackBufferCount,
mTransformFeedbackCounterBuffers.data());
}
......
......@@ -1047,8 +1047,9 @@ class CommandBufferHelper : angle::NonCopyable
return mRenderArea;
}
void resumeTransformFeedbackIfStarted();
void pauseTransformFeedbackIfStarted();
void resumeTransformFeedback();
void pauseTransformFeedback();
bool isTransformFeedbackStarted() const { return mValidTransformFeedbackBufferCount > 0; }
uint32_t getAndResetCounter()
{
......
......@@ -582,7 +582,8 @@ TEST_P(TransformFeedbackTest, MultiContext)
GLuint buffer;
size_t primitiveCounts[passCount];
};
ContextInfo contexts[32];
static constexpr uint32_t kContextCount = 32;
ContextInfo contexts[kContextCount];
const size_t maxDrawSize = 512;
......
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