зеркало из https://github.com/AvaloniaUI/angle.git
Vulkan: Flush descriptor set updates during flush*Commands()
The intent of this CL is to reduce the number of descriptor set updates by delaying the work until all of the GLES commands that could trigger a re-update have been performed and the command stream is being flushed. To achieve this, flushDescriptorSetUpdates() is being moved from setupDraw()/setupDispatch() to flushRenderPassCommands()/flushOutsideRPCommands(). This change also exposed an issue where the BufferView handles were not being preserved until flushDescriptorSetUpdates() was called. To resolve this, flushDescriptorSetUpdates() is also being called during BufferViewHelper::release() before the BufferView memory is released. Bug: angleproject:5706 Change-Id: I61e19af9c0fac891aa2115d72391459b80d22f19 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2939385 Reviewed-by: Charlie Lao <cclao@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Tim Van Patten <timvp@google.com>
This commit is contained in:
Родитель
bf42f0096f
Коммит
02b73c2fd7
|
@ -347,7 +347,7 @@ constexpr ContextVk::DirtyBits ContextVk::kResourcesAndDescSetDirtyBits;
|
|||
constexpr ContextVk::DirtyBits ContextVk::kXfbBuffersAndDescSetDirtyBits;
|
||||
constexpr ContextVk::DirtyBits ContextVk::kDriverUniformsAndBindingDirtyBits;
|
||||
|
||||
ANGLE_INLINE void ContextVk::flushDescriptorSetUpdates()
|
||||
void ContextVk::flushDescriptorSetUpdates()
|
||||
{
|
||||
if (mWriteDescriptorSets.empty())
|
||||
{
|
||||
|
@ -371,17 +371,6 @@ ANGLE_INLINE void ContextVk::onRenderPassFinished()
|
|||
mGraphicsDirtyBits.set(DIRTY_BIT_RENDER_PASS);
|
||||
}
|
||||
|
||||
// ContextVk::ScopedDescriptorSetUpdates implementation.
|
||||
class ContextVk::ScopedDescriptorSetUpdates final : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
ANGLE_INLINE ScopedDescriptorSetUpdates(ContextVk *contextVk) : mContextVk(contextVk) {}
|
||||
ANGLE_INLINE ~ScopedDescriptorSetUpdates() { mContextVk->flushDescriptorSetUpdates(); }
|
||||
|
||||
private:
|
||||
ContextVk *mContextVk;
|
||||
};
|
||||
|
||||
ContextVk::DriverUniformsDescriptorSet::DriverUniformsDescriptorSet()
|
||||
: descriptorSet(VK_NULL_HANDLE), dynamicOffset(0)
|
||||
{}
|
||||
|
@ -851,10 +840,6 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
|
|||
mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
|
||||
}
|
||||
|
||||
// Create a local object to ensure we flush the descriptor updates to device when we leave this
|
||||
// function
|
||||
ScopedDescriptorSetUpdates descriptorSetUpdates(this);
|
||||
|
||||
if (mProgram && mProgram->dirtyUniforms())
|
||||
{
|
||||
ANGLE_TRY(mProgram->updateUniforms(this));
|
||||
|
@ -1096,10 +1081,6 @@ angle::Result ContextVk::setupDispatch(const gl::Context *context)
|
|||
// TODO: Remove this and fix tests. http://anglebug.com/5070
|
||||
ANGLE_TRY(flushOutsideRenderPassCommands());
|
||||
|
||||
// Create a local object to ensure we flush the descriptor updates to device when we leave this
|
||||
// function
|
||||
ScopedDescriptorSetUpdates descriptorSetUpdates(this);
|
||||
|
||||
if (mProgram && mProgram->dirtyUniforms())
|
||||
{
|
||||
ANGLE_TRY(mProgram->updateUniforms(this));
|
||||
|
@ -5721,6 +5702,7 @@ angle::Result ContextVk::flushCommandsAndEndRenderPassImpl()
|
|||
ANGLE_TRY(getRenderPassWithOps(mRenderPassCommands->getRenderPassDesc(),
|
||||
mRenderPassCommands->getAttachmentOps(), &renderPass));
|
||||
|
||||
flushDescriptorSetUpdates();
|
||||
ANGLE_TRY(mRenderer->flushRenderPassCommands(this, hasProtectedContent(), *renderPass,
|
||||
&mRenderPassCommands));
|
||||
|
||||
|
@ -5870,6 +5852,7 @@ angle::Result ContextVk::flushOutsideRenderPassCommands()
|
|||
mOutsideRenderPassCommands->addCommandDiagnostics(this);
|
||||
}
|
||||
|
||||
flushDescriptorSetUpdates();
|
||||
ANGLE_TRY(mRenderer->flushOutsideRPCommands(this, hasProtectedContent(),
|
||||
&mOutsideRenderPassCommands));
|
||||
|
||||
|
|
|
@ -636,6 +636,8 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
|
|||
|
||||
angle::Result handleGraphicsEventLog(GraphicsEventCmdBuf queryEventType);
|
||||
|
||||
void flushDescriptorSetUpdates();
|
||||
|
||||
private:
|
||||
// Dirty bits.
|
||||
enum DirtyBitType : size_t
|
||||
|
@ -912,7 +914,6 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText
|
|||
angle::Result flushCommandsAndEndRenderPassImpl();
|
||||
angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
|
||||
DirtyBits dirtyBitMask);
|
||||
void flushDescriptorSetUpdates();
|
||||
|
||||
void onRenderPassFinished();
|
||||
|
||||
|
|
|
@ -1467,7 +1467,7 @@ void TextureVk::releaseAndDeleteImageAndViews(ContextVk *contextVk)
|
|||
mImageCreateFlags = 0;
|
||||
SafeDelete(mImage);
|
||||
}
|
||||
mBufferViews.release(contextVk->getRenderer());
|
||||
mBufferViews.release(contextVk);
|
||||
mRedefinedLevels.reset();
|
||||
}
|
||||
|
||||
|
@ -2539,7 +2539,7 @@ angle::Result TextureVk::syncState(const gl::Context *context,
|
|||
const VkDeviceSize offset = bufferBinding.getOffset();
|
||||
const VkDeviceSize size = gl::GetBoundBufferAvailableSize(bufferBinding);
|
||||
|
||||
mBufferViews.release(renderer);
|
||||
mBufferViews.release(contextVk);
|
||||
mBufferViews.init(renderer, offset, size);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
|
|
@ -8205,8 +8205,10 @@ void BufferViewHelper::init(RendererVk *renderer, VkDeviceSize offset, VkDeviceS
|
|||
}
|
||||
}
|
||||
|
||||
void BufferViewHelper::release(RendererVk *renderer)
|
||||
void BufferViewHelper::release(ContextVk *contextVk)
|
||||
{
|
||||
contextVk->flushDescriptorSetUpdates();
|
||||
|
||||
std::vector<GarbageObject> garbage;
|
||||
|
||||
for (auto &formatAndView : mViews)
|
||||
|
@ -8219,13 +8221,14 @@ void BufferViewHelper::release(RendererVk *renderer)
|
|||
|
||||
if (!garbage.empty())
|
||||
{
|
||||
renderer->collectGarbage(std::move(mUse), std::move(garbage));
|
||||
RendererVk *rendererVk = contextVk->getRenderer();
|
||||
rendererVk->collectGarbage(std::move(mUse), std::move(garbage));
|
||||
|
||||
// Ensure the resource use is always valid.
|
||||
mUse.init();
|
||||
|
||||
// Update image view serial.
|
||||
mViewSerial = renderer->getResourceSerialFactory().generateImageOrBufferViewSerial();
|
||||
mViewSerial = rendererVk->getResourceSerialFactory().generateImageOrBufferViewSerial();
|
||||
}
|
||||
|
||||
mViews.clear();
|
||||
|
|
|
@ -2505,7 +2505,7 @@ class BufferViewHelper final : public Resource
|
|||
~BufferViewHelper() override;
|
||||
|
||||
void init(RendererVk *renderer, VkDeviceSize offset, VkDeviceSize size);
|
||||
void release(RendererVk *renderer);
|
||||
void release(ContextVk *contextVk);
|
||||
void destroy(VkDevice device);
|
||||
|
||||
angle::Result getView(ContextVk *contextVk,
|
||||
|
|
Загрузка…
Ссылка в новой задаче