Begin renderpasses immediately in GrVkOpsRenderPass.
This change will allow us to easily switch between rendering to a
primary vs secondary command buffer.
Change-Id: Iaa066f24b64a686db41a1554b0d75c185714ef8c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/239100
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/vk/GrVkOpsRenderPass.cpp b/src/gpu/vk/GrVkOpsRenderPass.cpp
index a42bef4..e884710 100644
--- a/src/gpu/vk/GrVkOpsRenderPass.cpp
+++ b/src/gpu/vk/GrVkOpsRenderPass.cpp
@@ -26,25 +26,6 @@
#include "src/gpu/vk/GrVkSemaphore.h"
#include "src/gpu/vk/GrVkTexture.h"
-GrVkPrimaryCommandBufferTask::~GrVkPrimaryCommandBufferTask() = default;
-GrVkPrimaryCommandBufferTask::GrVkPrimaryCommandBufferTask() = default;
-
-namespace {
-
-class InlineUpload : public GrVkPrimaryCommandBufferTask {
-public:
- InlineUpload(GrOpFlushState* state, const GrDeferredTextureUploadFn& upload)
- : fFlushState(state), fUpload(upload) {}
-
- void execute(const Args& args) override { fFlushState->doUpload(fUpload, true); }
-
-private:
- GrOpFlushState* fFlushState;
- GrDeferredTextureUploadFn fUpload;
-};
-
-} // anonymous namespace
-
/////////////////////////////////////////////////////////////////////////////
void get_vk_load_store_ops(GrLoadOp loadOpIn, GrStoreOp storeOpIn,
@@ -79,64 +60,81 @@
GrVkOpsRenderPass::GrVkOpsRenderPass(GrVkGpu* gpu) : fGpu(gpu) {}
-void GrVkOpsRenderPass::init() {
- GrVkRenderPass::LoadStoreOps vkColorOps(fVkColorLoadOp, fVkColorStoreOp);
- GrVkRenderPass::LoadStoreOps vkStencilOps(fVkStencilLoadOp, fVkStencilStoreOp);
+void GrVkOpsRenderPass::init(const GrOpsRenderPass::LoadAndStoreInfo& colorInfo,
+ const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
+ const SkPMColor4f& clearColor) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
- SkASSERT(fCommandBufferInfos.count() == 1);
- fCurrentCmdInfo = 0;
+ VkAttachmentLoadOp loadOp;
+ VkAttachmentStoreOp storeOp;
+ get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
+ &loadOp, &storeOp);
+ GrVkRenderPass::LoadStoreOps vkColorOps(loadOp, storeOp);
+
+ get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
+ &loadOp, &storeOp);
+ GrVkRenderPass::LoadStoreOps vkStencilOps(loadOp, storeOp);
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
+ GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
+
+ // Change layout of our render target so it can be used as the color attachment.
+ // TODO: If we know that we will never be blending or loading the attachment we could drop the
+ // VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.
+ targetImage->setImageLayout(fGpu,
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+ VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+ false);
+
+ // If we are using a stencil attachment we also need to update its layout
+ if (GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment()) {
+ GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
+ // We need the write and read access bits since we may load and store the stencil.
+ // The initial load happens in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT so we
+ // wait there.
+ vkStencil->setImageLayout(fGpu,
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
+ VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
+ false);
+ }
+
const GrVkResourceProvider::CompatibleRPHandle& rpHandle = vkRT->compatibleRenderPassHandle();
if (rpHandle.isValid()) {
- cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
vkStencilOps);
} else {
- cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
vkColorOps,
vkStencilOps);
}
+ SkASSERT(fCurrentRenderPass);
- cbInfo.fColorClearValue.color.float32[0] = fClearColor[0];
- cbInfo.fColorClearValue.color.float32[1] = fClearColor[1];
- cbInfo.fColorClearValue.color.float32[2] = fClearColor[2];
- cbInfo.fColorClearValue.color.float32[3] = fClearColor[3];
+ VkClearValue vkClearColor;
+ vkClearColor.color.float32[0] = clearColor[0];
+ vkClearColor.color.float32[1] = clearColor[1];
+ vkClearColor.color.float32[2] = clearColor[2];
+ vkClearColor.color.float32[3] = clearColor[3];
- if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
- cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
- } else {
- cbInfo.fBounds.setEmpty();
- }
+ fGpu->beginRenderPass(fCurrentRenderPass, &vkClearColor, vkRT, fOrigin, fBounds);
- if (VK_ATTACHMENT_LOAD_OP_CLEAR == fVkColorLoadOp) {
- cbInfo.fLoadStoreState = LoadStoreState::kStartsWithClear;
- } else if (VK_ATTACHMENT_LOAD_OP_LOAD == fVkColorLoadOp &&
- VK_ATTACHMENT_STORE_OP_STORE == fVkColorStoreOp) {
- cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
- } else if (VK_ATTACHMENT_LOAD_OP_DONT_CARE == fVkColorLoadOp) {
- cbInfo.fLoadStoreState = LoadStoreState::kStartsWithDiscard;
- }
-
- cbInfo.fCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
- cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
+ fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
}
void GrVkOpsRenderPass::initWrapped() {
- CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
- SkASSERT(fCommandBufferInfos.count() == 1);
- fCurrentCmdInfo = 0;
-
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
SkASSERT(vkRT->wrapsSecondaryCommandBuffer());
- cbInfo.fRenderPass = vkRT->externalRenderPass();
- cbInfo.fRenderPass->ref();
+ fCurrentRenderPass = vkRT->externalRenderPass();
+ SkASSERT(fCurrentRenderPass);
+ fCurrentRenderPass->ref();
- cbInfo.fBounds.setEmpty();
- cbInfo.fCommandBuffer.reset(
+ fCurrentSecondaryCommandBuffer.reset(
GrVkSecondaryCommandBuffer::Create(vkRT->getExternalSecondaryCommandBuffer()));
- cbInfo.currentCmdBuf()->begin(fGpu, nullptr, cbInfo.fRenderPass);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, nullptr, fCurrentRenderPass);
}
GrVkOpsRenderPass::~GrVkOpsRenderPass() {
@@ -145,9 +143,15 @@
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();
+}
+
void GrVkOpsRenderPass::end() {
- if (fCurrentCmdInfo >= 0) {
- fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
+ if (fCurrentSecondaryCommandBuffer) {
+ fCurrentSecondaryCommandBuffer->end(fGpu);
}
}
@@ -156,85 +160,15 @@
return;
}
- GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
- GrVkImage* targetImage = vkRT->msaaImage() ? vkRT->msaaImage() : vkRT;
- GrStencilAttachment* stencil = fRenderTarget->renderTargetPriv().getStencilAttachment();
- auto currPreCmd = fPreCommandBufferTasks.begin();
-
- GrVkPrimaryCommandBufferTask::Args taskArgs{fGpu, fRenderTarget};
- for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
-
- for (int c = 0; c < cbInfo.fNumPreCmds; ++c, ++currPreCmd) {
- currPreCmd->execute(taskArgs);
- }
-
- // TODO: Many things create a scratch texture which adds the discard immediately, but then
- // don't draw to it right away. This causes the discard to be ignored and we get yelled at
- // for loading uninitialized data. However, once MDB lands with reordering, the discard will
- // get reordered with the rest of the draw commands and we can remove the discard check.
- if (cbInfo.fIsEmpty &&
- cbInfo.fLoadStoreState != LoadStoreState::kStartsWithClear &&
- cbInfo.fLoadStoreState != LoadStoreState::kStartsWithDiscard) {
- // We have sumbitted no actual draw commands to the command buffer and we are not using
- // the render pass to do a clear so there is no need to submit anything.
- continue;
- }
-
- // We don't want to actually submit the secondary command buffer if it is wrapped.
- if (this->wrapsSecondaryCommandBuffer()) {
- // There should have only been one secondary command buffer in the wrapped case so it is
- // safe to just return here.
- SkASSERT(fCommandBufferInfos.count() == 1);
- return;
- }
-
- // Make sure if we only have a discard load that we execute the discard on the whole image.
- // TODO: Once we improve our tracking of discards so that we never end up flushing a discard
- // call with no actually ops, remove this.
- if (cbInfo.fIsEmpty && cbInfo.fLoadStoreState == LoadStoreState::kStartsWithDiscard) {
- cbInfo.fBounds = SkRect::MakeWH(vkRT->width(), vkRT->height());
- }
-
- if (cbInfo.fBounds.intersect(SkRect::MakeIWH(fRenderTarget->width(),
- fRenderTarget->height()))) {
- // Make sure we do the following layout changes after all copies, uploads, or any other
- // pre-work is done since we may change the layouts in the pre-work. Also since the
- // draws will be submitted in different render passes, we need to guard againts write
- // and write issues.
-
- // Change layout of our render target so it can be used as the color attachment.
- // TODO: If we know that we will never be blending or loading the attachment we could
- // drop the VK_ACCESS_COLOR_ATTACHMENT_READ_BIT.
- targetImage->setImageLayout(fGpu,
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
- VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
- VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- false);
-
- // If we are using a stencil attachment we also need to update its layout
- if (stencil) {
- GrVkStencilAttachment* vkStencil = (GrVkStencilAttachment*)stencil;
- // We need the write and read access bits since we may load and store the stencil.
- // The initial load happens in the VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT so we
- // wait there.
- vkStencil->setImageLayout(fGpu,
- VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT |
- VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
- VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
- false);
- }
-
- SkIRect iBounds;
- cbInfo.fBounds.roundOut(&iBounds);
-
- fGpu->submitSecondaryCommandBuffer(std::move(cbInfo.fCommandBuffer), cbInfo.fRenderPass,
- &cbInfo.fColorClearValue, vkRT, fOrigin, iBounds);
- }
+ // We don't want to actually submit the secondary command buffer if it is wrapped.
+ if (this->wrapsSecondaryCommandBuffer()) {
+ return;
}
- SkASSERT(currPreCmd == fPreCommandBufferTasks.end());
+
+ if (fCurrentSecondaryCommandBuffer) {
+ fGpu->submitSecondaryCommandBuffer(std::move(fCurrentSecondaryCommandBuffer));
+ }
+ fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
}
void GrVkOpsRenderPass::set(GrRenderTarget* rt, GrSurfaceOrigin origin,
@@ -242,10 +176,7 @@
const GrOpsRenderPass::StencilLoadAndStoreInfo& stencilInfo,
const SkTArray<GrTextureProxy*, true>& sampledProxies) {
SkASSERT(!fRenderTarget);
- SkASSERT(fCommandBufferInfos.empty());
- SkASSERT(-1 == fCurrentCmdInfo);
SkASSERT(fGpu == rt->getContext()->priv().getGpu());
- SkASSERT(!fLastPipelineState);
#ifdef SK_DEBUG
fIsActive = true;
@@ -268,31 +199,23 @@
return;
}
- fClearColor = colorInfo.fClearColor;
+ // TODO: This should be passed in via the GrOpsTask instead of always setting it to the full
+ // render target bounds.
+ fBounds = SkIRect::MakeWH(fRenderTarget->width(), fRenderTarget->height());
- get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
- &fVkColorLoadOp, &fVkColorStoreOp);
-
- get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
- &fVkStencilLoadOp, &fVkStencilStoreOp);
-
- this->init();
+ this->init(colorInfo, stencilInfo, colorInfo.fClearColor);
}
void GrVkOpsRenderPass::reset() {
- for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
- if (cbInfo.fCommandBuffer) {
- cbInfo.fCommandBuffer.release()->recycle(fGpu);
- }
- cbInfo.fRenderPass->unref(fGpu);
+ if (fCurrentSecondaryCommandBuffer) {
+ fCurrentSecondaryCommandBuffer.release()->recycle(fGpu);
}
- fCommandBufferInfos.reset();
- fPreCommandBufferTasks.reset();
+ if (fCurrentRenderPass) {
+ fCurrentRenderPass->unref(fGpu);
+ fCurrentRenderPass = nullptr;
+ }
+ fCurrentCBIsEmpty = true;
- fCurrentCmdInfo = -1;
-
- fLastPipelineState = nullptr;
fRenderTarget = nullptr;
#ifdef SK_DEBUG
@@ -314,8 +237,6 @@
void GrVkOpsRenderPass::onClearStencilClip(const GrFixedClip& clip, bool insideStencilMask) {
SkASSERT(!clip.hasWindowRectangles());
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
-
GrStencilAttachment* sb = fRenderTarget->renderTargetPriv().getStencilAttachment();
// this should only be called internally when we know we have a
// stencil buffer.
@@ -353,30 +274,21 @@
clearRect.layerCount = 1;
uint32_t stencilIndex;
- SkAssertResult(cbInfo.fRenderPass->stencilAttachmentIndex(&stencilIndex));
+ SkAssertResult(fCurrentRenderPass->stencilAttachmentIndex(&stencilIndex));
VkClearAttachment attachment;
attachment.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
attachment.colorAttachment = 0; // this value shouldn't matter
attachment.clearValue.depthStencil = vkStencilColor;
- cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
- cbInfo.fIsEmpty = false;
-
- // Update command buffer bounds
- if (!clip.scissorEnabled()) {
- cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
- } else {
- cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
- }
+ this->currentCommandBuffer()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
+ fCurrentCBIsEmpty = false;
}
void GrVkOpsRenderPass::onClear(const GrFixedClip& clip, const SkPMColor4f& color) {
// parent class should never let us get here with no RT
SkASSERT(!clip.hasWindowRectangles());
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
-
VkClearColorValue vkColor = {{color.fR, color.fG, color.fB, color.fA}};
// If we end up in a situation where we are calling clear without a scissior then in general it
@@ -385,7 +297,7 @@
// load op (e.g. if we needed to execute a wait op). Thus we also have the empty check here.
// TODO: Make the waitOp a RenderTask instead so we can clear out the GrOpsTask for a clear. We
// can then reenable this assert assuming we can't get messed up by a waitOp.
- //SkASSERT(!cbInfo.fIsEmpty || clip.scissorEnabled());
+ //SkASSERT(!fCurrentCBIsEmpty || clip.scissorEnabled());
// We always do a sub rect clear with clearAttachments since we are inside a render pass
VkClearRect clearRect;
@@ -406,35 +318,24 @@
clearRect.layerCount = 1;
uint32_t colorIndex;
- SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&colorIndex));
+ SkAssertResult(fCurrentRenderPass->colorAttachmentIndex(&colorIndex));
VkClearAttachment attachment;
attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
attachment.colorAttachment = colorIndex;
attachment.clearValue.color = vkColor;
- cbInfo.currentCmdBuf()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
- cbInfo.fIsEmpty = false;
-
- // Update command buffer bounds
- if (!clip.scissorEnabled()) {
- cbInfo.fBounds.join(fRenderTarget->getBoundsRect());
- } else {
- cbInfo.fBounds.join(SkRect::Make(clip.scissorRect()));
- }
+ this->currentCommandBuffer()->clearAttachments(fGpu, 1, &attachment, 1, &clearRect);
+ fCurrentCBIsEmpty = false;
return;
}
////////////////////////////////////////////////////////////////////////////////
void GrVkOpsRenderPass::addAdditionalRenderPass() {
+ SkASSERT(!this->wrapsSecondaryCommandBuffer());
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);
- fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf()->end(fGpu);
-
- CommandBufferInfo& cbInfo = fCommandBufferInfos.push_back();
- fCurrentCmdInfo++;
-
GrVkRenderPass::LoadStoreOps vkColorOps(VK_ATTACHMENT_LOAD_OP_LOAD,
VK_ATTACHMENT_STORE_OP_STORE);
GrVkRenderPass::LoadStoreOps vkStencilOps(VK_ATTACHMENT_LOAD_OP_LOAD,
@@ -442,34 +343,42 @@
const GrVkResourceProvider::CompatibleRPHandle& rpHandle =
vkRT->compatibleRenderPassHandle();
+ SkASSERT(fCurrentRenderPass);
+ fCurrentRenderPass->unref(fGpu);
if (rpHandle.isValid()) {
- cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(rpHandle,
vkColorOps,
vkStencilOps);
} else {
- cbInfo.fRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
+ fCurrentRenderPass = fGpu->resourceProvider().findRenderPass(*vkRT,
vkColorOps,
vkStencilOps);
}
- cbInfo.fLoadStoreState = LoadStoreState::kLoadAndStore;
+ SkASSERT(fCurrentRenderPass);
- cbInfo.fCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
- // It shouldn't matter what we set the clear color to here since we will assume loading of the
- // attachment.
- memset(&cbInfo.fColorClearValue, 0, sizeof(VkClearValue));
- cbInfo.fBounds.setEmpty();
+ VkClearValue vkClearColor;
+ memset(&vkClearColor, 0, sizeof(VkClearValue));
+ // 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);
- cbInfo.currentCmdBuf()->begin(fGpu, vkRT->framebuffer(), cbInfo.fRenderPass);
+ fCurrentSecondaryCommandBuffer = fGpu->cmdPool()->findOrCreateSecondaryCommandBuffer(fGpu);
+ fCurrentSecondaryCommandBuffer->begin(fGpu, vkRT->framebuffer(), fCurrentRenderPass);
}
void GrVkOpsRenderPass::inlineUpload(GrOpFlushState* state,
GrDeferredTextureUploadFn& upload) {
- if (!fCommandBufferInfos[fCurrentCmdInfo].fIsEmpty) {
- this->addAdditionalRenderPass();
+ if (fCurrentSecondaryCommandBuffer) {
+ fCurrentSecondaryCommandBuffer->end(fGpu);
+ fGpu->submitSecondaryCommandBuffer(std::move(fCurrentSecondaryCommandBuffer));
}
+ fGpu->endRenderPass(fRenderTarget, fOrigin, fBounds);
- fPreCommandBufferTasks.emplace<InlineUpload>(state, upload);
- ++fCommandBufferInfos[fCurrentCmdInfo].fNumPreCmds;
+ // We pass in true here to signal that after the upload we need to set the upload textures
+ // layout back to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL.
+ state->doUpload(upload, true);
+
+ this->addAdditionalRenderPass();
}
////////////////////////////////////////////////////////////////////////////////
@@ -477,7 +386,7 @@
void GrVkOpsRenderPass::bindGeometry(const GrGpuBuffer* indexBuffer,
const GrGpuBuffer* vertexBuffer,
const GrGpuBuffer* instanceBuffer) {
- GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
+ GrVkCommandBuffer* currCmdBuf = this->currentCommandBuffer();
// There is no need to put any memory barriers to make sure host writes have finished here.
// When a command buffer is submitted to a queue, there is an implicit memory barrier that
// occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
@@ -516,10 +425,10 @@
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrPipeline::DynamicStateArrays* dynamicStateArrays,
GrPrimitiveType primitiveType) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
- SkASSERT(cbInfo.fRenderPass);
+ GrVkCommandBuffer* currentCB = this->currentCommandBuffer();
+ SkASSERT(fCurrentRenderPass);
- VkRenderPass compatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
+ VkRenderPass compatibleRenderPass = fCurrentRenderPass->vkRenderPass();
const GrTextureProxy* const* primProcProxies = nullptr;
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
@@ -541,34 +450,27 @@
return pipelineState;
}
- fLastPipelineState = pipelineState;
+ pipelineState->bindPipeline(fGpu, currentCB);
- pipelineState->bindPipeline(fGpu, cbInfo.currentCmdBuf());
-
- pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin,
- primProc, pipeline, cbInfo.currentCmdBuf());
+ pipelineState->setAndBindUniforms(fGpu, fRenderTarget, fOrigin, primProc, pipeline, currentCB);
// Check whether we need to bind textures between each GrMesh. If not we can bind them all now.
bool setTextures = !(dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures);
if (setTextures) {
- pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies,
- cbInfo.currentCmdBuf());
+ pipelineState->setAndBindTextures(fGpu, primProc, pipeline, primProcProxies, currentCB);
}
if (!pipeline.isScissorEnabled()) {
- GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(),
- fRenderTarget, fOrigin,
+ GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
SkIRect::MakeWH(fRenderTarget->width(),
fRenderTarget->height()));
} else if (!dynamicStateArrays || !dynamicStateArrays->fScissorRects) {
SkASSERT(fixedDynamicState);
- GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
- fOrigin,
+ GrVkPipeline::SetDynamicScissorRectState(fGpu, currentCB, fRenderTarget, fOrigin,
fixedDynamicState->fScissorRect);
}
- GrVkPipeline::SetDynamicViewportState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget);
- GrVkPipeline::SetDynamicBlendConstantState(fGpu, cbInfo.currentCmdBuf(),
- pipeline.outputSwizzle(),
+ GrVkPipeline::SetDynamicViewportState(fGpu, currentCB, fRenderTarget);
+ GrVkPipeline::SetDynamicBlendConstantState(fGpu, currentCB, pipeline.outputSwizzle(),
pipeline.getXferProcessor());
return pipelineState;
@@ -594,8 +496,6 @@
return;
}
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
-
#ifdef SK_DEBUG
if (dynamicStateArrays && dynamicStateArrays->fPrimitiveProcessorTextures) {
for (int m = 0, i = 0; m < meshCount; ++m) {
@@ -646,22 +546,21 @@
}
if (dynamicScissor) {
- GrVkPipeline::SetDynamicScissorRectState(fGpu, cbInfo.currentCmdBuf(), fRenderTarget,
- fOrigin,
+ GrVkPipeline::SetDynamicScissorRectState(fGpu, this->currentCommandBuffer(),
+ fRenderTarget, fOrigin,
dynamicStateArrays->fScissorRects[i]);
}
if (dynamicTextures) {
GrTextureProxy* const* meshProxies = dynamicStateArrays->fPrimitiveProcessorTextures +
primProc.numTextureSamplers() * i;
pipelineState->setAndBindTextures(fGpu, primProc, pipeline, meshProxies,
- cbInfo.currentCmdBuf());
+ this->currentCommandBuffer());
}
SkASSERT(pipelineState);
mesh.sendToGpu(this);
}
- cbInfo.fBounds.join(bounds);
- cbInfo.fIsEmpty = false;
+ fCurrentCBIsEmpty = false;
}
void GrVkOpsRenderPass::sendInstancedMeshToGpu(GrPrimitiveType,
@@ -671,13 +570,12 @@
const GrBuffer* instanceBuffer,
int instanceCount,
int baseInstance) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
this->bindGeometry(nullptr, gpuVertexBuffer, gpuInstanceBuffer);
- cbInfo.currentCmdBuf()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
+ this->currentCommandBuffer()->draw(fGpu, vertexCount, instanceCount, baseVertex, baseInstance);
fGpu->stats()->incNumDraws();
}
@@ -692,7 +590,6 @@
int baseInstance,
GrPrimitiveRestart restart) {
SkASSERT(restart == GrPrimitiveRestart::kNo);
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
SkASSERT(!vertexBuffer || !vertexBuffer->isCpuBuffer());
SkASSERT(!instanceBuffer || !instanceBuffer->isCpuBuffer());
SkASSERT(!indexBuffer->isCpuBuffer());
@@ -700,8 +597,8 @@
auto gpuVertexBuffer = static_cast<const GrGpuBuffer*>(vertexBuffer);
auto gpuInstanceBuffer = static_cast<const GrGpuBuffer*>(instanceBuffer);
this->bindGeometry(gpuIndexxBuffer, gpuVertexBuffer, gpuInstanceBuffer);
- cbInfo.currentCmdBuf()->drawIndexed(fGpu, indexCount, instanceCount,
- baseIndex, baseVertex, baseInstance);
+ this->currentCommandBuffer()->drawIndexed(fGpu, indexCount, instanceCount,
+ baseIndex, baseVertex, baseInstance);
fGpu->stats()->incNumDraws();
}
@@ -712,15 +609,16 @@
GrVkImage* targetImage = target->msaaImage() ? target->msaaImage() : target;
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
VkRect2D bounds;
bounds.offset = { 0, 0 };
bounds.extent = { 0, 0 };
+ SkASSERT(fCurrentSecondaryCommandBuffer);
+
GrVkDrawableInfo vkInfo;
- vkInfo.fSecondaryCommandBuffer = cbInfo.currentCmdBuf()->vkCommandBuffer();
- vkInfo.fCompatibleRenderPass = cbInfo.fRenderPass->vkRenderPass();
- SkAssertResult(cbInfo.fRenderPass->colorAttachmentIndex(&vkInfo.fColorAttachmentIndex));
+ vkInfo.fSecondaryCommandBuffer = fCurrentSecondaryCommandBuffer->vkCommandBuffer();
+ vkInfo.fCompatibleRenderPass = fCurrentRenderPass->vkRenderPass();
+ SkAssertResult(fCurrentRenderPass->colorAttachmentIndex(&vkInfo.fColorAttachmentIndex));
vkInfo.fFormat = targetImage->imageFormat();
vkInfo.fDrawBounds = &bounds;
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@@ -732,18 +630,11 @@
GrBackendDrawableInfo info(vkInfo);
// After we draw into the command buffer via the drawable, cached state we have may be invalid.
- cbInfo.currentCmdBuf()->invalidateState();
+ this->currentCommandBuffer()->invalidateState();
// Also assume that the drawable produced output.
- cbInfo.fIsEmpty = false;
+ fCurrentCBIsEmpty = false;
drawable->draw(info);
fGpu->addDrawable(std::move(drawable));
-
- if (bounds.extent.width == 0 || bounds.extent.height == 0) {
- cbInfo.fBounds.join(target->getBoundsRect());
- } else {
- cbInfo.fBounds.join(SkRect::MakeXYWH(bounds.offset.x, bounds.offset.y,
- bounds.extent.width, bounds.extent.height));
- }
}