blob: 9c4787b865cb3bce8ef6e271e37bfd5d9931357d [file] [log] [blame]
Greg Daniel48cf2682016-02-22 09:11:32 -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
10#include "GrVkFramebuffer.h"
11#include "GrVkGpu.h"
12#include "GrVkRenderTarget.h"
13#include "GrVkUtil.h"
14
15void setup_simple_vk_attachment_description(VkAttachmentDescription* attachment,
16 VkFormat format,
17 uint32_t samples,
18 VkImageLayout layout) {
19 attachment->flags = 0;
20 attachment->format = format;
21 SkAssertResult(GrSampleCountToVkSampleCount(samples, &attachment->samples));
22 attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
23 attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
24 attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
25 attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
26 attachment->initialLayout = layout;
27 attachment->finalLayout = layout;
28}
29
30void GrVkRenderPass::initSimple(const GrVkGpu* gpu, const GrVkRenderTarget& target) {
31 // Get attachment information from render target. This includes which attachments the render
32 // target has (color, resolve, stencil) and the attachments format and sample count.
33 target.getAttachmentsDescriptor(&fAttachmentsDescriptor, &fAttachmentFlags);
34
35 uint32_t numAttachments = fAttachmentsDescriptor.fAttachmentCount;
36 // Attachment descriptions to be set on the render pass
37 SkTArray<VkAttachmentDescription> attachments(numAttachments);
38 attachments.reset(numAttachments);
39 memset(attachments.begin(), 0, numAttachments*sizeof(VkAttachmentDescription));
40
41 // Refs to attachments on the render pass (as described by teh VkAttachmentDescription above),
42 // that are used by the subpass.
43 VkAttachmentReference colorRef;
44 VkAttachmentReference resolveRef;
45 VkAttachmentReference stencilRef;
46 uint32_t currentAttachment = 0;
47
48 // Go through each of the attachment types (color, resolve, stencil) and set the necessary
49 // on the various Vk structs.
50 VkSubpassDescription subpassDesc;
51 memset(&subpassDesc, 0, sizeof(VkSubpassDescription));
52 subpassDesc.flags = 0;
53 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
54 subpassDesc.inputAttachmentCount = 0;
55 subpassDesc.pInputAttachments = nullptr;
56 if (fAttachmentFlags & kColor_AttachmentFlag) {
57 // set up color attachment
58 setup_simple_vk_attachment_description(&attachments[currentAttachment],
59 fAttachmentsDescriptor.fColor.fFormat,
60 fAttachmentsDescriptor.fColor.fSamples,
61 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
62 // setup subpass use of attachment
63 colorRef.attachment = currentAttachment++;
64 colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
65 subpassDesc.colorAttachmentCount = 1;
66 } else {
67 // I don't think there should ever be a time where we don't have a color attachment
68 SkASSERT(false);
69 colorRef.attachment = VK_ATTACHMENT_UNUSED;
70 colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
71 subpassDesc.colorAttachmentCount = 0;
72 }
73 subpassDesc.pColorAttachments = &colorRef;
74
75 if (fAttachmentFlags & kResolve_AttachmentFlag) {
76 // set up resolve attachment
77 setup_simple_vk_attachment_description(&attachments[currentAttachment],
78 fAttachmentsDescriptor.fResolve.fFormat,
79 fAttachmentsDescriptor.fResolve.fSamples,
80 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
81 // setup subpass use of attachment
82 resolveRef.attachment = currentAttachment++;
83 // I'm really not sure what the layout should be for the resolve textures.
84 resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
85 subpassDesc.pResolveAttachments = &resolveRef;
86 } else {
87 subpassDesc.pResolveAttachments = nullptr;
88 }
89
90 if (fAttachmentFlags & kStencil_AttachmentFlag) {
91 // set up stencil attachment
92 setup_simple_vk_attachment_description(&attachments[currentAttachment],
93 fAttachmentsDescriptor.fStencil.fFormat,
94 fAttachmentsDescriptor.fStencil.fSamples,
95 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
96 // setup subpass use of attachment
97 stencilRef.attachment = currentAttachment++;
98 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
99 } else {
100 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
101 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
102 }
103 subpassDesc.pDepthStencilAttachment = &stencilRef;
104
105 subpassDesc.preserveAttachmentCount = 0;
106 subpassDesc.pPreserveAttachments = nullptr;
107
108 SkASSERT(numAttachments == currentAttachment);
109
110 // Create the VkRenderPass compatible with the attachment descriptions above
111 VkRenderPassCreateInfo createInfo;
112 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
113 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
114 createInfo.pNext = nullptr;
115 createInfo.flags = 0;
116 createInfo.attachmentCount = numAttachments;
117 createInfo.pAttachments = attachments.begin();
118 createInfo.subpassCount = 1;
119 createInfo.pSubpasses = &subpassDesc;
120 createInfo.dependencyCount = 0;
121 createInfo.pDependencies = nullptr;
122
123 GR_VK_CALL_ERRCHECK(gpu->vkInterface(), CreateRenderPass(gpu->device(),
124 &createInfo,
125 nullptr,
126 &fRenderPass));
127}
128
129void GrVkRenderPass::freeGPUData(const GrVkGpu* gpu) const {
130 GR_VK_CALL(gpu->vkInterface(), DestroyRenderPass(gpu->device(), fRenderPass, nullptr));
131}
132
133// Works under the assumption that color attachment will always be the first attachment in our
134// attachment array if it exists.
135bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
136 *index = 0;
137 if (fAttachmentFlags & kColor_AttachmentFlag) {
138 return true;
139 }
140 return false;
141}
142
143// Works under the assumption that resolve attachment will always be after the color attachment.
144bool GrVkRenderPass::resolveAttachmentIndex(uint32_t* index) const {
145 *index = 0;
146 if (fAttachmentFlags & kColor_AttachmentFlag) {
147 ++(*index);
148 }
149 if (fAttachmentFlags & kResolve_AttachmentFlag) {
150 return true;
151 }
152 return false;
153}
154
155// Works under the assumption that stencil attachment will always be after the color and resolve
156// attachment.
157bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
158 *index = 0;
159 if (fAttachmentFlags & kColor_AttachmentFlag) {
160 ++(*index);
161 }
162 if (fAttachmentFlags & kResolve_AttachmentFlag) {
163 ++(*index);
164 }
165 if (fAttachmentFlags & kStencil_AttachmentFlag) {
166 return true;
167 }
168 return false;
169}
170
171void GrVkRenderPass::getBeginInfo(const GrVkRenderTarget& target,
172 VkRenderPassBeginInfo* beginInfo,
173 VkSubpassContents* contents) const {
174 SkASSERT(this->isCompatible(target));
175
176 VkRect2D renderArea;
177 renderArea.offset = { 0, 0 };
178 renderArea.extent = { (uint32_t)target.width(), (uint32_t)target.height() };
179
180 memset(beginInfo, 0, sizeof(VkRenderPassBeginInfo));
181 beginInfo->sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
182 beginInfo->pNext = nullptr;
183 beginInfo->renderPass = fRenderPass;
184 beginInfo->framebuffer = target.framebuffer()->framebuffer();
185 beginInfo->renderArea = renderArea;
186 beginInfo->clearValueCount = 0;
187 beginInfo->pClearValues = nullptr;
188
189 // Currently just assuming no secondary cmd buffers. This value will need to be update if we
190 // have them.
191 *contents = VK_SUBPASS_CONTENTS_INLINE;
192}
193
194bool GrVkRenderPass::isCompatible(const GrVkRenderTarget& target) const {
195 AttachmentsDescriptor desc;
196 AttachmentFlags flags;
197 target.getAttachmentsDescriptor(&desc, &flags);
198
199 if (flags != fAttachmentFlags) {
200 return false;
201 }
202
203 if (fAttachmentFlags & kColor_AttachmentFlag) {
204 if (fAttachmentsDescriptor.fColor != desc.fColor) {
205 return false;
206 }
207 }
208 if (fAttachmentFlags & kResolve_AttachmentFlag) {
209 if (fAttachmentsDescriptor.fResolve != desc.fResolve) {
210 return false;
211 }
212 }
213 if (fAttachmentFlags & kStencil_AttachmentFlag) {
214 if (fAttachmentsDescriptor.fStencil != desc.fStencil) {
215 return false;
216 }
217 }
218
219 return true;
220}