Hash :
70d1ef67
Author :
Date :
2024-11-20T11:34:39
Vulkan: Ensure onFramebufferBoundary is called for offscreen There is peak memory regression observed from crrev.com/c/6022549. What I suspect happening is that for offscreen or single buffered case, glFlush/glFinish is called but bail out because it already submitted or deferred. So we end up not calling onFramebufferBoundary(). This CL ensures we always call onFramebufferBoundary from these two functions for single buffer or offscreen. Also fixed a bug when onSharedPresentContextFlush is called we may end up calling onFramebufferBoundary. To make API names consistent, existing flushImpl() is renamed to flushAndSubmitCommands() and a new flushIMpl is added to wrap around most logic inside flush(). Bug: angleproject:372268711 Change-Id: I54eed8a81f4153d52ab962f213cacc87a73b89ac Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6037491 Reviewed-by: Yuxin Hu <yuxinhu@google.com> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Resource:
// Resource lifetime tracking in the Vulkan back-end.
//
#include "libANGLE/renderer/vulkan/vk_resource.h"
#include "libANGLE/renderer/vulkan/ContextVk.h"
namespace rx
{
namespace vk
{
// Resource implementation.
angle::Result Resource::waitForIdle(ContextVk *contextVk,
const char *debugMessage,
RenderPassClosureReason reason)
{
// If there are pending commands for the resource, flush them.
if (contextVk->hasUnsubmittedUse(mUse))
{
ANGLE_TRY(contextVk->flushAndSubmitCommands(nullptr, nullptr, reason));
}
Renderer *renderer = contextVk->getRenderer();
// Make sure the driver is done with the resource.
if (!renderer->hasResourceUseFinished(mUse))
{
if (debugMessage)
{
ANGLE_VK_PERF_WARNING(contextVk, GL_DEBUG_SEVERITY_HIGH, "%s", debugMessage);
}
ANGLE_TRY(renderer->finishResourceUse(contextVk, mUse));
}
ASSERT(renderer->hasResourceUseFinished(mUse));
return angle::Result::Continue;
}
std::ostream &operator<<(std::ostream &os, const ResourceUse &use)
{
const Serials &serials = use.getSerials();
os << '{';
for (size_t i = 0; i < serials.size(); i++)
{
os << serials[i].getValue();
if (i < serials.size() - 1)
{
os << ",";
}
}
os << '}';
return os;
}
// SharedGarbage implementation.
SharedGarbage::SharedGarbage() = default;
SharedGarbage::SharedGarbage(SharedGarbage &&other)
{
*this = std::move(other);
}
SharedGarbage::SharedGarbage(const ResourceUse &use, GarbageObjects &&garbage)
: mLifetime(use), mGarbage(std::move(garbage))
{}
SharedGarbage::~SharedGarbage() = default;
SharedGarbage &SharedGarbage::operator=(SharedGarbage &&rhs)
{
std::swap(mLifetime, rhs.mLifetime);
std::swap(mGarbage, rhs.mGarbage);
return *this;
}
bool SharedGarbage::destroyIfComplete(Renderer *renderer)
{
if (renderer->hasResourceUseFinished(mLifetime))
{
for (GarbageObject &object : mGarbage)
{
object.destroy(renderer);
}
return true;
}
return false;
}
bool SharedGarbage::hasResourceUseSubmitted(Renderer *renderer) const
{
return renderer->hasResourceUseSubmitted(mLifetime);
}
// ReleasableResource implementation.
template <class T>
void ReleasableResource<T>::release(Renderer *renderer)
{
renderer->collectGarbage(mUse, &mObject);
}
template class ReleasableResource<Semaphore>;
} // namespace vk
} // namespace rx