Add support for direct use of vulkan primary command buffer in render pass.

Change-Id: Icd43965da49963fc9b6ac6c1f7a40be50f2055e8
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/239920
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Greg Daniel 2019-09-06 11:05:27 -04:00 committed by Skia Commit-Bot
parent b9ce8351f4
commit eedd08576a
5 changed files with 37 additions and 16 deletions

View File

@ -141,6 +141,11 @@ public:
// Returns true if the device supports protected memory.
bool supportsProtectedMemory() const { return fSupportsProtectedMemory; }
// Returns whether we prefer to record draws directly into a primary command buffer.
bool preferPrimaryOverSecondaryCommandBuffers() const {
return fPreferPrimaryOverSecondaryCommandBuffers;
}
/**
* Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means
* the surface is not a render target, otherwise it is the number of samples in the render
@ -300,6 +305,8 @@ private:
bool fSupportsProtectedMemory = false;
bool fPreferPrimaryOverSecondaryCommandBuffers = true;
typedef GrCaps INHERITED;
};

View File

@ -2481,7 +2481,7 @@ void adjust_bounds_to_granularity(SkIRect* dstBounds, const SkIRect& srcBounds,
void GrVkGpu::beginRenderPass(const GrVkRenderPass* renderPass,
const VkClearValue* colorClear,
GrVkRenderTarget* target, GrSurfaceOrigin origin,
const SkIRect& bounds) {
const SkIRect& bounds, bool forSecondaryCB) {
SkASSERT (!target->wrapsSecondaryCommandBuffer());
auto nativeBounds = GrNativeRect::MakeRelativeTo(origin, target->height(), bounds);
@ -2511,7 +2511,8 @@ void GrVkGpu::beginRenderPass(const GrVkRenderPass* renderPass,
clears[1].depthStencil.depth = 0.0f;
clears[1].depthStencil.stencil = 0;
fCurrentCmdBuffer->beginRenderPass(this, renderPass, clears, *target, adjustedBounds, true);
fCurrentCmdBuffer->beginRenderPass(this, renderPass, clears, *target, adjustedBounds,
forSecondaryCB);
}
void GrVkGpu::endRenderPass(GrRenderTarget* target, GrSurfaceOrigin origin,

View File

@ -179,7 +179,7 @@ public:
void beginRenderPass(const GrVkRenderPass*,
const VkClearValue* colorClear,
GrVkRenderTarget*, GrSurfaceOrigin,
const SkIRect& bounds);
const SkIRect& bounds, bool forSecondaryCB);
void endRenderPass(GrRenderTarget* target, GrSurfaceOrigin origin, const SkIRect& bounds);
private:

View File

@ -119,10 +119,13 @@ void GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
vkClearColor.color.float32[2] = clearColor[2];
vkClearColor.color.float32[3] = clearColor[3];
fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds);
if (!fGpu->vkCaps().preferPrimaryOverSecondaryCommandBuffers()) {
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
}
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
SkToBool(fCurrentSecondaryCommandBuffer));
}
void GrVkOpsRenderPass::initWrapped() {
@ -144,9 +147,10 @@ GrVkOpsRenderPass::~GrVkOpsRenderPass() {
GrGpu* GrVkOpsRenderPass::gpu() { return fGpu; }
GrVkCommandBuffer* GrVkOpsRenderPass::currentCommandBuffer() {
// TODO: In the future this function may return the GrVkGpu's primary command buffer.
SkASSERT(fCurrentSecondaryCommandBuffer);
return fCurrentSecondaryCommandBuffer.get();
if (fCurrentSecondaryCommandBuffer) {
return fCurrentSecondaryCommandBuffer.get();
}
return fGpu->currentCommandBuffer();
}
void GrVkOpsRenderPass::end() {
@ -332,7 +336,7 @@ void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& colo
////////////////////////////////////////////////////////////////////////////////
void GrVkOpsRenderPass::addAdditionalRenderPass() {
void GrVkOpsRenderPass::addAdditionalRenderPass(bool mustUseSecondaryCommandBuffer) {
SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
@ -358,12 +362,17 @@ void GrVkOpsRenderPass::addAdditionalRenderPass() {
VkClearValue vkClearColor;
memset(&vkClearColor, 0, sizeof(VkClearValue));
if (!fGpu->vkCaps().preferPrimaryOverSecondaryCommandBuffers() ||
mustUseSecondaryCommandBuffer) {
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
}
// We use the same fBounds as the whole GrVkOpsRenderPass since we have no way of tracking the
// bounds in GrOpsTask for parts before and after inline uploads separately.
fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds);
fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds,
SkToBool(fCurrentSecondaryCommandBuffer));
}
void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state,
@ -378,7 +387,7 @@ void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state,
// layout back to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
state->doUpload(upload, true);
this->addAdditionalRenderPass();
this->addAdditionalRenderPass(false);
}
////////////////////////////////////////////////////////////////////////////////
@ -613,6 +622,10 @@ void GrVkOpsRenderPass::executeDrawable(std::unique_ptr<SkDrawable::GpuDrawHandl
bounds.offset = { 0, 0 };
bounds.extent = { 0, 0 };
if (!fCurrentSecondaryCommandBuffer) {
fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
this->addAdditionalRenderPass(true);
}
SkASSERT(fCurrentSecondaryCommandBuffer);
GrVkDrawableInfo vkInfo;

View File

@ -115,7 +115,7 @@ private:
void onClearStencilClip(const GrFixedClip&, bool insideStencilMask) override;
void addAdditionalRenderPass();
void addAdditionalRenderPass(bool mustUseSecondaryCommandBuffer);
std::unique_ptr<GrVkSecondaryCommandBuffer> fCurrentSecondaryCommandBuffer;
const GrVkRenderPass* fCurrentRenderPass;