blob: ee2d3d9f0e9415d77e7a617c3e9cc3024600dc2c [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:
38 SkFAIL("Unexpected attachment layout");
39 }
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;
87 } else {
88 // I don't think there should ever be a time where we don't have a color attachment
89 SkASSERT(false);
90 colorRef.attachment = VK_ATTACHMENT_UNUSED;
91 colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
92 subpassDesc.colorAttachmentCount = 0;
93 }
94 subpassDesc.pColorAttachments = &colorRef;
95
Greg Daniel164a9f02016-02-22 09:56:40 -050096 if (fAttachmentFlags & kStencil_AttachmentFlag) {
97 // set up stencil attachment
egdaniel2feb0932016-06-08 06:48:09 -070098 fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
egdanield62e28b2016-06-07 08:43:30 -070099 setup_vk_attachment_description(&attachments[currentAttachment],
100 fAttachmentsDescriptor.fStencil,
101 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -0500102 // setup subpass use of attachment
103 stencilRef.attachment = currentAttachment++;
104 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
105 } else {
106 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
107 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
108 }
109 subpassDesc.pDepthStencilAttachment = &stencilRef;
110
111 subpassDesc.preserveAttachmentCount = 0;
112 subpassDesc.pPreserveAttachments = nullptr;
113
114 SkASSERT(numAttachments == currentAttachment);
115
116 // Create the VkRenderPass compatible with the attachment descriptions above
117 VkRenderPassCreateInfo createInfo;
118 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
119 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
120 createInfo.pNext = nullptr;
121 createInfo.flags = 0;
122 createInfo.attachmentCount = numAttachments;
123 createInfo.pAttachments = attachments.begin();
124 createInfo.subpassCount = 1;
125 createInfo.pSubpasses = &subpassDesc;
126 createInfo.dependencyCount = 0;
127 createInfo.pDependencies = nullptr;
128
129 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
130 &createInfo,
131 nullptr,
132 &fRenderPass));
egdaniel27bb2842016-07-07 11:58:35 -0700133
134 // Get granularity for this render pass
135 GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
136 fRenderPass,
137 &fGranularity));
Greg Daniel164a9f02016-02-22 09:56:40 -0500138}
139
egdaniel2feb0932016-06-08 06:48:09 -0700140void GrVkRenderPass::init(const GrVkGpu* gpu,
141 const GrVkRenderPass& compatibleRenderPass,
142 const LoadStoreOps& colorOp,
egdaniel2feb0932016-06-08 06:48:09 -0700143 const LoadStoreOps& stencilOp) {
144 fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
145 fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
egdanielce3bfb12016-08-26 11:05:13 -0700146 this->init(gpu, colorOp, stencilOp);
egdaniel2feb0932016-06-08 06:48:09 -0700147}
148
149void GrVkRenderPass::init(const GrVkGpu* gpu,
150 const GrVkRenderTarget& target,
151 const LoadStoreOps& colorOp,
egdaniel2feb0932016-06-08 06:48:09 -0700152 const LoadStoreOps& stencilOp) {
153 // Get attachment information from render target. This includes which attachments the render
egdanielce3bfb12016-08-26 11:05:13 -0700154 // target has (color, stencil) and the attachments format and sample count.
egdaniel2feb0932016-06-08 06:48:09 -0700155 target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
egdanielce3bfb12016-08-26 11:05:13 -0700156 this->init(gpu, colorOp, stencilOp);
egdaniel2feb0932016-06-08 06:48:09 -0700157}
158
Greg Daniel164a9f02016-02-22 09:56:40 -0500159void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
160 GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
161}
162
163// Works under the assumption that color attachment will always be the first attachment in our
164// attachment array if it exists.
165bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
166 *index = 0;
167 if (fAttachmentFlags & kColor_AttachmentFlag) {
168 return true;
169 }
170 return false;
171}
172
Greg Daniel164a9f02016-02-22 09:56:40 -0500173// Works under the assumption that stencil attachment will always be after the color and resolve
174// attachment.
175bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
176 *index = 0;
177 if (fAttachmentFlags & kColor_AttachmentFlag) {
178 ++(*index);
179 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500180 if (fAttachmentFlags & kStencil_AttachmentFlag) {
181 return true;
182 }
183 return false;
184}
185
186void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
187 VkRenderPassBeginInfo* beginInfo,
188 VkSubpassContents* contents) const {
189 SkASSERT(this->isCompatible(target));
190
191 VkRect2D renderArea;
192 renderArea.offset = { 0, 0 };
193 renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() };
194
195 memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo));
196 beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
197 beginInfo->pNext = nullptr;
198 beginInfo->renderPass = fRenderPass;
199 beginInfo->framebuffer = target.framebuffer()->framebuffer();
200 beginInfo->renderArea = renderArea;
201 beginInfo->clearValueCount = 0;
202 beginInfo->pClearValues = nullptr;
203
halcanary9d524f22016-03-29 09:03:52 -0700204 // Currently just assuming no secondary cmd buffers. This value will need to be update if we
Greg Daniel164a9f02016-02-22 09:56:40 -0500205 // have them.
206 *contents = VK_SUBPASS_CONTENTS_INLINE;
207}
208
egdaniel9a6cf802016-06-08 08:22:05 -0700209bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
210 const AttachmentFlags& flags) const {
Greg Daniel164a9f02016-02-22 09:56:40 -0500211 if (flags != fAttachmentFlags) {
212 return false;
213 }
214
215 if (fAttachmentFlags & kColor_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700216 if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500217 return false;
218 }
219 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500220 if (fAttachmentFlags & kStencil_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700221 if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500222 return false;
223 }
224 }
225
226 return true;
227}
egdaniel22281c12016-03-23 13:49:40 -0700228
egdaniel9a6cf802016-06-08 08:22:05 -0700229bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
230 AttachmentsDescriptor desc;
231 AttachmentFlags flags;
232 target.getAttachmentsDescriptor(&desc, &flags);
233
234 return this->isCompatible(desc, flags);
235}
236
237bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
238 return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags);
239}
240
egdaniel2feb0932016-06-08 06:48:09 -0700241bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
egdaniel2feb0932016-06-08 06:48:09 -0700242 const LoadStoreOps& stencilOps) const {
243 if (fAttachmentFlags & kColor_AttachmentFlag) {
244 if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
245 return false;
246 }
247 }
egdaniel2feb0932016-06-08 06:48:09 -0700248 if (fAttachmentFlags & kStencil_AttachmentFlag) {
249 if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
250 return false;
251 }
252 }
253 return true;
254}
255
egdaniel22281c12016-03-23 13:49:40 -0700256void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
257 b->add32(fAttachmentFlags);
258 if (fAttachmentFlags & kColor_AttachmentFlag) {
259 b->add32(fAttachmentsDescriptor.fColor.fFormat);
260 b->add32(fAttachmentsDescriptor.fColor.fSamples);
261 }
egdaniel22281c12016-03-23 13:49:40 -0700262 if (fAttachmentFlags & kStencil_AttachmentFlag) {
263 b->add32(fAttachmentsDescriptor.fStencil.fFormat);
264 b->add32(fAttachmentsDescriptor.fStencil.fSamples);
265 }
266}