blob: c56bafa92daa367c547d95adbf4b36961255103e [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:
26 attachment->loadOp = desc.fLoadOp;
27 attachment->storeOp = desc.fStoreOp;
28 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;
34 attachment->stencilLoadOp = desc.fLoadOp;
35 attachment->stencilStoreOp = desc.fStoreOp;
36 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) {
46 // Get attachment information from render target. This includes which attachments the render
47 // target has (color, resolve, stencil) and the attachments format and sample count.
48 target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
49
50 uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
51 // Attachment descriptions to be set on the render pass
52 SkTArray<VkAttachmentDescription> attachments(numAttachments);
53 attachments.reset(numAttachments);
54 memset(attachments.begin(), 0, numAttachments*sizeof(VkAttachmentDescription));
55
56 // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
57 // that are used by the subpass.
58 VkAttachmentReference colorRef;
59 VkAttachmentReference resolveRef;
60 VkAttachmentReference stencilRef;
61 uint32_t currentAttachment = 0;
62
63 // Go through each of the attachment types (color, resolve, stencil) and set the necessary
64 // on the various Vk structs.
65 VkSubpassDescription subpassDesc;
66 memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
67 subpassDesc.flags = 0;
68 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
69 subpassDesc.inputAttachmentCount = 0;
70 subpassDesc.pInputAttachments = nullptr;
71 if (fAttachmentFlags & kColor_AttachmentFlag) {
72 // set up color attachment
egdanield62e28b2016-06-07 08:43:30 -070073 setup_vk_attachment_description(&attachments[currentAttachment],
74 fAttachmentsDescriptor.fColor,
75 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -050076 // setup subpass use of attachment
77 colorRef.attachment = currentAttachment++;
78 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
79 subpassDesc.colorAttachmentCount = 1;
80 } else {
81 // I don't think there should ever be a time where we don't have a color attachment
82 SkASSERT(false);
83 colorRef.attachment = VK_ATTACHMENT_UNUSED;
84 colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
85 subpassDesc.colorAttachmentCount = 0;
86 }
87 subpassDesc.pColorAttachments = &colorRef;
88
89 if (fAttachmentFlags & kResolve_AttachmentFlag) {
90 // set up resolve attachment
egdanield62e28b2016-06-07 08:43:30 -070091 setup_vk_attachment_description(&attachments[currentAttachment],
92 fAttachmentsDescriptor.fResolve,
93 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -050094 // setup subpass use of attachment
95 resolveRef.attachment = currentAttachment++;
96 // I'm really not sure what the layout should be for the resolve textures.
97 resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
98 subpassDesc.pResolveAttachments = &resolveRef;
99 } else {
100 subpassDesc.pResolveAttachments = nullptr;
101 }
102
103 if (fAttachmentFlags & kStencil_AttachmentFlag) {
104 // set up stencil attachment
egdanield62e28b2016-06-07 08:43:30 -0700105 setup_vk_attachment_description(&attachments[currentAttachment],
106 fAttachmentsDescriptor.fStencil,
107 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Greg Daniel164a9f02016-02-22 09:56:40 -0500108 // setup subpass use of attachment
109 stencilRef.attachment = currentAttachment++;
110 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
111 } else {
112 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
113 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
114 }
115 subpassDesc.pDepthStencilAttachment = &stencilRef;
116
117 subpassDesc.preserveAttachmentCount = 0;
118 subpassDesc.pPreserveAttachments = nullptr;
119
120 SkASSERT(numAttachments == currentAttachment);
121
122 // Create the VkRenderPass compatible with the attachment descriptions above
123 VkRenderPassCreateInfo createInfo;
124 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
125 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
126 createInfo.pNext = nullptr;
127 createInfo.flags = 0;
128 createInfo.attachmentCount = numAttachments;
129 createInfo.pAttachments = attachments.begin();
130 createInfo.subpassCount = 1;
131 createInfo.pSubpasses = &subpassDesc;
132 createInfo.dependencyCount = 0;
133 createInfo.pDependencies = nullptr;
134
135 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
136 &createInfo,
137 nullptr,
138 &fRenderPass));
139}
140
141void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
142 GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
143}
144
145// Works under the assumption that color attachment will always be the first attachment in our
146// attachment array if it exists.
147bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
148 *index = 0;
149 if (fAttachmentFlags & kColor_AttachmentFlag) {
150 return true;
151 }
152 return false;
153}
154
155// Works under the assumption that resolve attachment will always be after the color attachment.
156bool GrVkRenderPass::resolveAttachmentIndex(uint32_t* index) const {
157 *index = 0;
158 if (fAttachmentFlags & kColor_AttachmentFlag) {
159 ++(*index);
160 }
161 if (fAttachmentFlags & kResolve_AttachmentFlag) {
162 return true;
163 }
164 return false;
165}
166
167// Works under the assumption that stencil attachment will always be after the color and resolve
168// attachment.
169bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
170 *index = 0;
171 if (fAttachmentFlags & kColor_AttachmentFlag) {
172 ++(*index);
173 }
174 if (fAttachmentFlags & kResolve_AttachmentFlag) {
175 ++(*index);
176 }
177 if (fAttachmentFlags & kStencil_AttachmentFlag) {
178 return true;
179 }
180 return false;
181}
182
183void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
184 VkRenderPassBeginInfo* beginInfo,
185 VkSubpassContents* contents) const {
186 SkASSERT(this->isCompatible(target));
187
188 VkRect2D renderArea;
189 renderArea.offset = { 0, 0 };
190 renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() };
191
192 memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo));
193 beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
194 beginInfo->pNext = nullptr;
195 beginInfo->renderPass = fRenderPass;
196 beginInfo->framebuffer = target.framebuffer()->framebuffer();
197 beginInfo->renderArea = renderArea;
198 beginInfo->clearValueCount = 0;
199 beginInfo->pClearValues = nullptr;
200
halcanary9d524f22016-03-29 09:03:52 -0700201 // Currently just assuming no secondary cmd buffers. This value will need to be update if we
Greg Daniel164a9f02016-02-22 09:56:40 -0500202 // have them.
203 *contents = VK_SUBPASS_CONTENTS_INLINE;
204}
205
206bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
207 AttachmentsDescriptor desc;
208 AttachmentFlags flags;
209 target.getAttachmentsDescriptor(&desc, &flags);
210
211 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 }
220 if (fAttachmentFlags & kResolve_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700221 if (!fAttachmentsDescriptor.fResolve.isCompatible(desc.fResolve)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500222 return false;
223 }
224 }
225 if (fAttachmentFlags & kStencil_AttachmentFlag) {
egdanield62e28b2016-06-07 08:43:30 -0700226 if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500227 return false;
228 }
229 }
230
231 return true;
232}
egdaniel22281c12016-03-23 13:49:40 -0700233
234void GrVkRenderPass::genKey(GrProcessorKeyBuilder* b) const {
235 b->add32(fAttachmentFlags);
236 if (fAttachmentFlags & kColor_AttachmentFlag) {
237 b->add32(fAttachmentsDescriptor.fColor.fFormat);
238 b->add32(fAttachmentsDescriptor.fColor.fSamples);
239 }
240 if (fAttachmentFlags & kResolve_AttachmentFlag) {
241 b->add32(fAttachmentsDescriptor.fResolve.fFormat);
242 b->add32(fAttachmentsDescriptor.fResolve.fSamples);
243 }
244 if (fAttachmentFlags & kStencil_AttachmentFlag) {
245 b->add32(fAttachmentsDescriptor.fStencil.fFormat);
246 b->add32(fAttachmentsDescriptor.fStencil.fSamples);
247 }
248}