зеркало из https://github.com/AvaloniaUI/angle.git
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: Tim Van Patten <timvp@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Родитель
9b4cfd1883
Коммит
357caadb09
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче