aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/vk
diff options
context:
space:
mode:
authorGravatar egdaniel <egdaniel@google.com>2016-06-08 08:22:05 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-08 08:22:06 -0700
commit9a6cf800bc392fb4ba5065efb64f5b0320098d1a (patch)
treee4fb702b9ae4b7772ec2277db1cf805498497f44 /src/gpu/vk
parent2feb0938dcf223da3641daf15f5d525db88a6967 (diff)
Subclass GrVkCommandBuffer into Primary and Secondary CommandBuffers.
Diffstat (limited to 'src/gpu/vk')
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp534
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h186
-rw-r--r--src/gpu/vk/GrVkGpu.cpp4
-rw-r--r--src/gpu/vk/GrVkGpu.h2
-rw-r--r--src/gpu/vk/GrVkRenderPass.cpp19
-rw-r--r--src/gpu/vk/GrVkRenderPass.h4
-rw-r--r--src/gpu/vk/GrVkResourceProvider.cpp4
-rw-r--r--src/gpu/vk/GrVkResourceProvider.h6
8 files changed, 443 insertions, 316 deletions
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index bc8c20f016..9604355aad 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,7 +61,206 @@ void GrVkCommandBuffer::abandonSubResources() const {
}
}
-void GrVkCommandBuffer::begin(const GrVkGpu* gpu) {
+////////////////////////////////////////////////////////////////////////////////
+// CommandBuffer commands
+////////////////////////////////////////////////////////////////////////////////
+
+void GrVkCommandBuffer::pipelineBarrier(const GrVkGpu* gpu,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags dstStageMask,
+ bool byRegion,
+ BarrierType barrierType,
+ void* barrier) const {
+ SkASSERT(fIsActive);
+ // For images we can have barriers inside of render passes but they require us to add more
+ // support in subpasses which need self dependencies to have barriers inside them. Also, we can
+ // never have buffer barriers inside of a render pass. For now we will just assert that we are
+ // not in a render pass.
+ SkASSERT(!fActiveRenderPass);
+ VkDependencyFlags dependencyFlags = byRegion ? VK_DEPENDENCY_BY_REGION_BIT : 0;
+
+ switch (barrierType) {
+ case kMemory_BarrierType: {
+ const VkMemoryBarrier* barrierPtr = reinterpret_cast<VkMemoryBarrier*>(barrier);
+ GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
+ dstStageMask, dependencyFlags,
+ 1, barrierPtr,
+ 0, nullptr,
+ 0, nullptr));
+ break;
+ }
+
+ case kBufferMemory_BarrierType: {
+ const VkBufferMemoryBarrier* barrierPtr =
+ reinterpret_cast<VkBufferMemoryBarrier*>(barrier);
+ GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
+ dstStageMask, dependencyFlags,
+ 0, nullptr,
+ 1, barrierPtr,
+ 0, nullptr));
+ break;
+ }
+
+ case kImageMemory_BarrierType: {
+ const VkImageMemoryBarrier* barrierPtr =
+ reinterpret_cast<VkImageMemoryBarrier*>(barrier);
+ GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
+ dstStageMask, dependencyFlags,
+ 0, nullptr,
+ 0, nullptr,
+ 1, barrierPtr));
+ break;
+ }
+ }
+
+}
+
+void GrVkCommandBuffer::clearAttachments(const GrVkGpu* gpu,
+ int numAttachments,
+ const VkClearAttachment* attachments,
+ int numRects,
+ const VkClearRect* clearRects) const {
+ SkASSERT(fIsActive);
+ SkASSERT(fActiveRenderPass);
+ SkASSERT(numAttachments > 0);
+ SkASSERT(numRects > 0);
+#ifdef SK_DEBUG
+ for (int i = 0; i < numAttachments; ++i) {
+ if (attachments[i].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
+ uint32_t testIndex;
+ SkAssertResult(fActiveRenderPass->colorAttachmentIndex(&testIndex));
+ SkASSERT(testIndex == attachments[i].colorAttachment);
+ }
+ }
+#endif
+ GR_VK_CALL(gpu->vkInterface(), CmdClearAttachments(fCmdBuffer,
+ numAttachments,
+ attachments,
+ numRects,
+ clearRects));
+}
+
+void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu,
+ GrVkPipelineState* pipelineState,
+ VkPipelineLayout layout,
+ uint32_t firstSet,
+ uint32_t setCount,
+ const VkDescriptorSet* descriptorSets,
+ uint32_t dynamicOffsetCount,
+ const uint32_t* dynamicOffsets) {
+ SkASSERT(fIsActive);
+ GR_VK_CALL(gpu->vkInterface(), CmdBindDescriptorSets(fCmdBuffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ layout,
+ firstSet,
+ setCount,
+ descriptorSets,
+ dynamicOffsetCount,
+ dynamicOffsets));
+ pipelineState->addUniformResources(*this);
+}
+
+void GrVkCommandBuffer::bindPipeline(const GrVkGpu* gpu, const GrVkPipeline* pipeline) {
+ SkASSERT(fIsActive);
+ GR_VK_CALL(gpu->vkInterface(), CmdBindPipeline(fCmdBuffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ pipeline->pipeline()));
+ addResource(pipeline);
+}
+
+void GrVkCommandBuffer::drawIndexed(const GrVkGpu* gpu,
+ uint32_t indexCount,
+ uint32_t instanceCount,
+ uint32_t firstIndex,
+ int32_t vertexOffset,
+ uint32_t firstInstance) const {
+ SkASSERT(fIsActive);
+ SkASSERT(fActiveRenderPass);
+ GR_VK_CALL(gpu->vkInterface(), CmdDrawIndexed(fCmdBuffer,
+ indexCount,
+ instanceCount,
+ firstIndex,
+ vertexOffset,
+ firstInstance));
+}
+
+void GrVkCommandBuffer::draw(const GrVkGpu* gpu,
+ uint32_t vertexCount,
+ uint32_t instanceCount,
+ uint32_t firstVertex,
+ uint32_t firstInstance) const {
+ SkASSERT(fIsActive);
+ SkASSERT(fActiveRenderPass);
+ GR_VK_CALL(gpu->vkInterface(), CmdDraw(fCmdBuffer,
+ vertexCount,
+ instanceCount,
+ firstVertex,
+ firstInstance));
+}
+
+void GrVkCommandBuffer::setViewport(const GrVkGpu* gpu,
+ uint32_t firstViewport,
+ uint32_t viewportCount,
+ const VkViewport* viewports) {
+ SkASSERT(fIsActive);
+ SkASSERT(1 == viewportCount);
+ if (memcmp(viewports, &fCachedViewport, sizeof(VkViewport))) {
+ GR_VK_CALL(gpu->vkInterface(), CmdSetViewport(fCmdBuffer,
+ firstViewport,
+ viewportCount,
+ viewports));
+ fCachedViewport = viewports[0];
+ }
+}
+
+void GrVkCommandBuffer::setScissor(const GrVkGpu* gpu,
+ uint32_t firstScissor,
+ uint32_t scissorCount,
+ const VkRect2D* scissors) {
+ SkASSERT(fIsActive);
+ SkASSERT(1 == scissorCount);
+ if (memcmp(scissors, &fCachedScissor, sizeof(VkRect2D))) {
+ GR_VK_CALL(gpu->vkInterface(), CmdSetScissor(fCmdBuffer,
+ firstScissor,
+ scissorCount,
+ scissors));
+ fCachedScissor = scissors[0];
+ }
+}
+
+void GrVkCommandBuffer::setBlendConstants(const GrVkGpu* gpu,
+ const float blendConstants[4]) {
+ SkASSERT(fIsActive);
+ if (memcmp(blendConstants, fCachedBlendConstant, 4 * sizeof(float))) {
+ GR_VK_CALL(gpu->vkInterface(), CmdSetBlendConstants(fCmdBuffer, blendConstants));
+ 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));
@@ -93,7 +274,7 @@ void GrVkCommandBuffer::begin(const GrVkGpu* gpu) {
fIsActive = true;
}
-void GrVkCommandBuffer::end(const GrVkGpu* gpu) {
+void GrVkPrimaryCommandBuffer::end(const GrVkGpu* gpu) {
SkASSERT(fIsActive);
SkASSERT(!fActiveRenderPass);
GR_VK_CALL_ERRCHECK(gpu->vkInterface(), EndCommandBuffer(fCmdBuffer));
@@ -101,9 +282,7 @@ void GrVkCommandBuffer::end(const GrVkGpu* gpu) {
fIsActive = false;
}
-///////////////////////////////////////////////////////////////////////////////
-
-void GrVkCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
+void GrVkPrimaryCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
const GrVkRenderPass* renderPass,
const GrVkRenderTarget& target) {
SkASSERT(fIsActive);
@@ -117,14 +296,26 @@ void GrVkCommandBuffer::beginRenderPass(const GrVkGpu* gpu,
target.addResources(*this);
}
-void GrVkCommandBuffer::endRenderPass(const GrVkGpu* gpu) {
+void GrVkPrimaryCommandBuffer::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) {
+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;
@@ -163,7 +354,7 @@ void GrVkCommandBuffer::submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu
}
}
-bool GrVkCommandBuffer::finished(const GrVkGpu* gpu) const {
+bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) const {
if (VK_NULL_HANDLE == fSubmitFence) {
return true;
}
@@ -185,67 +376,13 @@ bool GrVkCommandBuffer::finished(const GrVkGpu* gpu) const {
return false;
}
-////////////////////////////////////////////////////////////////////////////////
-// CommandBuffer commands
-////////////////////////////////////////////////////////////////////////////////
-
-void GrVkCommandBuffer::pipelineBarrier(const GrVkGpu* gpu,
- VkPipelineStageFlags srcStageMask,
- VkPipelineStageFlags dstStageMask,
- bool byRegion,
- BarrierType barrierType,
- void* barrier) const {
- SkASSERT(fIsActive);
- // For images we can have barriers inside of render passes but they require us to add more
- // support in subpasses which need self dependencies to have barriers inside them. Also, we can
- // never have buffer barriers inside of a render pass. For now we will just assert that we are
- // not in a render pass.
- SkASSERT(!fActiveRenderPass);
- VkDependencyFlags dependencyFlags = byRegion ? VK_DEPENDENCY_BY_REGION_BIT : 0;
-
- switch (barrierType) {
- case kMemory_BarrierType: {
- const VkMemoryBarrier* barrierPtr = reinterpret_cast<VkMemoryBarrier*>(barrier);
- GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
- dstStageMask, dependencyFlags,
- 1, barrierPtr,
- 0, nullptr,
- 0, nullptr));
- break;
- }
-
- case kBufferMemory_BarrierType: {
- const VkBufferMemoryBarrier* barrierPtr =
- reinterpret_cast<VkBufferMemoryBarrier*>(barrier);
- GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
- dstStageMask, dependencyFlags,
- 0, nullptr,
- 1, barrierPtr,
- 0, nullptr));
- break;
- }
-
- case kImageMemory_BarrierType: {
- const VkImageMemoryBarrier* barrierPtr =
- reinterpret_cast<VkImageMemoryBarrier*>(barrier);
- GR_VK_CALL(gpu->vkInterface(), CmdPipelineBarrier(fCmdBuffer, srcStageMask,
- dstStageMask, dependencyFlags,
- 0, nullptr,
- 0, nullptr,
- 1, barrierPtr));
- break;
- }
- }
-
-}
-
-void GrVkCommandBuffer::copyImage(const GrVkGpu* gpu,
- GrVkImage* srcImage,
- VkImageLayout srcLayout,
- GrVkImage* dstImage,
- VkImageLayout dstLayout,
- uint32_t copyRegionCount,
- const VkImageCopy* copyRegions) {
+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());
@@ -259,16 +396,16 @@ void GrVkCommandBuffer::copyImage(const GrVkGpu* gpu,
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) {
+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);
@@ -283,12 +420,12 @@ void GrVkCommandBuffer::blitImage(const GrVkGpu* gpu,
filter));
}
-void GrVkCommandBuffer::copyImageToBuffer(const GrVkGpu* gpu,
- GrVkImage* srcImage,
- VkImageLayout srcLayout,
- GrVkTransferBuffer* dstBuffer,
- uint32_t copyRegionCount,
- const VkBufferImageCopy* copyRegions) {
+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());
@@ -301,12 +438,12 @@ void GrVkCommandBuffer::copyImageToBuffer(const GrVkGpu* gpu,
copyRegions));
}
-void GrVkCommandBuffer::copyBufferToImage(const GrVkGpu* gpu,
- GrVkTransferBuffer* srcBuffer,
- GrVkImage* dstImage,
- VkImageLayout dstLayout,
- uint32_t copyRegionCount,
- const VkBufferImageCopy* 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());
@@ -319,11 +456,11 @@ void GrVkCommandBuffer::copyBufferToImage(const GrVkGpu* gpu,
copyRegions));
}
-void GrVkCommandBuffer::clearColorImage(const GrVkGpu* gpu,
- GrVkImage* image,
- const VkClearColorValue* color,
- uint32_t subRangeCount,
- const VkImageSubresourceRange* subRanges) {
+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());
@@ -335,11 +472,11 @@ void GrVkCommandBuffer::clearColorImage(const GrVkGpu* gpu,
subRanges));
}
-void GrVkCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu,
- GrVkImage* image,
- const VkClearDepthStencilValue* color,
- uint32_t subRangeCount,
- const VkImageSubresourceRange* 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());
@@ -351,124 +488,65 @@ void GrVkCommandBuffer::clearDepthStencilImage(const GrVkGpu* gpu,
subRanges));
}
-void GrVkCommandBuffer::clearAttachments(const GrVkGpu* gpu,
- int numAttachments,
- const VkClearAttachment* attachments,
- int numRects,
- const VkClearRect* clearRects) const {
- SkASSERT(fIsActive);
- SkASSERT(fActiveRenderPass);
- SkASSERT(numAttachments > 0);
- SkASSERT(numRects > 0);
-#ifdef SK_DEBUG
- for (int i = 0; i < numAttachments; ++i) {
- if (attachments[i].aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
- uint32_t testIndex;
- SkAssertResult(fActiveRenderPass->colorAttachmentIndex(&testIndex));
- SkASSERT(testIndex == attachments[i].colorAttachment);
- }
- }
-#endif
- GR_VK_CALL(gpu->vkInterface(), CmdClearAttachments(fCmdBuffer,
- numAttachments,
- attachments,
- numRects,
- clearRects));
-}
+///////////////////////////////////////////////////////////////////////////////
+// SecondaryCommandBuffer
+////////////////////////////////////////////////////////////////////////////////
-void GrVkCommandBuffer::bindDescriptorSets(const GrVkGpu* gpu,
- GrVkPipelineState* pipelineState,
- VkPipelineLayout layout,
- uint32_t firstSet,
- uint32_t setCount,
- const VkDescriptorSet* descriptorSets,
- uint32_t dynamicOffsetCount,
- const uint32_t* dynamicOffsets) {
- SkASSERT(fIsActive);
- GR_VK_CALL(gpu->vkInterface(), CmdBindDescriptorSets(fCmdBuffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS,
- layout,
- firstSet,
- setCount,
- descriptorSets,
- dynamicOffsetCount,
- dynamicOffsets));
- pipelineState->addUniformResources(*this);
-}
+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
+ };
-void GrVkCommandBuffer::bindPipeline(const GrVkGpu* gpu, const GrVkPipeline* pipeline) {
- SkASSERT(fIsActive);
- GR_VK_CALL(gpu->vkInterface(), CmdBindPipeline(fCmdBuffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS,
- pipeline->pipeline()));
- addResource(pipeline);
+ VkCommandBuffer cmdBuffer;
+ VkResult err = GR_VK_CALL(gpu->vkInterface(), AllocateCommandBuffers(gpu->device(),
+ &cmdInfo,
+ &cmdBuffer));
+ if (err) {
+ return nullptr;
+ }
+ return new GrVkSecondaryCommandBuffer(cmdBuffer, compatibleRenderPass);
}
-void GrVkCommandBuffer::drawIndexed(const GrVkGpu* gpu,
- uint32_t indexCount,
- uint32_t instanceCount,
- uint32_t firstIndex,
- int32_t vertexOffset,
- uint32_t firstInstance) const {
- SkASSERT(fIsActive);
- SkASSERT(fActiveRenderPass);
- GR_VK_CALL(gpu->vkInterface(), CmdDrawIndexed(fCmdBuffer,
- indexCount,
- instanceCount,
- firstIndex,
- vertexOffset,
- firstInstance));
-}
-void GrVkCommandBuffer::draw(const GrVkGpu* gpu,
- uint32_t vertexCount,
- uint32_t instanceCount,
- uint32_t firstVertex,
- uint32_t firstInstance) const {
- SkASSERT(fIsActive);
+void GrVkSecondaryCommandBuffer::begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer) {
+ SkASSERT(!fIsActive);
SkASSERT(fActiveRenderPass);
- GR_VK_CALL(gpu->vkInterface(), CmdDraw(fCmdBuffer,
- vertexCount,
- instanceCount,
- firstVertex,
- firstInstance));
-}
-void GrVkCommandBuffer::setViewport(const GrVkGpu* gpu,
- uint32_t firstViewport,
- uint32_t viewportCount,
- const VkViewport* viewports) {
- SkASSERT(fIsActive);
- SkASSERT(1 == viewportCount);
- if (memcmp(viewports, &fCachedViewport, sizeof(VkViewport))) {
- GR_VK_CALL(gpu->vkInterface(), CmdSetViewport(fCmdBuffer,
- firstViewport,
- viewportCount,
- viewports));
- fCachedViewport = viewports[0];
- }
-}
+ 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;
-void GrVkCommandBuffer::setScissor(const GrVkGpu* gpu,
- uint32_t firstScissor,
- uint32_t scissorCount,
- const VkRect2D* scissors) {
- SkASSERT(fIsActive);
- SkASSERT(1 == scissorCount);
- if (memcmp(scissors, &fCachedScissor, sizeof(VkRect2D))) {
- GR_VK_CALL(gpu->vkInterface(), CmdSetScissor(fCmdBuffer,
- firstScissor,
- scissorCount,
- scissors));
- fCachedScissor = scissors[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 GrVkCommandBuffer::setBlendConstants(const GrVkGpu* gpu,
- const float blendConstants[4]) {
+void GrVkSecondaryCommandBuffer::end(const GrVkGpu* gpu) {
SkASSERT(fIsActive);
- if (memcmp(blendConstants, fCachedBlendConstant, 4 * sizeof(float))) {
- GR_VK_CALL(gpu->vkInterface(), CmdSetBlendConstants(fCmdBuffer, blendConstants));
- memcpy(fCachedBlendConstant, blendConstants, 4 * sizeof(float));
- }
+ 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 b513a47f29..709e4c6044 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 GrVkTransferBuffer;
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 @@ public:
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 @@ public:
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 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;
+ explicit GrVkPrimaryCommandBuffer(VkCommandBuffer cmdBuffer) : INHERITED(cmdBuffer) {}
- SkTArray<const GrVkResource*, true> fTrackedResources;
-
- VkCommandBuffer fCmdBuffer;
- VkFence fSubmitFence;
+ typedef GrVkCommandBuffer INHERITED;
+};
- VkBuffer fBoundVertexBuffer;
- bool fBoundVertexBufferIsValid;
+class GrVkSecondaryCommandBuffer : public GrVkCommandBuffer {
+public:
+ static GrVkSecondaryCommandBuffer* Create(const GrVkGpu* gpu, VkCommandPool cmdPool,
+ const GrVkRenderPass* compatibleRenderPass);
- VkBuffer fBoundIndexBuffer;
- bool fBoundIndexBufferIsValid;
+ void begin(const GrVkGpu* gpu, const GrVkFramebuffer* framebuffer);
+ void end(const GrVkGpu* gpu);
- // 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;
+private:
+ explicit GrVkSecondaryCommandBuffer(VkCommandBuffer cmdBuffer,
+ const GrVkRenderPass* compatibleRenderPass)
+ : INHERITED(cmdBuffer, compatibleRenderPass) {
+ }
- // 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;
+ friend class GrVkPrimaryCommandBuffer;
- // Cached values used for dynamic state updates
- VkViewport fCachedViewport;
- VkRect2D fCachedScissor;
- float fCachedBlendConstant[4];
+ typedef GrVkCommandBuffer INHERITED;
};
-
#endif
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index fb533e317e..d18481c08a 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -128,7 +128,7 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
// must call this after creating the CommandPool
fResourceProvider.init();
- fCurrentCmdBuffer = fResourceProvider.createCommandBuffer();
+ fCurrentCmdBuffer = fResourceProvider.createPrimaryCommandBuffer();
SkASSERT(fCurrentCmdBuffer);
fCurrentCmdBuffer->begin(this);
}
@@ -169,7 +169,7 @@ void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
// 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 506b2379f6..00055ad87c 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -214,7 +214,7 @@ private:
// 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 6a0f953a1c..a49393800f 100644
--- a/src/gpu/vk/GrVkRenderPass.cpp
+++ b/src/gpu/vk/GrVkRenderPass.cpp
@@ -233,11 +233,8 @@ void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
*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 @@ bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
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 b4f4b2b2bb..997989d073 100644
--- a/src/gpu/vk/GrVkRenderPass.h
+++ b/src/gpu/vk/GrVkRenderPass.h
@@ -110,6 +110,8 @@ public:
// 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 @@ private:
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 cd3ba47bca..ae333bc69e 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -215,8 +215,8 @@ void GrVkResourceProvider::getUniformDescriptorSet(VkDescriptorSet* ds,
*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 e754501cba..d4383af96a 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 @@ public:
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 @@ private:
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