Subclass GrVkCommandBuffer into Primary and Secondary CommandBuffers.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2019723002
Review-Url: https://codereview.chromium.org/2019723002
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index bc8c20f..9604355 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -16,24 +16,6 @@
#include "GrVkTransferBuffer.h"
#include "GrVkUtil.h"
-GrVkCommandBuffer* GrVkCommandBuffer::Create(const GrVkGpu* gpu, VkCommandPool cmdPool) {
- const VkCommandBufferAllocateInfo cmdInfo = {
- VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
- NULL, // pNext
- cmdPool, // commandPool
- VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
- 1 // bufferCount
- };
-
- VkCommandBuffer cmdBuffer;
- VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateCommandBuffers(gpu->device(),
- &cmdInfo,
- &cmdBuffer));
- if (err) {
- return nullptr;
- }
- return new GrVkCommandBuffer(cmdBuffer);
-}
GrVkCommandBuffer::~GrVkCommandBuffer() {
// Should have ended any render pass we're in the middle of
@@ -79,112 +61,6 @@
}
}
-void GrVkCommandBuffer::begin(const GrVkGpu* gpu) {
- SkASSERT(!fIsActive);
- VkCommandBufferBeginInfo cmdBufferBeginInfo;
- memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
- cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cmdBufferBeginInfo.pNext = nullptr;
- cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- cmdBufferBeginInfo.pInheritanceInfo = nullptr;
-
- GR_VK_CALL_ERRCHECK(gpu->vkInterface(), BeginCommandBuffer(fCmdBuffer,
- &cmdBufferBeginInfo));
- fIsActive = true;
-}
-
-void GrVkCommandBuffer::end(const GrVkGpu* gpu) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- GR_VK_CALL_ERRCHECK(gpu->vkInterface(), EndCommandBuffer(fCmdBuffer));
- this->invalidateState();
- fIsActive = false;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrVkCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
- const GrVkRenderPass* renderPass,
- const GrVkRenderTarget& target) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- VkRenderPassBeginInfo beginInfo;
- VkSubpassContents contents;
- renderPass->getBeginInfo(target, &beginInfo, &contents);
- GR_VK_CALL(gpu->vkInterface(), CmdBeginRenderPass(fCmdBuffer, &beginInfo, contents));
- fActiveRenderPass = renderPass;
- this->addResource(renderPass);
- target.addResources(*this);
-}
-
-void GrVkCommandBuffer::endRenderPass(const GrVkGpu* gpu) {
- SkASSERT(fIsActive);
- SkASSERT(fActiveRenderPass);
- GR_VK_CALL(gpu->vkInterface(), CmdEndRenderPass(fCmdBuffer));
- fActiveRenderPass = nullptr;
-}
-
-void GrVkCommandBuffer::submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync) {
- SkASSERT(!fIsActive);
-
- VkResult err;
- VkFenceCreateInfo fenceInfo;
- memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
- fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
- err = GR_VK_CALL(gpu->vkInterface(), CreateFence(gpu->device(), &fenceInfo, nullptr,
- &fSubmitFence));
- SkASSERT(!err);
-
- VkSubmitInfo submitInfo;
- memset(&submitInfo, 0, sizeof(VkSubmitInfo));
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.waitSemaphoreCount = 0;
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.pWaitDstStageMask = 0;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &fCmdBuffer;
- submitInfo.signalSemaphoreCount = 0;
- submitInfo.pSignalSemaphores = nullptr;
- GR_VK_CALL_ERRCHECK(gpu->vkInterface(), QueueSubmit(queue, 1, &submitInfo, fSubmitFence));
-
- if (GrVkGpu::kForce_SyncQueue == sync) {
- err = GR_VK_CALL(gpu->vkInterface(),
- WaitForFences(gpu->device(), 1, &fSubmitFence, true, UINT64_MAX));
- if (VK_TIMEOUT == err) {
- SkDebugf("Fence failed to signal: %d\n", err);
- SkFAIL("failing");
- }
- SkASSERT(!err);
-
- // Destroy the fence
- GR_VK_CALL(gpu->vkInterface(), DestroyFence(gpu->device(), fSubmitFence, nullptr));
- fSubmitFence = VK_NULL_HANDLE;
- }
-}
-
-bool GrVkCommandBuffer::finished(const GrVkGpu* gpu) const {
- if (VK_NULL_HANDLE == fSubmitFence) {
- return true;
- }
-
- VkResult err = GR_VK_CALL(gpu->vkInterface(), GetFenceStatus(gpu->device(), fSubmitFence));
- switch (err) {
- case VK_SUCCESS:
- return true;
-
- case VK_NOT_READY:
- return false;
-
- default:
- SkDebugf("Error getting fence status: %d\n", err);
- SkFAIL("failing");
- break;
- }
-
- return false;
-}
-
////////////////////////////////////////////////////////////////////////////////
// CommandBuffer commands
////////////////////////////////////////////////////////////////////////////////
@@ -239,118 +115,6 @@
}
-void GrVkCommandBuffer::copyImage(const GrVkGpu* gpu,
- GrVkImage* srcImage,
- VkImageLayout srcLayout,
- GrVkImage* dstImage,
- VkImageLayout dstLayout,
- uint32_t copyRegionCount,
- const VkImageCopy* copyRegions) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(srcImage->resource());
- this->addResource(dstImage->resource());
- GR_VK_CALL(gpu->vkInterface(), CmdCopyImage(fCmdBuffer,
- srcImage->image(),
- srcLayout,
- dstImage->image(),
- dstLayout,
- copyRegionCount,
- copyRegions));
-}
-
-void GrVkCommandBuffer::blitImage(const GrVkGpu* gpu,
- const GrVkResource* srcResource,
- VkImage srcImage,
- VkImageLayout srcLayout,
- const GrVkResource* dstResource,
- VkImage dstImage,
- VkImageLayout dstLayout,
- uint32_t blitRegionCount,
- const VkImageBlit* blitRegions,
- VkFilter filter) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(srcResource);
- this->addResource(dstResource);
- GR_VK_CALL(gpu->vkInterface(), CmdBlitImage(fCmdBuffer,
- srcImage,
- srcLayout,
- dstImage,
- dstLayout,
- blitRegionCount,
- blitRegions,
- filter));
-}
-
-void GrVkCommandBuffer::copyImageToBuffer(const GrVkGpu* gpu,
- GrVkImage* srcImage,
- VkImageLayout srcLayout,
- GrVkTransferBuffer* dstBuffer,
- uint32_t copyRegionCount,
- const VkBufferImageCopy* copyRegions) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(srcImage->resource());
- this->addResource(dstBuffer->resource());
- GR_VK_CALL(gpu->vkInterface(), CmdCopyImageToBuffer(fCmdBuffer,
- srcImage->image(),
- srcLayout,
- dstBuffer->buffer(),
- copyRegionCount,
- copyRegions));
-}
-
-void GrVkCommandBuffer::copyBufferToImage(const GrVkGpu* gpu,
- GrVkTransferBuffer* srcBuffer,
- GrVkImage* dstImage,
- VkImageLayout dstLayout,
- uint32_t copyRegionCount,
- const VkBufferImageCopy* copyRegions) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(srcBuffer->resource());
- this->addResource(dstImage->resource());
- GR_VK_CALL(gpu->vkInterface(), CmdCopyBufferToImage(fCmdBuffer,
- srcBuffer->buffer(),
- dstImage->image(),
- dstLayout,
- copyRegionCount,
- copyRegions));
-}
-
-void GrVkCommandBuffer::clearColorImage(const GrVkGpu* gpu,
- GrVkImage* image,
- const VkClearColorValue* color,
- uint32_t subRangeCount,
- const VkImageSubresourceRange* subRanges) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(image->resource());
- GR_VK_CALL(gpu->vkInterface(), CmdClearColorImage(fCmdBuffer,
- image->image(),
- image->currentLayout(),
- color,
- subRangeCount,
- subRanges));
-}
-
-void GrVkCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu,
- GrVkImage* image,
- const VkClearDepthStencilValue* color,
- uint32_t subRangeCount,
- const VkImageSubresourceRange* subRanges) {
- SkASSERT(fIsActive);
- SkASSERT(!fActiveRenderPass);
- this->addResource(image->resource());
- GR_VK_CALL(gpu->vkInterface(), CmdClearDepthStencilImage(fCmdBuffer,
- image->image(),
- image->currentLayout(),
- color,
- subRangeCount,
- subRanges));
-}
-
void GrVkCommandBuffer::clearAttachments(const GrVkGpu* gpu,
int numAttachments,
const VkClearAttachment* attachments,
@@ -472,3 +236,317 @@
memcpy(fCachedBlendConstant, blendConstants, 4 * sizeof(float));
}
}
+
+///////////////////////////////////////////////////////////////////////////////
+// PrimaryCommandBuffer
+////////////////////////////////////////////////////////////////////////////////
+GrVkPrimaryCommandBuffer* GrVkPrimaryCommandBuffer::Create(const GrVkGpu* gpu,
+ VkCommandPool cmdPool) {
+ const VkCommandBufferAllocateInfo cmdInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
+ NULL, // pNext
+ cmdPool, // commandPool
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
+ 1 // bufferCount
+ };
+
+ VkCommandBuffer cmdBuffer;
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateCommandBuffers(gpu->device(),
+ &cmdInfo,
+ &cmdBuffer));
+ if (err) {
+ return nullptr;
+ }
+ return new GrVkPrimaryCommandBuffer(cmdBuffer);
+}
+
+void GrVkPrimaryCommandBuffer::begin(const GrVkGpu* gpu) {
+ SkASSERT(!fIsActive);
+ VkCommandBufferBeginInfo cmdBufferBeginInfo;
+ memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
+ cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdBufferBeginInfo.pNext = nullptr;
+ cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), BeginCommandBuffer(fCmdBuffer,
+ &cmdBufferBeginInfo));
+ fIsActive = true;
+}
+
+void GrVkPrimaryCommandBuffer::end(const GrVkGpu* gpu) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), EndCommandBuffer(fCmdBuffer));
+ this->invalidateState();
+ fIsActive = false;
+}
+
+void GrVkPrimaryCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
+ const GrVkRenderPass* renderPass,
+ const GrVkRenderTarget& target) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ VkRenderPassBeginInfo beginInfo;
+ VkSubpassContents contents;
+ renderPass->getBeginInfo(target, &beginInfo, &contents);
+ GR_VK_CALL(gpu->vkInterface(), CmdBeginRenderPass(fCmdBuffer, &beginInfo, contents));
+ fActiveRenderPass = renderPass;
+ this->addResource(renderPass);
+ target.addResources(*this);
+}
+
+void GrVkPrimaryCommandBuffer::endRenderPass(const GrVkGpu* gpu) {
+ SkASSERT(fIsActive);
+ SkASSERT(fActiveRenderPass);
+ GR_VK_CALL(gpu->vkInterface(), CmdEndRenderPass(fCmdBuffer));
+ fActiveRenderPass = nullptr;
+}
+
+void GrVkPrimaryCommandBuffer::executeCommands(const GrVkGpu* gpu,
+ const GrVkSecondaryCommandBuffer* buffer) {
+ SkASSERT(fIsActive);
+ SkASSERT(fActiveRenderPass);
+ SkASSERT(fActiveRenderPass->isCompatible(*buffer->fActiveRenderPass));
+
+ GR_VK_CALL(gpu->vkInterface(), CmdExecuteCommands(fCmdBuffer, 1, &buffer->fCmdBuffer));
+ this->addResource(buffer);
+}
+
+void GrVkPrimaryCommandBuffer::submitToQueue(const GrVkGpu* gpu,
+ VkQueue queue,
+ GrVkGpu::SyncQueue sync) {
+ SkASSERT(!fIsActive);
+
+ VkResult err;
+ VkFenceCreateInfo fenceInfo;
+ memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
+ fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ err = GR_VK_CALL(gpu->vkInterface(), CreateFence(gpu->device(), &fenceInfo, nullptr,
+ &fSubmitFence));
+ SkASSERT(!err);
+
+ VkSubmitInfo submitInfo;
+ memset(&submitInfo, 0, sizeof(VkSubmitInfo));
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = 0;
+ submitInfo.pWaitSemaphores = nullptr;
+ submitInfo.pWaitDstStageMask = 0;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &fCmdBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), QueueSubmit(queue, 1, &submitInfo, fSubmitFence));
+
+ if (GrVkGpu::kForce_SyncQueue == sync) {
+ err = GR_VK_CALL(gpu->vkInterface(),
+ WaitForFences(gpu->device(), 1, &fSubmitFence, true, UINT64_MAX));
+ if (VK_TIMEOUT == err) {
+ SkDebugf("Fence failed to signal: %d\n", err);
+ SkFAIL("failing");
+ }
+ SkASSERT(!err);
+
+ // Destroy the fence
+ GR_VK_CALL(gpu->vkInterface(), DestroyFence(gpu->device(), fSubmitFence, nullptr));
+ fSubmitFence = VK_NULL_HANDLE;
+ }
+}
+
+bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) const {
+ if (VK_NULL_HANDLE == fSubmitFence) {
+ return true;
+ }
+
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), GetFenceStatus(gpu->device(), fSubmitFence));
+ switch (err) {
+ case VK_SUCCESS:
+ return true;
+
+ case VK_NOT_READY:
+ return false;
+
+ default:
+ SkDebugf("Error getting fence status: %d\n", err);
+ SkFAIL("failing");
+ break;
+ }
+
+ return false;
+}
+
+void GrVkPrimaryCommandBuffer::copyImage(const GrVkGpu* gpu,
+ GrVkImage* srcImage,
+ VkImageLayout srcLayout,
+ GrVkImage* dstImage,
+ VkImageLayout dstLayout,
+ uint32_t copyRegionCount,
+ const VkImageCopy* copyRegions) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(srcImage->resource());
+ this->addResource(dstImage->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdCopyImage(fCmdBuffer,
+ srcImage->image(),
+ srcLayout,
+ dstImage->image(),
+ dstLayout,
+ copyRegionCount,
+ copyRegions));
+}
+
+void GrVkPrimaryCommandBuffer::blitImage(const GrVkGpu* gpu,
+ const GrVkResource* srcResource,
+ VkImage srcImage,
+ VkImageLayout srcLayout,
+ const GrVkResource* dstResource,
+ VkImage dstImage,
+ VkImageLayout dstLayout,
+ uint32_t blitRegionCount,
+ const VkImageBlit* blitRegions,
+ VkFilter filter) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(srcResource);
+ this->addResource(dstResource);
+ GR_VK_CALL(gpu->vkInterface(), CmdBlitImage(fCmdBuffer,
+ srcImage,
+ srcLayout,
+ dstImage,
+ dstLayout,
+ blitRegionCount,
+ blitRegions,
+ filter));
+}
+
+void GrVkPrimaryCommandBuffer::copyImageToBuffer(const GrVkGpu* gpu,
+ GrVkImage* srcImage,
+ VkImageLayout srcLayout,
+ GrVkTransferBuffer* dstBuffer,
+ uint32_t copyRegionCount,
+ const VkBufferImageCopy* copyRegions) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(srcImage->resource());
+ this->addResource(dstBuffer->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdCopyImageToBuffer(fCmdBuffer,
+ srcImage->image(),
+ srcLayout,
+ dstBuffer->buffer(),
+ copyRegionCount,
+ copyRegions));
+}
+
+void GrVkPrimaryCommandBuffer::copyBufferToImage(const GrVkGpu* gpu,
+ GrVkTransferBuffer* srcBuffer,
+ GrVkImage* dstImage,
+ VkImageLayout dstLayout,
+ uint32_t copyRegionCount,
+ const VkBufferImageCopy* copyRegions) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(srcBuffer->resource());
+ this->addResource(dstImage->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdCopyBufferToImage(fCmdBuffer,
+ srcBuffer->buffer(),
+ dstImage->image(),
+ dstLayout,
+ copyRegionCount,
+ copyRegions));
+}
+
+void GrVkPrimaryCommandBuffer::clearColorImage(const GrVkGpu* gpu,
+ GrVkImage* image,
+ const VkClearColorValue* color,
+ uint32_t subRangeCount,
+ const VkImageSubresourceRange* subRanges) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(image->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdClearColorImage(fCmdBuffer,
+ image->image(),
+ image->currentLayout(),
+ color,
+ subRangeCount,
+ subRanges));
+}
+
+void GrVkPrimaryCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu,
+ GrVkImage* image,
+ const VkClearDepthStencilValue* color,
+ uint32_t subRangeCount,
+ const VkImageSubresourceRange* subRanges) {
+ SkASSERT(fIsActive);
+ SkASSERT(!fActiveRenderPass);
+ this->addResource(image->resource());
+ GR_VK_CALL(gpu->vkInterface(), CmdClearDepthStencilImage(fCmdBuffer,
+ image->image(),
+ image->currentLayout(),
+ color,
+ subRangeCount,
+ subRanges));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SecondaryCommandBuffer
+////////////////////////////////////////////////////////////////////////////////
+
+GrVkSecondaryCommandBuffer* GrVkSecondaryCommandBuffer::Create(
+ const GrVkGpu* gpu,
+ VkCommandPool cmdPool,
+ const GrVkRenderPass* compatibleRenderPass) {
+ const VkCommandBufferAllocateInfo cmdInfo = {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // sType
+ NULL, // pNext
+ cmdPool, // commandPool
+ VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
+ 1 // bufferCount
+ };
+
+ VkCommandBuffer cmdBuffer;
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateCommandBuffers(gpu->device(),
+ &cmdInfo,
+ &cmdBuffer));
+ if (err) {
+ return nullptr;
+ }
+ return new GrVkSecondaryCommandBuffer(cmdBuffer, compatibleRenderPass);
+}
+
+
+void GrVkSecondaryCommandBuffer::begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer) {
+ SkASSERT(!fIsActive);
+ SkASSERT(fActiveRenderPass);
+
+ VkCommandBufferInheritanceInfo inheritanceInfo;
+ memset(&inheritanceInfo, 0, sizeof(VkCommandBufferInheritanceInfo));
+ inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+ inheritanceInfo.pNext = nullptr;
+ inheritanceInfo.renderPass = fActiveRenderPass->vkRenderPass();
+ inheritanceInfo.subpass = 0; // Currently only using 1 subpass for each render pass
+ inheritanceInfo.framebuffer = framebuffer ? framebuffer->framebuffer() : VK_NULL_HANDLE;
+ inheritanceInfo.occlusionQueryEnable = false;
+ inheritanceInfo.queryFlags = 0;
+ inheritanceInfo.pipelineStatistics = 0;
+
+ VkCommandBufferBeginInfo cmdBufferBeginInfo;
+ memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
+ cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cmdBufferBeginInfo.pNext = nullptr;
+ cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT |
+ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cmdBufferBeginInfo.pInheritanceInfo = &inheritanceInfo;
+
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), BeginCommandBuffer(fCmdBuffer,
+ &cmdBufferBeginInfo));
+ fIsActive = true;
+}
+
+void GrVkSecondaryCommandBuffer::end(const GrVkGpu* gpu) {
+ SkASSERT(fIsActive);
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), EndCommandBuffer(fCmdBuffer));
+ this->invalidateState();
+ fIsActive = false;
+}
+
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index b513a47..709e4c6 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -13,6 +13,7 @@
#include "GrVkUtil.h"
#include "vk/GrVkDefines.h"
+class GrVkFramebuffer;
class GrVkPipeline;
class GrVkRenderPass;
class GrVkRenderTarget;
@@ -20,24 +21,10 @@
class GrVkCommandBuffer : public GrVkResource {
public:
- static GrVkCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool);
~GrVkCommandBuffer() override;
- void begin(const GrVkGpu* gpu);
- void end(const GrVkGpu* gpu);
-
void invalidateState();
- // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
- // in the render pass.
- void beginRenderPass(const GrVkGpu* gpu,
- const GrVkRenderPass* renderPass,
- const GrVkRenderTarget& target);
- void endRenderPass(const GrVkGpu* gpu);
-
- void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync);
- bool finished(const GrVkGpu* gpu) const;
-
////////////////////////////////////////////////////////////////////////////
// CommandBuffer commands
////////////////////////////////////////////////////////////////////////////
@@ -105,6 +92,98 @@
void setBlendConstants(const GrVkGpu* gpu, const float blendConstants[4]);
+ // Commands that only work inside of a render pass
+ void clearAttachments(const GrVkGpu* gpu,
+ int numAttachments,
+ const VkClearAttachment* attachments,
+ int numRects,
+ const VkClearRect* clearRects) const;
+
+ void drawIndexed(const GrVkGpu* gpu,
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance) const;
+
+ void draw(const GrVkGpu* gpu,
+ uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance) const;
+
+ // Add ref-counted resource that will be tracked and released when this
+ // command buffer finishes execution
+ void addResource(const GrVkResource* resource) {
+ resource->ref();
+ fTrackedResources.push_back(resource);
+ }
+
+protected:
+ GrVkCommandBuffer(VkCommandBuffer cmdBuffer, const GrVkRenderPass* rp = VK_NULL_HANDLE)
+ : fTrackedResources(kInitialTrackedResourcesCount)
+ , fIsActive(false)
+ , fActiveRenderPass(rp)
+ , fCmdBuffer(cmdBuffer)
+ , fSubmitFence(VK_NULL_HANDLE)
+ , fBoundVertexBufferIsValid(false)
+ , fBoundIndexBufferIsValid(false) {
+ this->invalidateState();
+ }
+ SkTArray<const GrVkResource*, true> fTrackedResources;
+
+ // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add
+ // new commands to the buffer;
+ bool fIsActive;
+
+ // Stores a pointer to the current active render pass (i.e. begin has been called but not
+ // end). A nullptr means there is no active render pass. The GrVKCommandBuffer does not own
+ // the render pass.
+ const GrVkRenderPass* fActiveRenderPass;
+
+ VkCommandBuffer fCmdBuffer;
+ VkFence fSubmitFence;
+
+private:
+ static const int kInitialTrackedResourcesCount = 32;
+
+ void freeGPUData(const GrVkGpu* gpu) const override;
+ void abandonSubResources() const override;
+
+ VkBuffer fBoundVertexBuffer;
+ bool fBoundVertexBufferIsValid;
+
+ VkBuffer fBoundIndexBuffer;
+ bool fBoundIndexBufferIsValid;
+
+ // Cached values used for dynamic state updates
+ VkViewport fCachedViewport;
+ VkRect2D fCachedScissor;
+ float fCachedBlendConstant[4];
+};
+
+class GrVkSecondaryCommandBuffer;
+
+class GrVkPrimaryCommandBuffer : public GrVkCommandBuffer {
+public:
+ static GrVkPrimaryCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool);
+
+ void begin(const GrVkGpu* gpu);
+ void end(const GrVkGpu* gpu);
+
+ // Begins render pass on this command buffer. The framebuffer from GrVkRenderTarget will be used
+ // in the render pass.
+ void beginRenderPass(const GrVkGpu* gpu,
+ const GrVkRenderPass* renderPass,
+ const GrVkRenderTarget& target);
+ void endRenderPass(const GrVkGpu* gpu);
+
+ // Submits the SecondaryCommandBuffer into this command buffer. It is required that we are
+ // currently inside a render pass that is compatible with the one used to create the
+ // SecondaryCommandBuffer.
+ void executeCommands(const GrVkGpu* gpu,
+ const GrVkSecondaryCommandBuffer* secondaryBuffer);
+
// Commands that only work outside of a render pass
void clearColorImage(const GrVkGpu* gpu,
GrVkImage* image,
@@ -169,75 +248,32 @@
uint32_t copyRegionCount,
const VkBufferImageCopy* copyRegions);
- // Commands that only work inside of a render pass
- void clearAttachments(const GrVkGpu* gpu,
- int numAttachments,
- const VkClearAttachment* attachments,
- int numRects,
- const VkClearRect* clearRects) const;
-
- void drawIndexed(const GrVkGpu* gpu,
- uint32_t indexCount,
- uint32_t instanceCount,
- uint32_t firstIndex,
- int32_t vertexOffset,
- uint32_t firstInstance) const;
-
- void draw(const GrVkGpu* gpu,
- uint32_t vertexCount,
- uint32_t instanceCount,
- uint32_t firstVertex,
- uint32_t firstInstance) const;
-
- // Add ref-counted resource that will be tracked and released when this
- // command buffer finishes execution
- void addResource(const GrVkResource* resource) {
- resource->ref();
- fTrackedResources.push_back(resource);
- }
+ void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync);
+ bool finished(const GrVkGpu* gpu) const;
private:
- static const int kInitialTrackedResourcesCount = 32;
+ explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer) : INHERITED(cmdBuffer) {}
- explicit GrVkCommandBuffer(VkCommandBuffer cmdBuffer)
- : fTrackedResources(kInitialTrackedResourcesCount)
- , fCmdBuffer(cmdBuffer)
- , fSubmitFence(VK_NULL_HANDLE)
- , fBoundVertexBufferIsValid(false)
- , fBoundIndexBufferIsValid(false)
- , fIsActive(false)
- , fActiveRenderPass(nullptr) {
- this->invalidateState();
- }
-
- void freeGPUData(const GrVkGpu* gpu) const override;
- void abandonSubResources() const override;
-
- SkTArray<const GrVkResource*, true> fTrackedResources;
-
- VkCommandBuffer fCmdBuffer;
- VkFence fSubmitFence;
-
- VkBuffer fBoundVertexBuffer;
- bool fBoundVertexBufferIsValid;
-
- VkBuffer fBoundIndexBuffer;
- bool fBoundIndexBufferIsValid;
-
- // Tracks whether we are in the middle of a command buffer begin/end calls and thus can add new
- // commands to the buffer;
- bool fIsActive;
-
- // Stores a pointer to the current active render pass (i.e. begin has been called but not end).
- // A nullptr means there is no active render pass. The GrVKCommandBuffer does not own the render
- // pass.
- const GrVkRenderPass* fActiveRenderPass;
-
- // Cached values used for dynamic state updates
- VkViewport fCachedViewport;
- VkRect2D fCachedScissor;
- float fCachedBlendConstant[4];
+ typedef GrVkCommandBuffer INHERITED;
};
+class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
+public:
+ static GrVkSecondaryCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool,
+ const GrVkRenderPass* compatibleRenderPass);
+
+ void begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer);
+ void end(const GrVkGpu* gpu);
+
+private:
+ explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer,
+ const GrVkRenderPass* compatibleRenderPass)
+ : INHERITED(cmdBuffer, compatibleRenderPass) {
+ }
+
+ friend class GrVkPrimaryCommandBuffer;
+
+ typedef GrVkCommandBuffer INHERITED;
+};
#endif
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index fb533e3..d18481c 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -128,7 +128,7 @@
// must call this after creating the CommandPool
fResourceProvider.init();
- fCurrentCmdBuffer = fResourceProvider.createCommandBuffer();
+ fCurrentCmdBuffer = fResourceProvider.createPrimaryCommandBuffer();
SkASSERT(fCurrentCmdBuffer);
fCurrentCmdBuffer->begin(this);
}
@@ -169,7 +169,7 @@
// Release old command buffer and create a new one
fCurrentCmdBuffer->unref(this);
- fCurrentCmdBuffer = fResourceProvider.createCommandBuffer();
+ fCurrentCmdBuffer = fResourceProvider.createPrimaryCommandBuffer();
SkASSERT(fCurrentCmdBuffer);
fCurrentCmdBuffer->begin(this);
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 506b237..00055ad 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -214,7 +214,7 @@
// Created by GrVkGpu
GrVkResourceProvider fResourceProvider;
VkCommandPool fCmdPool;
- GrVkCommandBuffer* fCurrentCmdBuffer;
+ GrVkPrimaryCommandBuffer* fCurrentCmdBuffer;
VkPhysicalDeviceMemoryProperties fPhysDevMemProps;
#ifdef ENABLE_VK_LAYERS
diff --git a/src/gpu/vk/GrVkRenderPass.cpp b/src/gpu/vk/GrVkRenderPass.cpp
index 6a0f953..a493938 100644
--- a/src/gpu/vk/GrVkRenderPass.cpp
+++ b/src/gpu/vk/GrVkRenderPass.cpp
@@ -233,11 +233,8 @@
*contents = VK_SUBPASS_CONTENTS_INLINE;
}
-bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
- AttachmentsDescriptor desc;
- AttachmentFlags flags;
- target.getAttachmentsDescriptor(&desc, &flags);
-
+bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
+ const AttachmentFlags& flags) const {
if (flags != fAttachmentFlags) {
return false;
}
@@ -261,6 +258,18 @@
return true;
}
+bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
+ AttachmentsDescriptor desc;
+ AttachmentFlags flags;
+ target.getAttachmentsDescriptor(&desc, &flags);
+
+ return this->isCompatible(desc, flags);
+}
+
+bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
+ return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags);
+}
+
bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
const LoadStoreOps& resolveOps,
const LoadStoreOps& stencilOps) const {
diff --git a/src/gpu/vk/GrVkRenderPass.h b/src/gpu/vk/GrVkRenderPass.h
index b4f4b2b..997989d 100644
--- a/src/gpu/vk/GrVkRenderPass.h
+++ b/src/gpu/vk/GrVkRenderPass.h
@@ -110,6 +110,8 @@
// basic RenderPasses that can be used when creating a VkFrameBuffer object.
bool isCompatible(const GrVkRenderTarget& target) const;
+ bool isCompatible(const GrVkRenderPass& renderPass) const;
+
bool equalLoadStoreOps(const LoadStoreOps& colorOps,
const LoadStoreOps& resolveOps,
const LoadStoreOps& stencilOps) const;
@@ -126,6 +128,8 @@
const LoadStoreOps& resolveOps,
const LoadStoreOps& stencilOps);
+ bool isCompatible(const AttachmentsDescriptor&, const AttachmentFlags&) const;
+
void freeGPUData(const GrVkGpu* gpu) const override;
VkRenderPass fRenderPass;
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index cd3ba47..ae333bc 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -215,8 +215,8 @@
*outPool = fUniformDescPool;
}
-GrVkCommandBuffer* GrVkResourceProvider::createCommandBuffer() {
- GrVkCommandBuffer* cmdBuffer = GrVkCommandBuffer::Create(fGpu, fGpu->cmdPool());
+GrVkPrimaryCommandBuffer* GrVkResourceProvider::createPrimaryCommandBuffer() {
+ GrVkPrimaryCommandBuffer* cmdBuffer = GrVkPrimaryCommandBuffer::Create(fGpu, fGpu->cmdPool());
fActiveCommandBuffers.push_back(cmdBuffer);
cmdBuffer->ref();
return cmdBuffer;
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index e754501..d4383af 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -25,7 +25,7 @@
class GrPipeline;
class GrPrimitiveProcessor;
class GrTextureParams;
-class GrVkCommandBuffer;
+class GrVkPrimaryCommandBuffer;
class GrVkGpu;
class GrVkPipeline;
class GrVkRenderTarget;
@@ -77,7 +77,7 @@
const GrVkRenderPass::LoadStoreOps& stencilOps);
- GrVkCommandBuffer* createCommandBuffer();
+ GrVkPrimaryCommandBuffer* createPrimaryCommandBuffer();
void checkCommandBuffers();
// Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
@@ -201,7 +201,7 @@
SkSTArray<4, CompatibleRenderPassSet> fRenderPassArray;
// Array of CommandBuffers that are currently in flight
- SkSTArray<4, GrVkCommandBuffer*> fActiveCommandBuffers;
+ SkSTArray<4, GrVkPrimaryCommandBuffer*> fActiveCommandBuffers;
// Stores GrVkSampler objects that we've already created so we can reuse them across multiple
// GrVkPipelineStates