blob: 7f8b20ad415228e7dee680f7852e93b5777ecfba [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
2* Copyright 2015 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#include "GrVkRenderPass.h"
9
egdaniel22281c12016-03-23 13:49:40 -070010#include "GrProcessor.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050011#include "GrVkFramebuffer.h"
12#include "GrVkGpu.h"
13#include "GrVkRenderTarget.h"
14#include "GrVkUtil.h"
15
egdanield62e28b2016-06-07 08:43:30 -070016typedef GrVkRenderPass::AttachmentsDescriptor::AttachmentDesc AttachmentDesc;
17
18void setup_vk_attachment_description(VkAttachmentDescription* attachment,
19 const AttachmentDesc& desc,
20 VkImageLayout layout) {
Greg Daniel164a9f02016-02-22 09:56:40 -050021 attachment->flags = 0;
egdanield62e28b2016-06-07 08:43:30 -070022 attachment->format = desc.fFormat;
23 SkAssertResult(GrSampleCountToVkSampleCount(desc.fSamples, &attachment->samples));
24 switch (layout) {
25 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
egdaniel2feb0932016-06-08 06:48:09 -070026 attachment->loadOp = desc.fLoadStoreOps.fLoadOp;
27 attachment->storeOp = desc.fLoadStoreOps.fStoreOp;
egdanield62e28b2016-06-07 08:43:30 -070028 attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
29 attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
30 break;
31 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
32 attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
33 attachment->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
egdaniel2feb0932016-06-08 06:48:09 -070034 attachment->stencilLoadOp = desc.fLoadStoreOps.fLoadOp;
35 attachment->stencilStoreOp = desc.fLoadStoreOps.fStoreOp;
egdanield62e28b2016-06-07 08:43:30 -070036 break;
37 default:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040038 SK_ABORT("Unexpected attachment layout");
egdanield62e28b2016-06-07 08:43:30 -070039 }
40
Greg Daniel164a9f02016-02-22 09:56:40 -050041 attachment->initialLayout = layout;
42 attachment->finalLayout = layout;
43}
44
45void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) {
egdaniel2feb0932016-06-08 06:48:09 -070046 static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
47 VK_ATTACHMENT_STORE_OP_STORE);
Greg Daniel164a9f02016-02-22 09:56:40 -050048
egdanielce3bfb12016-08-26 11:05:13 -070049 this->init(gpu, target, kBasicLoadStoreOps, kBasicLoadStoreOps);
egdaniel2feb0932016-06-08 06:48:09 -070050}
51
52void GrVkRenderPass::init(const GrVkGpu* gpu,
53 const LoadStoreOps& colorOp,
egdaniel2feb0932016-06-08 06:48:09 -070054 const LoadStoreOps& stencilOp) {
Greg Daniel164a9f02016-02-22 09:56:40 -050055 uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
56 // Attachment descriptions to be set on the render pass
57 SkTArray<VkAttachmentDescription> attachments(numAttachments);
58 attachments.reset(numAttachments);
egdaniel2feb0932016-06-08 06:48:09 -070059 memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));
Greg Daniel164a9f02016-02-22 09:56:40 -050060
61 // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
62 // that are used by the subpass.
63 VkAttachmentReference colorRef;
Greg Daniel164a9f02016-02-22 09:56:40 -050064 VkAttachmentReference stencilRef;
65 uint32_t currentAttachment = 0;
66
egdanielce3bfb12016-08-26 11:05:13 -070067 // Go through each of the attachment types (color, stencil) and set the necessary
Greg Daniel164a9f02016-02-22 09:56:40 -050068 // on the various Vk structs.
69 VkSubpassDescription subpassDesc;
70 memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
71 subpassDesc.flags = 0;
72 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
73 subpassDesc.inputAttachmentCount = 0;
74 subpassDesc.pInputAttachments = nullptr;
egdanielce3bfb12016-08-26 11:05:13 -070075 subpassDesc.pResolveAttachments = nullptr;
76
Greg Daniel164a9f02016-02-22 09:56:40 -050077 if (fAttachmentFlags & kColor_AttachmentFlag) {
78 // set up color attachment
egdaniel2feb0932016-06-08 06:48:09 -070079 fAttachmentsDescriptor.fColor.fLoadStoreOps = colorOp;
egdanield62e28b2016-06-07 08:43:30 -070080 setup_vk_attachment_description(&attachments[currentAttachment],
81 fAttachmentsDescriptor.fColor,
82 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -050083 // setup subpass use of attachment
84 colorRef.attachment = currentAttachment++;
85 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
86 subpassDesc.colorAttachmentCount = 1;
Greg Daniel77a86f82017-01-23 11:04:45 -050087
88 if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
89 fClearValueCount++;
90 }
Greg Daniel164a9f02016-02-22 09:56:40 -050091 } else {
92 // I don't think there should ever be a time where we don't have a color attachment
93 SkASSERT(false);
94 colorRef.attachment = VK_ATTACHMENT_UNUSED;
95 colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
96 subpassDesc.colorAttachmentCount = 0;
97 }
98 subpassDesc.pColorAttachments = &colorRef;
99
Greg Daniel164a9f02016-02-22 09:56:40 -0500100 if (fAttachmentFlags & kStencil_AttachmentFlag) {
101 // set up stencil attachment
egdaniel2feb0932016-06-08 06:48:09 -0700102 fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
egdanield62e28b2016-06-07 08:43:30 -0700103 setup_vk_attachment_description(&attachments[currentAttachment],
104 fAttachmentsDescriptor.fStencil,
105 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -0500106 // setup subpass use of attachment
107 stencilRef.attachment = currentAttachment++;
108 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
Greg Daniel77a86f82017-01-23 11:04:45 -0500109 if (VK_ATTACHMENT_LOAD_OP_CLEAR == stencilOp.fLoadOp) {
110 fClearValueCount++;
111 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500112 } else {
113 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
114 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
115 }
116 subpassDesc.pDepthStencilAttachment = &stencilRef;
117
118 subpassDesc.preserveAttachmentCount = 0;
119 subpassDesc.pPreserveAttachments = nullptr;
120
121 SkASSERT(numAttachments == currentAttachment);
122
123 // Create the VkRenderPass compatible with the attachment descriptions above
124 VkRenderPassCreateInfo createInfo;
125 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
126 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
127 createInfo.pNext = nullptr;
128 createInfo.flags = 0;
129 createInfo.attachmentCount = numAttachments;
130 createInfo.pAttachments = attachments.begin();
131 createInfo.subpassCount = 1;
132 createInfo.pSubpasses = &subpassDesc;
133 createInfo.dependencyCount = 0;
134 createInfo.pDependencies = nullptr;
135
136 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
137 &createInfo,
138 nullptr,
139 &fRenderPass));
egdaniel27bb2842016-07-07 11:58:35 -0700140
141 // Get granularity for this render pass
142 GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
143 fRenderPass,
144 &fGranularity));
Greg Daniel164a9f02016-02-22 09:56:40 -0500145}
146
egdaniel2feb0932016-06-08 06:48:09 -0700147void GrVkRenderPass::init(const GrVkGpu* gpu,
148 const GrVkRenderPass& compatibleRenderPass,
149 const LoadStoreOps& colorOp,
egdaniel2feb0932016-06-08 06:48:09 -0700150 const LoadStoreOps& stencilOp) {
151 fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
152 fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
egdanielce3bfb12016-08-26 11:05:13 -0700153 this->init(gpu, colorOp, stencilOp);
egdaniel2feb0932016-06-08 06:48:09 -0700154}
155
156void GrVkRenderPass::init(const GrVkGpu* gpu,
Greg Daniel77a86f82017-01-23 11:04:45 -0500157 const GrVkRenderTarget& target,
egdaniel2feb0932016-06-08 06:48:09 -0700158 const LoadStoreOps& colorOp,
egdaniel2feb0932016-06-08 06:48:09 -0700159 const LoadStoreOps& stencilOp) {
160 // Get attachment information from render target. This includes which attachments the render
egdanielce3bfb12016-08-26 11:05:13 -0700161 // target has (color, stencil) and the attachments format and sample count.
egdaniel2feb0932016-06-08 06:48:09 -0700162 target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
egdanielce3bfb12016-08-26 11:05:13 -0700163 this->init(gpu, colorOp, stencilOp);
egdaniel2feb0932016-06-08 06:48:09 -0700164}
165
Greg Daniel164a9f02016-02-22 09:56:40 -0500166void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
167 GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
168}
169
170// Works under the assumption that color attachment will always be the first attachment in our
171// attachment array if it exists.
172bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
173 *index = 0;
174 if (fAttachmentFlags & kColor_AttachmentFlag) {
175 return true;
176 }
177 return false;
178}
179
Greg Daniel164a9f02016-02-22 09:56:40 -0500180// Works under the assumption that stencil attachment will always be after the color and resolve
181// attachment.
182bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
183 *index = 0;
184 if (fAttachmentFlags & kColor_AttachmentFlag) {
185 ++(*index);
186 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500187 if (fAttachmentFlags & kStencil_AttachmentFlag) {
188 return true;
189 }
190 return false;
191}
192
egdaniel9a6cf802016-06-08 08:22:05 -0700193bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
194 const AttachmentFlags& flags) const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500195 if (flags != fAttachmentFlags) {
196 return false;
197 }
198
199 if (fAttachmentFlags & kColor_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700200 if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500201 return false;
202 }
203 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500204 if (fAttachmentFlags & kStencil_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700205 if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500206 return false;
207 }
208 }
209
210 return true;
211}
egdaniel22281c12016-03-23 13:49:40 -0700212
egdaniel9a6cf802016-06-08 08:22:05 -0700213bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
214 AttachmentsDescriptor desc;
215 AttachmentFlags flags;
216 target.getAttachmentsDescriptor(&desc, &flags);
217
218 return this->isCompatible(desc, flags);
219}
220
221bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
222 return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags);
223}
224
egdaniel2feb0932016-06-08 06:48:09 -0700225bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700226 const LoadStoreOps& stencilOps) const {
227 if (fAttachmentFlags & kColor_AttachmentFlag) {
228 if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
229 return false;
230 }
231 }
egdaniel2feb0932016-06-08 06:48:09 -0700232 if (fAttachmentFlags & kStencil_AttachmentFlag) {
233 if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
234 return false;
235 }
236 }
237 return true;
238}
239
egdaniel22281c12016-03-23 13:49:40 -0700240void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
241 b->add32(fAttachmentFlags);
242 if (fAttachmentFlags & kColor_AttachmentFlag) {
243 b->add32(fAttachmentsDescriptor.fColor.fFormat);
244 b->add32(fAttachmentsDescriptor.fColor.fSamples);
245 }
egdaniel22281c12016-03-23 13:49:40 -0700246 if (fAttachmentFlags & kStencil_AttachmentFlag) {
247 b->add32(fAttachmentsDescriptor.fStencil.fFormat);
248 b->add32(fAttachmentsDescriptor.fStencil.fSamples);
249 }
250}