Index: src/gpu/vk/GrVkRenderPass.cpp |
diff --git a/src/gpu/vk/GrVkRenderPass.cpp b/src/gpu/vk/GrVkRenderPass.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9c4787b865cb3bce8ef6e271e37bfd5d9931357d |
--- /dev/null |
+++ b/src/gpu/vk/GrVkRenderPass.cpp |
@@ -0,0 +1,220 @@ |
+/* |
+* Copyright 2015 Google Inc. |
+* |
+* Use of this source code is governed by a BSD-style license that can be |
+* found in the LICENSE file. |
+*/ |
+ |
+#include "GrVkRenderPass.h" |
+ |
+#include "GrVkFramebuffer.h" |
+#include "GrVkGpu.h" |
+#include "GrVkRenderTarget.h" |
+#include "GrVkUtil.h" |
+ |
+void setup_simple_vk_attachment_description(VkAttachmentDescription* attachment, |
+ VkFormat format, |
+ uint32_t samples, |
+ VkImageLayout layout) { |
+ attachment->flags = 0; |
+ attachment->format = format; |
+ SkAssertResult(GrSampleCountToVkSampleCount(samples, &attachment->samples)); |
+ attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
+ attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
+ attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; |
+ attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE; |
+ attachment->initialLayout = layout; |
+ attachment->finalLayout = layout; |
+} |
+ |
+void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) { |
+ // Get attachment information from render target. This includes which attachments the render |
+ // target has (color, resolve, stencil) and the attachments format and sample count. |
+ target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags); |
+ |
+ uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount; |
+ // Attachment descriptions to be set on the render pass |
+ SkTArray<VkAttachmentDescription> attachments(numAttachments); |
+ attachments.reset(numAttachments); |
+ memset(attachments.begin(), 0, numAttachments*sizeof(VkAttachmentDescription)); |
+ |
+ // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above), |
+ // that are used by the subpass. |
+ VkAttachmentReference colorRef; |
+ VkAttachmentReference resolveRef; |
+ VkAttachmentReference stencilRef; |
+ uint32_t currentAttachment = 0; |
+ |
+ // Go through each of the attachment types (color, resolve, stencil) and set the necessary |
+ // on the various Vk structs. |
+ VkSubpassDescription subpassDesc; |
+ memset(&subpassDesc, 0, sizeof(VkSubpassDescription)); |
+ subpassDesc.flags = 0; |
+ subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; |
+ subpassDesc.inputAttachmentCount = 0; |
+ subpassDesc.pInputAttachments = nullptr; |
+ if (fAttachmentFlags & kColor_AttachmentFlag) { |
+ // set up color attachment |
+ setup_simple_vk_attachment_description(&attachments[currentAttachment], |
+ fAttachmentsDescriptor.fColor.fFormat, |
+ fAttachmentsDescriptor.fColor.fSamples, |
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); |
+ // setup subpass use of attachment |
+ colorRef.attachment = currentAttachment++; |
+ colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
+ subpassDesc.colorAttachmentCount = 1; |
+ } else { |
+ // I don't think there should ever be a time where we don't have a color attachment |
+ SkASSERT(false); |
+ colorRef.attachment = VK_ATTACHMENT_UNUSED; |
+ colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED; |
+ subpassDesc.colorAttachmentCount = 0; |
+ } |
+ subpassDesc.pColorAttachments = &colorRef; |
+ |
+ if (fAttachmentFlags & kResolve_AttachmentFlag) { |
+ // set up resolve attachment |
+ setup_simple_vk_attachment_description(&attachments[currentAttachment], |
+ fAttachmentsDescriptor.fResolve.fFormat, |
+ fAttachmentsDescriptor.fResolve.fSamples, |
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); |
+ // setup subpass use of attachment |
+ resolveRef.attachment = currentAttachment++; |
+ // I'm really not sure what the layout should be for the resolve textures. |
+ resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; |
+ subpassDesc.pResolveAttachments = &resolveRef; |
+ } else { |
+ subpassDesc.pResolveAttachments = nullptr; |
+ } |
+ |
+ if (fAttachmentFlags & kStencil_AttachmentFlag) { |
+ // set up stencil attachment |
+ setup_simple_vk_attachment_description(&attachments[currentAttachment], |
+ fAttachmentsDescriptor.fStencil.fFormat, |
+ fAttachmentsDescriptor.fStencil.fSamples, |
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); |
+ // setup subpass use of attachment |
+ stencilRef.attachment = currentAttachment++; |
+ stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; |
+ } else { |
+ stencilRef.attachment = VK_ATTACHMENT_UNUSED; |
+ stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED; |
+ } |
+ subpassDesc.pDepthStencilAttachment = &stencilRef; |
+ |
+ subpassDesc.preserveAttachmentCount = 0; |
+ subpassDesc.pPreserveAttachments = nullptr; |
+ |
+ SkASSERT(numAttachments == currentAttachment); |
+ |
+ // Create the VkRenderPass compatible with the attachment descriptions above |
+ VkRenderPassCreateInfo createInfo; |
+ memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo)); |
+ createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; |
+ createInfo.pNext = nullptr; |
+ createInfo.flags = 0; |
+ createInfo.attachmentCount = numAttachments; |
+ createInfo.pAttachments = attachments.begin(); |
+ createInfo.subpassCount = 1; |
+ createInfo.pSubpasses = &subpassDesc; |
+ createInfo.dependencyCount = 0; |
+ createInfo.pDependencies = nullptr; |
+ |
+ GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(), |
+ &createInfo, |
+ nullptr, |
+ &fRenderPass)); |
+} |
+ |
+void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const { |
+ GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr)); |
+} |
+ |
+// Works under the assumption that color attachment will always be the first attachment in our |
+// attachment array if it exists. |
+bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const { |
+ *index = 0; |
+ if (fAttachmentFlags & kColor_AttachmentFlag) { |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+// Works under the assumption that resolve attachment will always be after the color attachment. |
+bool GrVkRenderPass::resolveAttachmentIndex(uint32_t* index) const { |
+ *index = 0; |
+ if (fAttachmentFlags & kColor_AttachmentFlag) { |
+ ++(*index); |
+ } |
+ if (fAttachmentFlags & kResolve_AttachmentFlag) { |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+// Works under the assumption that stencil attachment will always be after the color and resolve |
+// attachment. |
+bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const { |
+ *index = 0; |
+ if (fAttachmentFlags & kColor_AttachmentFlag) { |
+ ++(*index); |
+ } |
+ if (fAttachmentFlags & kResolve_AttachmentFlag) { |
+ ++(*index); |
+ } |
+ if (fAttachmentFlags & kStencil_AttachmentFlag) { |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target, |
+ VkRenderPassBeginInfo* beginInfo, |
+ VkSubpassContents* contents) const { |
+ SkASSERT(this->isCompatible(target)); |
+ |
+ VkRect2D renderArea; |
+ renderArea.offset = { 0, 0 }; |
+ renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() }; |
+ |
+ memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo)); |
+ beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; |
+ beginInfo->pNext = nullptr; |
+ beginInfo->renderPass = fRenderPass; |
+ beginInfo->framebuffer = target.framebuffer()->framebuffer(); |
+ beginInfo->renderArea = renderArea; |
+ beginInfo->clearValueCount = 0; |
+ beginInfo->pClearValues = nullptr; |
+ |
+ // Currently just assuming no secondary cmd buffers. This value will need to be update if we |
+ // have them. |
+ *contents = VK_SUBPASS_CONTENTS_INLINE; |
+} |
+ |
+bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const { |
+ AttachmentsDescriptor desc; |
+ AttachmentFlags flags; |
+ target.getAttachmentsDescriptor(&desc, &flags); |
+ |
+ if (flags != fAttachmentFlags) { |
+ return false; |
+ } |
+ |
+ if (fAttachmentFlags & kColor_AttachmentFlag) { |
+ if (fAttachmentsDescriptor.fColor != desc.fColor) { |
+ return false; |
+ } |
+ } |
+ if (fAttachmentFlags & kResolve_AttachmentFlag) { |
+ if (fAttachmentsDescriptor.fResolve != desc.fResolve) { |
+ return false; |
+ } |
+ } |
+ if (fAttachmentFlags & kStencil_AttachmentFlag) { |
+ if (fAttachmentsDescriptor.fStencil != desc.fStencil) { |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
+} |