When wrapped, store ref to GrVkSecondaryCommandBuffer on GrVkRenderTarget.

We need the wrapped GrVkSeocndaryCommandBuffer to live, holding refs to
GrVkResources until the GPU is done with the work. However, we don't know
ourselves when the command buffer gets submitted or when the GPU is done
since the client handles on that in the wrapped case. Our spec for wrapped
secondary command buffers requires to the client to keep the
GrSecondaryCommandBufferContext alive till the GPU is done the work so we
can use that to manage our needed lifetime as well. By putting the
GrVkSecondaryCommandBuffer on the GrVkRenderTarget, which is owned by the
SkGpuDevice in the above GrSCBContext, or lifetime should match what we need.

Change-Id: I7cdd92089bed390548ebf33f9d5c7e714bacc9c5
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/256361
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2019-11-25 16:23:50 -05:00 committed by Skia Commit-Bot
parent 5fab90999f
commit 32d6c8d024
3 changed files with 30 additions and 2 deletions

View File

@ -181,6 +181,11 @@ void GrVkOpsRenderPass::submit() {
// We don't want to actually submit the secondary command buffer if it is wrapped.
if (this->wrapsSecondaryCommandBuffer()) {
// We pass the ownership of the GrVkSecondaryCommandBuffer to the special wrapped
// GrVkRenderTarget since it's lifetime matches the lifetime we need to keep the
// GrVkResources on the GrVkSecondaryCommandBuffer alive.
static_cast<GrVkRenderTarget*>(fRenderTarget)->addWrappedGrSecondaryCommandBuffer(
std::move(fCurrentSecondaryCommandBuffer));
return;
}

View File

@ -356,6 +356,11 @@ void GrVkRenderTarget::releaseInternalObjects() {
fCachedSimpleRenderPass->unref(gpu);
fCachedSimpleRenderPass = nullptr;
}
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
SkASSERT(fGrSecondaryCommandBuffers[i]);
fGrSecondaryCommandBuffers[i]->releaseResources(gpu);
}
fGrSecondaryCommandBuffers.reset();
}
void GrVkRenderTarget::abandonInternalObjects() {
@ -380,6 +385,11 @@ void GrVkRenderTarget::abandonInternalObjects() {
fCachedSimpleRenderPass->unrefAndAbandon();
fCachedSimpleRenderPass = nullptr;
}
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
SkASSERT(fGrSecondaryCommandBuffers[i]);
fGrSecondaryCommandBuffers[i]->abandonGPUData();
}
fGrSecondaryCommandBuffers.reset();
}
void GrVkRenderTarget::onRelease() {

View File

@ -13,14 +13,13 @@
#include "src/gpu/vk/GrVkImage.h"
#include "include/gpu/vk/GrVkTypes.h"
#include "src/gpu/vk/GrVkCommandBuffer.h"
#include "src/gpu/vk/GrVkRenderPass.h"
#include "src/gpu/vk/GrVkResourceProvider.h"
class GrVkCommandBuffer;
class GrVkFramebuffer;
class GrVkGpu;
class GrVkImageView;
class GrVkSecondaryCommandBuffer;
class GrVkStencilAttachment;
struct GrVkImageInfo;
@ -91,6 +90,10 @@ public:
void addResources(GrVkCommandBuffer& commandBuffer);
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer));
}
protected:
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
@ -183,6 +186,16 @@ private:
// VkCommandBuffer and not VK_NULL_HANDLE. In this case the render target will not be backed by
// an actual VkImage and will thus be limited in terms of what it can be used for.
VkCommandBuffer fSecondaryCommandBuffer = VK_NULL_HANDLE;
// When we wrap a secondary command buffer, we will record GrVkResources onto it which need to
// be kept alive till the command buffer gets submitted and the GPU has finished. However, in
// the wrapped case, we don't know when the command buffer gets submitted and when it is
// finished on the GPU since the client is in charge of that. However, we do require that the
// client keeps the GrVkSecondaryCBDrawContext alive and call releaseResources on it once the
// GPU is finished all the work. Thus we can use this to manage the lifetime of our
// GrVkSecondaryCommandBuffers. By storing them on the GrVkRenderTarget, which is owned by the
// SkGpuDevice on the GrVkSecondaryCBDrawContext, we assure that the GrVkResources held by the
// GrVkSecondaryCommandBuffer don't get deleted before they are allowed to.
SkTArray<std::unique_ptr<GrVkCommandBuffer>> fGrSecondaryCommandBuffers;
};
#endif