blob: 6a0f953a1c90f4d024fcaf2a8231c69162aaf123 [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
egdaniel2feb0932016-06-08 06:48:09 -070049 this->init(gpu, target, kBasicLoadStoreOps, kBasicLoadStoreOps, kBasicLoadStoreOps);
50}
51
52void GrVkRenderPass::init(const GrVkGpu* gpu,
53 const LoadStoreOps& colorOp,
54 const LoadStoreOps& resolveOp,
55 const LoadStoreOps& stencilOp) {
Greg Daniel164a9f02016-02-22 09:56:40 -050056 uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
57 // Attachment descriptions to be set on the render pass
58 SkTArray<VkAttachmentDescription> attachments(numAttachments);
59 attachments.reset(numAttachments);
egdaniel2feb0932016-06-08 06:48:09 -070060 memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));
Greg Daniel164a9f02016-02-22 09:56:40 -050061
62 // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
63 // that are used by the subpass.
64 VkAttachmentReference colorRef;
65 VkAttachmentReference resolveRef;
66 VkAttachmentReference stencilRef;
67 uint32_t currentAttachment = 0;
68
69 // Go through each of the attachment types (color, resolve, stencil) and set the necessary
70 // on the various Vk structs.
71 VkSubpassDescription subpassDesc;
72 memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
73 subpassDesc.flags = 0;
74 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
75 subpassDesc.inputAttachmentCount = 0;
76 subpassDesc.pInputAttachments = nullptr;
77 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
96 if (fAttachmentFlags & kResolve_AttachmentFlag) {
97 // set up resolve attachment
egdaniel2feb0932016-06-08 06:48:09 -070098 fAttachmentsDescriptor.fResolve.fLoadStoreOps = resolveOp;
egdanield62e28b2016-06-07 08:43:30 -070099 setup_vk_attachment_description(&attachments[currentAttachment],
100 fAttachmentsDescriptor.fResolve,
101 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -0500102 // setup subpass use of attachment
103 resolveRef.attachment = currentAttachment++;
104 // I'm really not sure what the layout should be for the resolve textures.
105 resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
106 subpassDesc.pResolveAttachments = &resolveRef;
107 } else {
108 subpassDesc.pResolveAttachments = nullptr;
109 }
110
111 if (fAttachmentFlags & kStencil_AttachmentFlag) {
112 // set up stencil attachment
egdaniel2feb0932016-06-08 06:48:09 -0700113 fAttachmentsDescriptor.fStencil.fLoadStoreOps = stencilOp;
egdanield62e28b2016-06-07 08:43:30 -0700114 setup_vk_attachment_description(&attachments[currentAttachment],
115 fAttachmentsDescriptor.fStencil,
116 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -0500117 // setup subpass use of attachment
118 stencilRef.attachment = currentAttachment++;
119 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
120 } else {
121 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
122 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
123 }
124 subpassDesc.pDepthStencilAttachment = &stencilRef;
125
126 subpassDesc.preserveAttachmentCount = 0;
127 subpassDesc.pPreserveAttachments = nullptr;
128
129 SkASSERT(numAttachments == currentAttachment);
130
131 // Create the VkRenderPass compatible with the attachment descriptions above
132 VkRenderPassCreateInfo createInfo;
133 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
134 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
135 createInfo.pNext = nullptr;
136 createInfo.flags = 0;
137 createInfo.attachmentCount = numAttachments;
138 createInfo.pAttachments = attachments.begin();
139 createInfo.subpassCount = 1;
140 createInfo.pSubpasses = &subpassDesc;
141 createInfo.dependencyCount = 0;
142 createInfo.pDependencies = nullptr;
143
144 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
145 &createInfo,
146 nullptr,
147 &fRenderPass));
148}
149
egdaniel2feb0932016-06-08 06:48:09 -0700150void GrVkRenderPass::init(const GrVkGpu* gpu,
151 const GrVkRenderPass& compatibleRenderPass,
152 const LoadStoreOps& colorOp,
153 const LoadStoreOps& resolveOp,
154 const LoadStoreOps& stencilOp) {
155 fAttachmentFlags = compatibleRenderPass.fAttachmentFlags;
156 fAttachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
157 this->init(gpu, colorOp, resolveOp, stencilOp);
158}
159
160void GrVkRenderPass::init(const GrVkGpu* gpu,
161 const GrVkRenderTarget& target,
162 const LoadStoreOps& colorOp,
163 const LoadStoreOps& resolveOp,
164 const LoadStoreOps& stencilOp) {
165 // Get attachment information from render target. This includes which attachments the render
166 // target has (color, resolve, stencil) and the attachments format and sample count.
167 target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
168 this->init(gpu, colorOp, resolveOp, stencilOp);
169}
170
Greg Daniel164a9f02016-02-22 09:56:40 -0500171void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
172 GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
173}
174
175// Works under the assumption that color attachment will always be the first attachment in our
176// attachment array if it exists.
177bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
178 *index = 0;
179 if (fAttachmentFlags & kColor_AttachmentFlag) {
180 return true;
181 }
182 return false;
183}
184
185// Works under the assumption that resolve attachment will always be after the color attachment.
186bool GrVkRenderPass::resolveAttachmentIndex(uint32_t* index) const {
187 *index = 0;
188 if (fAttachmentFlags & kColor_AttachmentFlag) {
189 ++(*index);
190 }
191 if (fAttachmentFlags & kResolve_AttachmentFlag) {
192 return true;
193 }
194 return false;
195}
196
197// Works under the assumption that stencil attachment will always be after the color and resolve
198// attachment.
199bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
200 *index = 0;
201 if (fAttachmentFlags & kColor_AttachmentFlag) {
202 ++(*index);
203 }
204 if (fAttachmentFlags & kResolve_AttachmentFlag) {
205 ++(*index);
206 }
207 if (fAttachmentFlags & kStencil_AttachmentFlag) {
208 return true;
209 }
210 return false;
211}
212
213void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
214 VkRenderPassBeginInfo* beginInfo,
215 VkSubpassContents* contents) const {
216 SkASSERT(this->isCompatible(target));
217
218 VkRect2D renderArea;
219 renderArea.offset = { 0, 0 };
220 renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() };
221
222 memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo));
223 beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
224 beginInfo->pNext = nullptr;
225 beginInfo->renderPass = fRenderPass;
226 beginInfo->framebuffer = target.framebuffer()->framebuffer();
227 beginInfo->renderArea = renderArea;
228 beginInfo->clearValueCount = 0;
229 beginInfo->pClearValues = nullptr;
230
halcanary9d524f22016-03-29 09:03:52 -0700231 // Currently just assuming no secondary cmd buffers. This value will need to be update if we
Greg Daniel164a9f02016-02-22 09:56:40 -0500232 // have them.
233 *contents = VK_SUBPASS_CONTENTS_INLINE;
234}
235
236bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
237 AttachmentsDescriptor desc;
238 AttachmentFlags flags;
239 target.getAttachmentsDescriptor(&desc, &flags);
240
241 if (flags != fAttachmentFlags) {
242 return false;
243 }
244
245 if (fAttachmentFlags & kColor_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700246 if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500247 return false;
248 }
249 }
250 if (fAttachmentFlags & kResolve_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700251 if (!fAttachmentsDescriptor.fResolve.isCompatible(desc.fResolve)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500252 return false;
253 }
254 }
255 if (fAttachmentFlags & kStencil_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700256 if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500257 return false;
258 }
259 }
260
261 return true;
262}
egdaniel22281c12016-03-23 13:49:40 -0700263
egdaniel2feb0932016-06-08 06:48:09 -0700264bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
265 const LoadStoreOps& resolveOps,
266 const LoadStoreOps& stencilOps) const {
267 if (fAttachmentFlags & kColor_AttachmentFlag) {
268 if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
269 return false;
270 }
271 }
272 if (fAttachmentFlags & kResolve_AttachmentFlag) {
273 if (fAttachmentsDescriptor.fResolve.fLoadStoreOps != resolveOps) {
274 return false;
275 }
276 }
277 if (fAttachmentFlags & kStencil_AttachmentFlag) {
278 if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
279 return false;
280 }
281 }
282 return true;
283}
284
egdaniel22281c12016-03-23 13:49:40 -0700285void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
286 b->add32(fAttachmentFlags);
287 if (fAttachmentFlags & kColor_AttachmentFlag) {
288 b->add32(fAttachmentsDescriptor.fColor.fFormat);
289 b->add32(fAttachmentsDescriptor.fColor.fSamples);
290 }
291 if (fAttachmentFlags & kResolve_AttachmentFlag) {
292 b->add32(fAttachmentsDescriptor.fResolve.fFormat);
293 b->add32(fAttachmentsDescriptor.fResolve.fSamples);
294 }
295 if (fAttachmentFlags & kStencil_AttachmentFlag) {
296 b->add32(fAttachmentsDescriptor.fStencil.fFormat);
297 b->add32(fAttachmentsDescriptor.fStencil.fSamples);
298 }
299}