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:
parent
5fab90999f
commit
32d6c8d024
@ -181,6 +181,11 @@ void GrVkOpsRenderPass::submit() {
|
|||||||
|
|
||||||
// We don't want to actually submit the secondary command buffer if it is wrapped.
|
// We don't want to actually submit the secondary command buffer if it is wrapped.
|
||||||
if (this->wrapsSecondaryCommandBuffer()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,6 +356,11 @@ void GrVkRenderTarget::releaseInternalObjects() {
|
|||||||
fCachedSimpleRenderPass->unref(gpu);
|
fCachedSimpleRenderPass->unref(gpu);
|
||||||
fCachedSimpleRenderPass = nullptr;
|
fCachedSimpleRenderPass = nullptr;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
|
||||||
|
SkASSERT(fGrSecondaryCommandBuffers[i]);
|
||||||
|
fGrSecondaryCommandBuffers[i]->releaseResources(gpu);
|
||||||
|
}
|
||||||
|
fGrSecondaryCommandBuffers.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrVkRenderTarget::abandonInternalObjects() {
|
void GrVkRenderTarget::abandonInternalObjects() {
|
||||||
@ -380,6 +385,11 @@ void GrVkRenderTarget::abandonInternalObjects() {
|
|||||||
fCachedSimpleRenderPass->unrefAndAbandon();
|
fCachedSimpleRenderPass->unrefAndAbandon();
|
||||||
fCachedSimpleRenderPass = nullptr;
|
fCachedSimpleRenderPass = nullptr;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < fGrSecondaryCommandBuffers.count(); ++i) {
|
||||||
|
SkASSERT(fGrSecondaryCommandBuffers[i]);
|
||||||
|
fGrSecondaryCommandBuffers[i]->abandonGPUData();
|
||||||
|
}
|
||||||
|
fGrSecondaryCommandBuffers.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrVkRenderTarget::onRelease() {
|
void GrVkRenderTarget::onRelease() {
|
||||||
|
@ -13,14 +13,13 @@
|
|||||||
#include "src/gpu/vk/GrVkImage.h"
|
#include "src/gpu/vk/GrVkImage.h"
|
||||||
|
|
||||||
#include "include/gpu/vk/GrVkTypes.h"
|
#include "include/gpu/vk/GrVkTypes.h"
|
||||||
|
#include "src/gpu/vk/GrVkCommandBuffer.h"
|
||||||
#include "src/gpu/vk/GrVkRenderPass.h"
|
#include "src/gpu/vk/GrVkRenderPass.h"
|
||||||
#include "src/gpu/vk/GrVkResourceProvider.h"
|
#include "src/gpu/vk/GrVkResourceProvider.h"
|
||||||
|
|
||||||
class GrVkCommandBuffer;
|
|
||||||
class GrVkFramebuffer;
|
class GrVkFramebuffer;
|
||||||
class GrVkGpu;
|
class GrVkGpu;
|
||||||
class GrVkImageView;
|
class GrVkImageView;
|
||||||
class GrVkSecondaryCommandBuffer;
|
|
||||||
class GrVkStencilAttachment;
|
class GrVkStencilAttachment;
|
||||||
|
|
||||||
struct GrVkImageInfo;
|
struct GrVkImageInfo;
|
||||||
@ -91,6 +90,10 @@ public:
|
|||||||
|
|
||||||
void addResources(GrVkCommandBuffer& commandBuffer);
|
void addResources(GrVkCommandBuffer& commandBuffer);
|
||||||
|
|
||||||
|
void addWrappedGrSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer> cmdBuffer) {
|
||||||
|
fGrSecondaryCommandBuffers.push_back(std::move(cmdBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GrVkRenderTarget(GrVkGpu* gpu,
|
GrVkRenderTarget(GrVkGpu* gpu,
|
||||||
const GrSurfaceDesc& desc,
|
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
|
// 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.
|
// an actual VkImage and will thus be limited in terms of what it can be used for.
|
||||||
VkCommandBuffer fSecondaryCommandBuffer = VK_NULL_HANDLE;
|
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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user