xref: /aosp_15_r20/external/swiftshader/src/Vulkan/VkRenderPass.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "VkRenderPass.hpp"
16*03ce13f7SAndroid Build Coastguard Worker #include "VkStringify.hpp"
17*03ce13f7SAndroid Build Coastguard Worker #include <cstring>
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker namespace {
20*03ce13f7SAndroid Build Coastguard Worker 
21*03ce13f7SAndroid Build Coastguard Worker template<class T>
ComputeRequiredAllocationSizeT(const T * pCreateInfo)22*03ce13f7SAndroid Build Coastguard Worker size_t ComputeRequiredAllocationSizeT(const T *pCreateInfo)
23*03ce13f7SAndroid Build Coastguard Worker {
24*03ce13f7SAndroid Build Coastguard Worker 	size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription) + pCreateInfo->attachmentCount * sizeof(int)  // first use
25*03ce13f7SAndroid Build Coastguard Worker 	                        + pCreateInfo->attachmentCount * sizeof(uint32_t);                                                           // union of subpass view masks, per attachment
26*03ce13f7SAndroid Build Coastguard Worker 	size_t subpassesSize = 0;
27*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
28*03ce13f7SAndroid Build Coastguard Worker 	{
29*03ce13f7SAndroid Build Coastguard Worker 		const auto &subpass = pCreateInfo->pSubpasses[i];
30*03ce13f7SAndroid Build Coastguard Worker 		uint32_t nbAttachments = subpass.inputAttachmentCount + subpass.colorAttachmentCount;
31*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.pResolveAttachments)
32*03ce13f7SAndroid Build Coastguard Worker 		{
33*03ce13f7SAndroid Build Coastguard Worker 			nbAttachments += subpass.colorAttachmentCount;
34*03ce13f7SAndroid Build Coastguard Worker 		}
35*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.pDepthStencilAttachment)
36*03ce13f7SAndroid Build Coastguard Worker 		{
37*03ce13f7SAndroid Build Coastguard Worker 			nbAttachments += 1;
38*03ce13f7SAndroid Build Coastguard Worker 		}
39*03ce13f7SAndroid Build Coastguard Worker 		subpassesSize += sizeof(VkSubpassDescription) +
40*03ce13f7SAndroid Build Coastguard Worker 		                 sizeof(VkAttachmentReference) * nbAttachments +
41*03ce13f7SAndroid Build Coastguard Worker 		                 sizeof(uint32_t) * subpass.preserveAttachmentCount +
42*03ce13f7SAndroid Build Coastguard Worker 		                 sizeof(uint32_t);  // view mask
43*03ce13f7SAndroid Build Coastguard Worker 	}
44*03ce13f7SAndroid Build Coastguard Worker 	size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
45*03ce13f7SAndroid Build Coastguard Worker 
46*03ce13f7SAndroid Build Coastguard Worker 	return attachmentSize + subpassesSize + dependenciesSize;
47*03ce13f7SAndroid Build Coastguard Worker }
48*03ce13f7SAndroid Build Coastguard Worker 
49*03ce13f7SAndroid Build Coastguard Worker template<class T>
CopySubpasses(VkSubpassDescription * dst,const T * src,uint32_t count)50*03ce13f7SAndroid Build Coastguard Worker void CopySubpasses(VkSubpassDescription *dst, const T *src, uint32_t count)
51*03ce13f7SAndroid Build Coastguard Worker {
52*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < count; ++i)
53*03ce13f7SAndroid Build Coastguard Worker 	{
54*03ce13f7SAndroid Build Coastguard Worker 		dst[i].flags = src[i].flags;
55*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pipelineBindPoint = src[i].pipelineBindPoint;
56*03ce13f7SAndroid Build Coastguard Worker 		dst[i].inputAttachmentCount = src[i].inputAttachmentCount;
57*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pInputAttachments = nullptr;
58*03ce13f7SAndroid Build Coastguard Worker 		dst[i].colorAttachmentCount = src[i].colorAttachmentCount;
59*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pColorAttachments = nullptr;
60*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pResolveAttachments = nullptr;
61*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pDepthStencilAttachment = nullptr;
62*03ce13f7SAndroid Build Coastguard Worker 		dst[i].preserveAttachmentCount = src[i].preserveAttachmentCount;
63*03ce13f7SAndroid Build Coastguard Worker 		dst[i].pPreserveAttachments = nullptr;
64*03ce13f7SAndroid Build Coastguard Worker 	}
65*03ce13f7SAndroid Build Coastguard Worker }
66*03ce13f7SAndroid Build Coastguard Worker 
67*03ce13f7SAndroid Build Coastguard Worker template<class T>
CopyAttachmentDescriptions(VkAttachmentDescription * dst,const T * src,uint32_t count)68*03ce13f7SAndroid Build Coastguard Worker void CopyAttachmentDescriptions(VkAttachmentDescription *dst, const T *src, uint32_t count)
69*03ce13f7SAndroid Build Coastguard Worker {
70*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < count; ++i)
71*03ce13f7SAndroid Build Coastguard Worker 	{
72*03ce13f7SAndroid Build Coastguard Worker 		dst[i].flags = src[i].flags;
73*03ce13f7SAndroid Build Coastguard Worker 		dst[i].format = src[i].format;
74*03ce13f7SAndroid Build Coastguard Worker 		dst[i].samples = src[i].samples;
75*03ce13f7SAndroid Build Coastguard Worker 		dst[i].loadOp = src[i].loadOp;
76*03ce13f7SAndroid Build Coastguard Worker 		dst[i].storeOp = src[i].storeOp;
77*03ce13f7SAndroid Build Coastguard Worker 		dst[i].stencilLoadOp = src[i].stencilLoadOp;
78*03ce13f7SAndroid Build Coastguard Worker 		dst[i].stencilStoreOp = src[i].stencilStoreOp;
79*03ce13f7SAndroid Build Coastguard Worker 		dst[i].initialLayout = src[i].initialLayout;
80*03ce13f7SAndroid Build Coastguard Worker 		dst[i].finalLayout = src[i].finalLayout;
81*03ce13f7SAndroid Build Coastguard Worker 	}
82*03ce13f7SAndroid Build Coastguard Worker }
83*03ce13f7SAndroid Build Coastguard Worker 
84*03ce13f7SAndroid Build Coastguard Worker template<class T>
CopyAttachmentReferences(VkAttachmentReference * dst,const T * src,uint32_t count)85*03ce13f7SAndroid Build Coastguard Worker void CopyAttachmentReferences(VkAttachmentReference *dst, const T *src, uint32_t count)
86*03ce13f7SAndroid Build Coastguard Worker {
87*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < count; ++i)
88*03ce13f7SAndroid Build Coastguard Worker 	{
89*03ce13f7SAndroid Build Coastguard Worker 		dst[i].attachment = src[i].attachment;
90*03ce13f7SAndroid Build Coastguard Worker 		dst[i].layout = src[i].layout;
91*03ce13f7SAndroid Build Coastguard Worker 	}
92*03ce13f7SAndroid Build Coastguard Worker }
93*03ce13f7SAndroid Build Coastguard Worker 
94*03ce13f7SAndroid Build Coastguard Worker template<class T>
CopySubpassDependencies(VkSubpassDependency * dst,const T * src,uint32_t count)95*03ce13f7SAndroid Build Coastguard Worker void CopySubpassDependencies(VkSubpassDependency *dst, const T *src, uint32_t count)
96*03ce13f7SAndroid Build Coastguard Worker {
97*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < count; ++i)
98*03ce13f7SAndroid Build Coastguard Worker 	{
99*03ce13f7SAndroid Build Coastguard Worker 		dst[i].srcSubpass = src[i].srcSubpass;
100*03ce13f7SAndroid Build Coastguard Worker 		dst[i].dstSubpass = src[i].dstSubpass;
101*03ce13f7SAndroid Build Coastguard Worker 		dst[i].srcStageMask = src[i].srcStageMask;
102*03ce13f7SAndroid Build Coastguard Worker 		dst[i].dstStageMask = src[i].dstStageMask;
103*03ce13f7SAndroid Build Coastguard Worker 		dst[i].srcAccessMask = src[i].srcAccessMask;
104*03ce13f7SAndroid Build Coastguard Worker 		dst[i].dstAccessMask = src[i].dstAccessMask;
105*03ce13f7SAndroid Build Coastguard Worker 		dst[i].dependencyFlags = src[i].dependencyFlags;
106*03ce13f7SAndroid Build Coastguard Worker 	}
107*03ce13f7SAndroid Build Coastguard Worker }
108*03ce13f7SAndroid Build Coastguard Worker 
GetViewMasks(const VkRenderPassCreateInfo * pCreateInfo,uint32_t * masks)109*03ce13f7SAndroid Build Coastguard Worker bool GetViewMasks(const VkRenderPassCreateInfo *pCreateInfo, uint32_t *masks)
110*03ce13f7SAndroid Build Coastguard Worker {
111*03ce13f7SAndroid Build Coastguard Worker 	return false;
112*03ce13f7SAndroid Build Coastguard Worker }
113*03ce13f7SAndroid Build Coastguard Worker 
GetViewMasks(const VkRenderPassCreateInfo2KHR * pCreateInfo,uint32_t * masks)114*03ce13f7SAndroid Build Coastguard Worker bool GetViewMasks(const VkRenderPassCreateInfo2KHR *pCreateInfo, uint32_t *masks)
115*03ce13f7SAndroid Build Coastguard Worker {
116*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
117*03ce13f7SAndroid Build Coastguard Worker 	{
118*03ce13f7SAndroid Build Coastguard Worker 		masks[i] = pCreateInfo->pSubpasses[i].viewMask;
119*03ce13f7SAndroid Build Coastguard Worker 	}
120*03ce13f7SAndroid Build Coastguard Worker 	return true;
121*03ce13f7SAndroid Build Coastguard Worker }
122*03ce13f7SAndroid Build Coastguard Worker 
123*03ce13f7SAndroid Build Coastguard Worker }  // namespace
124*03ce13f7SAndroid Build Coastguard Worker 
125*03ce13f7SAndroid Build Coastguard Worker namespace vk {
126*03ce13f7SAndroid Build Coastguard Worker 
RenderPass(const VkRenderPassCreateInfo * pCreateInfo,void * mem)127*03ce13f7SAndroid Build Coastguard Worker RenderPass::RenderPass(const VkRenderPassCreateInfo *pCreateInfo, void *mem)
128*03ce13f7SAndroid Build Coastguard Worker     : attachmentCount(pCreateInfo->attachmentCount)
129*03ce13f7SAndroid Build Coastguard Worker     , subpassCount(pCreateInfo->subpassCount)
130*03ce13f7SAndroid Build Coastguard Worker     , dependencyCount(pCreateInfo->dependencyCount)
131*03ce13f7SAndroid Build Coastguard Worker {
132*03ce13f7SAndroid Build Coastguard Worker 	init(pCreateInfo, &mem);
133*03ce13f7SAndroid Build Coastguard Worker }
134*03ce13f7SAndroid Build Coastguard Worker 
RenderPass(const VkRenderPassCreateInfo2KHR * pCreateInfo,void * mem)135*03ce13f7SAndroid Build Coastguard Worker RenderPass::RenderPass(const VkRenderPassCreateInfo2KHR *pCreateInfo, void *mem)
136*03ce13f7SAndroid Build Coastguard Worker     : attachmentCount(pCreateInfo->attachmentCount)
137*03ce13f7SAndroid Build Coastguard Worker     , subpassCount(pCreateInfo->subpassCount)
138*03ce13f7SAndroid Build Coastguard Worker     , dependencyCount(pCreateInfo->dependencyCount)
139*03ce13f7SAndroid Build Coastguard Worker {
140*03ce13f7SAndroid Build Coastguard Worker 	init(pCreateInfo, &mem);
141*03ce13f7SAndroid Build Coastguard Worker 	// Note: the init function above ignores:
142*03ce13f7SAndroid Build Coastguard Worker 	// - pCorrelatedViewMasks: This provides a potential performance optimization
143*03ce13f7SAndroid Build Coastguard Worker 	// - VkAttachmentReference2::aspectMask : This specifies which aspects may be used
144*03ce13f7SAndroid Build Coastguard Worker 	// - VkSubpassDependency2::viewOffset : This is the same as VkRenderPassMultiviewCreateInfo::pViewOffsets, which is currently ignored
145*03ce13f7SAndroid Build Coastguard Worker 	// - Any pNext pointer in VkRenderPassCreateInfo2KHR's internal structures
146*03ce13f7SAndroid Build Coastguard Worker 
147*03ce13f7SAndroid Build Coastguard Worker 	char *hostMemory = reinterpret_cast<char *>(mem);
148*03ce13f7SAndroid Build Coastguard Worker 
149*03ce13f7SAndroid Build Coastguard Worker 	// Handle the extensions in each subpass
150*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < subpassCount; i++)
151*03ce13f7SAndroid Build Coastguard Worker 	{
152*03ce13f7SAndroid Build Coastguard Worker 		const auto &subpass = pCreateInfo->pSubpasses[i];
153*03ce13f7SAndroid Build Coastguard Worker 		const auto *extension = reinterpret_cast<const VkBaseInStructure *>(subpass.pNext);
154*03ce13f7SAndroid Build Coastguard Worker 		while(extension)
155*03ce13f7SAndroid Build Coastguard Worker 		{
156*03ce13f7SAndroid Build Coastguard Worker 			switch(extension->sType)
157*03ce13f7SAndroid Build Coastguard Worker 			{
158*03ce13f7SAndroid Build Coastguard Worker 			case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE:
159*03ce13f7SAndroid Build Coastguard Worker 				{
160*03ce13f7SAndroid Build Coastguard Worker 					const auto *ext = reinterpret_cast<const VkSubpassDescriptionDepthStencilResolve *>(extension);
161*03ce13f7SAndroid Build Coastguard Worker 					// If any subpass includes depthStencilResolve, allocate a DSR struct for each subpass
162*03ce13f7SAndroid Build Coastguard Worker 					// This allows us to index into subpassDepthStencilResolves using the subpass index.
163*03ce13f7SAndroid Build Coastguard Worker 					if(ext->pDepthStencilResolveAttachment != nullptr && ext->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED)
164*03ce13f7SAndroid Build Coastguard Worker 					{
165*03ce13f7SAndroid Build Coastguard Worker 						if(subpassDepthStencilResolves == nullptr)
166*03ce13f7SAndroid Build Coastguard Worker 						{
167*03ce13f7SAndroid Build Coastguard Worker 							// Align host memory to 8-bytes
168*03ce13f7SAndroid Build Coastguard Worker 							const intptr_t memoryAsInt = reinterpret_cast<intptr_t>(hostMemory);
169*03ce13f7SAndroid Build Coastguard Worker 							const intptr_t alignment = alignof(VkSubpassDescriptionDepthStencilResolve);
170*03ce13f7SAndroid Build Coastguard Worker 							const intptr_t padding = (alignment - memoryAsInt % alignment) % alignment;
171*03ce13f7SAndroid Build Coastguard Worker 							hostMemory += padding;
172*03ce13f7SAndroid Build Coastguard Worker 
173*03ce13f7SAndroid Build Coastguard Worker 							subpassDepthStencilResolves = reinterpret_cast<VkSubpassDescriptionDepthStencilResolve *>(hostMemory);
174*03ce13f7SAndroid Build Coastguard Worker 							hostMemory += subpassCount * sizeof(VkSubpassDescriptionDepthStencilResolve);
175*03ce13f7SAndroid Build Coastguard Worker 							for(uint32_t subpass = 0; subpass < subpassCount; subpass++)
176*03ce13f7SAndroid Build Coastguard Worker 							{
177*03ce13f7SAndroid Build Coastguard Worker 								subpassDepthStencilResolves[subpass].sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE;
178*03ce13f7SAndroid Build Coastguard Worker 								subpassDepthStencilResolves[subpass].pNext = nullptr;
179*03ce13f7SAndroid Build Coastguard Worker 								subpassDepthStencilResolves[subpass].depthResolveMode = VK_RESOLVE_MODE_NONE;
180*03ce13f7SAndroid Build Coastguard Worker 								subpassDepthStencilResolves[subpass].stencilResolveMode = VK_RESOLVE_MODE_NONE;
181*03ce13f7SAndroid Build Coastguard Worker 								subpassDepthStencilResolves[subpass].pDepthStencilResolveAttachment = nullptr;
182*03ce13f7SAndroid Build Coastguard Worker 							}
183*03ce13f7SAndroid Build Coastguard Worker 						}
184*03ce13f7SAndroid Build Coastguard Worker 
185*03ce13f7SAndroid Build Coastguard Worker 						VkAttachmentReference2 *reference = reinterpret_cast<VkAttachmentReference2 *>(hostMemory);
186*03ce13f7SAndroid Build Coastguard Worker 						hostMemory += sizeof(VkAttachmentReference2);
187*03ce13f7SAndroid Build Coastguard Worker 
188*03ce13f7SAndroid Build Coastguard Worker 						subpassDepthStencilResolves[i].depthResolveMode = ext->depthResolveMode;
189*03ce13f7SAndroid Build Coastguard Worker 						subpassDepthStencilResolves[i].stencilResolveMode = ext->stencilResolveMode;
190*03ce13f7SAndroid Build Coastguard Worker 						reference->pNext = nullptr;
191*03ce13f7SAndroid Build Coastguard Worker 						reference->sType = ext->pDepthStencilResolveAttachment->sType;
192*03ce13f7SAndroid Build Coastguard Worker 						reference->attachment = ext->pDepthStencilResolveAttachment->attachment;
193*03ce13f7SAndroid Build Coastguard Worker 						reference->layout = ext->pDepthStencilResolveAttachment->layout;
194*03ce13f7SAndroid Build Coastguard Worker 						reference->aspectMask = ext->pDepthStencilResolveAttachment->aspectMask;
195*03ce13f7SAndroid Build Coastguard Worker 						subpassDepthStencilResolves[i].pDepthStencilResolveAttachment = reinterpret_cast<const VkAttachmentReference2 *>(reference);
196*03ce13f7SAndroid Build Coastguard Worker 
197*03ce13f7SAndroid Build Coastguard Worker 						MarkFirstUse(reference->attachment, i);
198*03ce13f7SAndroid Build Coastguard Worker 					}
199*03ce13f7SAndroid Build Coastguard Worker 				}
200*03ce13f7SAndroid Build Coastguard Worker 				break;
201*03ce13f7SAndroid Build Coastguard Worker 			default:
202*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("VkRenderPassCreateInfo2KHR->subpass[%d]->pNext sType: %s",
203*03ce13f7SAndroid Build Coastguard Worker 				            i, vk::Stringify(extension->sType).c_str());
204*03ce13f7SAndroid Build Coastguard Worker 				break;
205*03ce13f7SAndroid Build Coastguard Worker 			}
206*03ce13f7SAndroid Build Coastguard Worker 
207*03ce13f7SAndroid Build Coastguard Worker 			extension = extension->pNext;
208*03ce13f7SAndroid Build Coastguard Worker 		}
209*03ce13f7SAndroid Build Coastguard Worker 	}
210*03ce13f7SAndroid Build Coastguard Worker }
211*03ce13f7SAndroid Build Coastguard Worker 
212*03ce13f7SAndroid Build Coastguard Worker template<class T>
init(const T * pCreateInfo,void ** mem)213*03ce13f7SAndroid Build Coastguard Worker void RenderPass::init(const T *pCreateInfo, void **mem)
214*03ce13f7SAndroid Build Coastguard Worker {
215*03ce13f7SAndroid Build Coastguard Worker 	char *hostMemory = reinterpret_cast<char *>(*mem);
216*03ce13f7SAndroid Build Coastguard Worker 
217*03ce13f7SAndroid Build Coastguard Worker 	// subpassCount must be greater than 0
218*03ce13f7SAndroid Build Coastguard Worker 	ASSERT(pCreateInfo->subpassCount > 0);
219*03ce13f7SAndroid Build Coastguard Worker 
220*03ce13f7SAndroid Build Coastguard Worker 	size_t subpassesSize = pCreateInfo->subpassCount * sizeof(VkSubpassDescription);
221*03ce13f7SAndroid Build Coastguard Worker 	subpasses = reinterpret_cast<VkSubpassDescription *>(hostMemory);
222*03ce13f7SAndroid Build Coastguard Worker 	CopySubpasses(subpasses, pCreateInfo->pSubpasses, pCreateInfo->subpassCount);
223*03ce13f7SAndroid Build Coastguard Worker 	hostMemory += subpassesSize;
224*03ce13f7SAndroid Build Coastguard Worker 	uint32_t *masks = reinterpret_cast<uint32_t *>(hostMemory);
225*03ce13f7SAndroid Build Coastguard Worker 	hostMemory += subpassCount * sizeof(uint32_t);
226*03ce13f7SAndroid Build Coastguard Worker 
227*03ce13f7SAndroid Build Coastguard Worker 	if(attachmentCount > 0)
228*03ce13f7SAndroid Build Coastguard Worker 	{
229*03ce13f7SAndroid Build Coastguard Worker 		size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription);
230*03ce13f7SAndroid Build Coastguard Worker 		attachments = reinterpret_cast<VkAttachmentDescription *>(hostMemory);
231*03ce13f7SAndroid Build Coastguard Worker 		CopyAttachmentDescriptions(attachments, pCreateInfo->pAttachments, pCreateInfo->attachmentCount);
232*03ce13f7SAndroid Build Coastguard Worker 		hostMemory += attachmentSize;
233*03ce13f7SAndroid Build Coastguard Worker 
234*03ce13f7SAndroid Build Coastguard Worker 		size_t firstUseSize = pCreateInfo->attachmentCount * sizeof(int);
235*03ce13f7SAndroid Build Coastguard Worker 		attachmentFirstUse = reinterpret_cast<int *>(hostMemory);
236*03ce13f7SAndroid Build Coastguard Worker 		hostMemory += firstUseSize;
237*03ce13f7SAndroid Build Coastguard Worker 
238*03ce13f7SAndroid Build Coastguard Worker 		attachmentViewMasks = reinterpret_cast<uint32_t *>(hostMemory);
239*03ce13f7SAndroid Build Coastguard Worker 		hostMemory += pCreateInfo->attachmentCount * sizeof(uint32_t);
240*03ce13f7SAndroid Build Coastguard Worker 		for(auto i = 0u; i < pCreateInfo->attachmentCount; i++)
241*03ce13f7SAndroid Build Coastguard Worker 		{
242*03ce13f7SAndroid Build Coastguard Worker 			attachmentFirstUse[i] = -1;
243*03ce13f7SAndroid Build Coastguard Worker 			attachmentViewMasks[i] = 0;
244*03ce13f7SAndroid Build Coastguard Worker 		}
245*03ce13f7SAndroid Build Coastguard Worker 	}
246*03ce13f7SAndroid Build Coastguard Worker 
247*03ce13f7SAndroid Build Coastguard Worker 	const VkBaseInStructure *extensionCreateInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext);
248*03ce13f7SAndroid Build Coastguard Worker 	while(extensionCreateInfo)
249*03ce13f7SAndroid Build Coastguard Worker 	{
250*03ce13f7SAndroid Build Coastguard Worker 		switch(extensionCreateInfo->sType)
251*03ce13f7SAndroid Build Coastguard Worker 		{
252*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
253*03ce13f7SAndroid Build Coastguard Worker 			{
254*03ce13f7SAndroid Build Coastguard Worker 				// Renderpass uses multiview if this structure is present AND some subpass specifies
255*03ce13f7SAndroid Build Coastguard Worker 				// a nonzero view mask
256*03ce13f7SAndroid Build Coastguard Worker 				const auto *multiviewCreateInfo = reinterpret_cast<const VkRenderPassMultiviewCreateInfo *>(extensionCreateInfo);
257*03ce13f7SAndroid Build Coastguard Worker 				for(auto i = 0u; i < pCreateInfo->subpassCount; i++)
258*03ce13f7SAndroid Build Coastguard Worker 				{
259*03ce13f7SAndroid Build Coastguard Worker 					masks[i] = multiviewCreateInfo->pViewMasks[i];
260*03ce13f7SAndroid Build Coastguard Worker 					// This is now a multiview renderpass, so make the masks available
261*03ce13f7SAndroid Build Coastguard Worker 					if(masks[i])
262*03ce13f7SAndroid Build Coastguard Worker 					{
263*03ce13f7SAndroid Build Coastguard Worker 						viewMasks = masks;
264*03ce13f7SAndroid Build Coastguard Worker 					}
265*03ce13f7SAndroid Build Coastguard Worker 				}
266*03ce13f7SAndroid Build Coastguard Worker 			}
267*03ce13f7SAndroid Build Coastguard Worker 			break;
268*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
269*03ce13f7SAndroid Build Coastguard Worker 			// VkRenderPassInputAttachmentAspectCreateInfo has already been handled in libvulkan.
270*03ce13f7SAndroid Build Coastguard Worker 			break;
271*03ce13f7SAndroid Build Coastguard Worker 		case VK_STRUCTURE_TYPE_MAX_ENUM:
272*03ce13f7SAndroid Build Coastguard Worker 			// dEQP tests that this value is ignored.
273*03ce13f7SAndroid Build Coastguard Worker 			break;
274*03ce13f7SAndroid Build Coastguard Worker 		default:
275*03ce13f7SAndroid Build Coastguard Worker 			UNSUPPORTED("pCreateInfo->pNext sType = %s", vk::Stringify(extensionCreateInfo->sType).c_str());
276*03ce13f7SAndroid Build Coastguard Worker 			break;
277*03ce13f7SAndroid Build Coastguard Worker 		}
278*03ce13f7SAndroid Build Coastguard Worker 
279*03ce13f7SAndroid Build Coastguard Worker 		extensionCreateInfo = extensionCreateInfo->pNext;
280*03ce13f7SAndroid Build Coastguard Worker 	}
281*03ce13f7SAndroid Build Coastguard Worker 
282*03ce13f7SAndroid Build Coastguard Worker 	if(!viewMasks && (GetViewMasks(pCreateInfo, masks)))
283*03ce13f7SAndroid Build Coastguard Worker 	{
284*03ce13f7SAndroid Build Coastguard Worker 		for(auto i = 0u; i < pCreateInfo->subpassCount; i++)
285*03ce13f7SAndroid Build Coastguard Worker 		{
286*03ce13f7SAndroid Build Coastguard Worker 			if(masks[i])
287*03ce13f7SAndroid Build Coastguard Worker 			{
288*03ce13f7SAndroid Build Coastguard Worker 				viewMasks = masks;
289*03ce13f7SAndroid Build Coastguard Worker 			}
290*03ce13f7SAndroid Build Coastguard Worker 		}
291*03ce13f7SAndroid Build Coastguard Worker 	}
292*03ce13f7SAndroid Build Coastguard Worker 
293*03ce13f7SAndroid Build Coastguard Worker 	// Deep copy subpasses
294*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
295*03ce13f7SAndroid Build Coastguard Worker 	{
296*03ce13f7SAndroid Build Coastguard Worker 		const auto &subpass = pCreateInfo->pSubpasses[i];
297*03ce13f7SAndroid Build Coastguard Worker 
298*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.inputAttachmentCount > 0)
299*03ce13f7SAndroid Build Coastguard Worker 		{
300*03ce13f7SAndroid Build Coastguard Worker 			size_t inputAttachmentsSize = subpass.inputAttachmentCount * sizeof(VkAttachmentReference);
301*03ce13f7SAndroid Build Coastguard Worker 			subpasses[i].pInputAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
302*03ce13f7SAndroid Build Coastguard Worker 			CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pInputAttachments),
303*03ce13f7SAndroid Build Coastguard Worker 			                         pCreateInfo->pSubpasses[i].pInputAttachments, subpass.inputAttachmentCount);
304*03ce13f7SAndroid Build Coastguard Worker 			hostMemory += inputAttachmentsSize;
305*03ce13f7SAndroid Build Coastguard Worker 
306*03ce13f7SAndroid Build Coastguard Worker 			for(auto j = 0u; j < subpasses[i].inputAttachmentCount; j++)
307*03ce13f7SAndroid Build Coastguard Worker 			{
308*03ce13f7SAndroid Build Coastguard Worker 				if(subpass.pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
309*03ce13f7SAndroid Build Coastguard Worker 					MarkFirstUse(subpass.pInputAttachments[j].attachment, i);
310*03ce13f7SAndroid Build Coastguard Worker 			}
311*03ce13f7SAndroid Build Coastguard Worker 		}
312*03ce13f7SAndroid Build Coastguard Worker 
313*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.colorAttachmentCount > 0)
314*03ce13f7SAndroid Build Coastguard Worker 		{
315*03ce13f7SAndroid Build Coastguard Worker 			size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference);
316*03ce13f7SAndroid Build Coastguard Worker 			subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
317*03ce13f7SAndroid Build Coastguard Worker 			CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pColorAttachments),
318*03ce13f7SAndroid Build Coastguard Worker 			                         subpass.pColorAttachments, subpass.colorAttachmentCount);
319*03ce13f7SAndroid Build Coastguard Worker 			hostMemory += colorAttachmentsSize;
320*03ce13f7SAndroid Build Coastguard Worker 
321*03ce13f7SAndroid Build Coastguard Worker 			if(subpass.pResolveAttachments)
322*03ce13f7SAndroid Build Coastguard Worker 			{
323*03ce13f7SAndroid Build Coastguard Worker 				subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference *>(hostMemory);
324*03ce13f7SAndroid Build Coastguard Worker 				CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pResolveAttachments),
325*03ce13f7SAndroid Build Coastguard Worker 				                         subpass.pResolveAttachments, subpass.colorAttachmentCount);
326*03ce13f7SAndroid Build Coastguard Worker 				hostMemory += colorAttachmentsSize;
327*03ce13f7SAndroid Build Coastguard Worker 			}
328*03ce13f7SAndroid Build Coastguard Worker 
329*03ce13f7SAndroid Build Coastguard Worker 			for(auto j = 0u; j < subpasses[i].colorAttachmentCount; j++)
330*03ce13f7SAndroid Build Coastguard Worker 			{
331*03ce13f7SAndroid Build Coastguard Worker 				if(subpass.pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
332*03ce13f7SAndroid Build Coastguard Worker 					MarkFirstUse(subpass.pColorAttachments[j].attachment, i);
333*03ce13f7SAndroid Build Coastguard Worker 				if(subpass.pResolveAttachments &&
334*03ce13f7SAndroid Build Coastguard Worker 				   subpass.pResolveAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
335*03ce13f7SAndroid Build Coastguard Worker 					MarkFirstUse(subpass.pResolveAttachments[j].attachment, i);
336*03ce13f7SAndroid Build Coastguard Worker 			}
337*03ce13f7SAndroid Build Coastguard Worker 		}
338*03ce13f7SAndroid Build Coastguard Worker 
339*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.pDepthStencilAttachment)
340*03ce13f7SAndroid Build Coastguard Worker 		{
341*03ce13f7SAndroid Build Coastguard Worker 			subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference *>(hostMemory);
342*03ce13f7SAndroid Build Coastguard Worker 			CopyAttachmentReferences(const_cast<VkAttachmentReference *>(subpasses[i].pDepthStencilAttachment),
343*03ce13f7SAndroid Build Coastguard Worker 			                         subpass.pDepthStencilAttachment, 1);
344*03ce13f7SAndroid Build Coastguard Worker 			hostMemory += sizeof(VkAttachmentReference);
345*03ce13f7SAndroid Build Coastguard Worker 
346*03ce13f7SAndroid Build Coastguard Worker 			if(subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED)
347*03ce13f7SAndroid Build Coastguard Worker 				MarkFirstUse(subpass.pDepthStencilAttachment->attachment, i);
348*03ce13f7SAndroid Build Coastguard Worker 		}
349*03ce13f7SAndroid Build Coastguard Worker 
350*03ce13f7SAndroid Build Coastguard Worker 		if(subpass.preserveAttachmentCount > 0)
351*03ce13f7SAndroid Build Coastguard Worker 		{
352*03ce13f7SAndroid Build Coastguard Worker 			size_t preserveAttachmentSize = subpass.preserveAttachmentCount * sizeof(uint32_t);
353*03ce13f7SAndroid Build Coastguard Worker 			subpasses[i].pPreserveAttachments = reinterpret_cast<uint32_t *>(hostMemory);
354*03ce13f7SAndroid Build Coastguard Worker 			for(uint32_t j = 0u; j < subpass.preserveAttachmentCount; j++)
355*03ce13f7SAndroid Build Coastguard Worker 			{
356*03ce13f7SAndroid Build Coastguard Worker 				const_cast<uint32_t *>(subpasses[i].pPreserveAttachments)[j] = pCreateInfo->pSubpasses[i].pPreserveAttachments[j];
357*03ce13f7SAndroid Build Coastguard Worker 			}
358*03ce13f7SAndroid Build Coastguard Worker 			hostMemory += preserveAttachmentSize;
359*03ce13f7SAndroid Build Coastguard Worker 
360*03ce13f7SAndroid Build Coastguard Worker 			for(auto j = 0u; j < subpasses[i].preserveAttachmentCount; j++)
361*03ce13f7SAndroid Build Coastguard Worker 			{
362*03ce13f7SAndroid Build Coastguard Worker 				if(subpass.pPreserveAttachments[j] != VK_ATTACHMENT_UNUSED)
363*03ce13f7SAndroid Build Coastguard Worker 					MarkFirstUse(subpass.pPreserveAttachments[j], i);
364*03ce13f7SAndroid Build Coastguard Worker 			}
365*03ce13f7SAndroid Build Coastguard Worker 		}
366*03ce13f7SAndroid Build Coastguard Worker 	}
367*03ce13f7SAndroid Build Coastguard Worker 
368*03ce13f7SAndroid Build Coastguard Worker 	if(pCreateInfo->dependencyCount > 0)
369*03ce13f7SAndroid Build Coastguard Worker 	{
370*03ce13f7SAndroid Build Coastguard Worker 		dependencies = reinterpret_cast<VkSubpassDependency *>(hostMemory);
371*03ce13f7SAndroid Build Coastguard Worker 		CopySubpassDependencies(dependencies, pCreateInfo->pDependencies, pCreateInfo->dependencyCount);
372*03ce13f7SAndroid Build Coastguard Worker 		hostMemory += dependencyCount * sizeof(VkSubpassDependency);
373*03ce13f7SAndroid Build Coastguard Worker 	}
374*03ce13f7SAndroid Build Coastguard Worker 	*mem = hostMemory;
375*03ce13f7SAndroid Build Coastguard Worker }
376*03ce13f7SAndroid Build Coastguard Worker 
destroy(const VkAllocationCallbacks * pAllocator)377*03ce13f7SAndroid Build Coastguard Worker void RenderPass::destroy(const VkAllocationCallbacks *pAllocator)
378*03ce13f7SAndroid Build Coastguard Worker {
379*03ce13f7SAndroid Build Coastguard Worker 	vk::freeHostMemory(subpasses, pAllocator);  // attachments and dependencies are in the same allocation
380*03ce13f7SAndroid Build Coastguard Worker }
381*03ce13f7SAndroid Build Coastguard Worker 
ComputeRequiredAllocationSize(const VkRenderPassCreateInfo * pCreateInfo)382*03ce13f7SAndroid Build Coastguard Worker size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo *pCreateInfo)
383*03ce13f7SAndroid Build Coastguard Worker {
384*03ce13f7SAndroid Build Coastguard Worker 	return ComputeRequiredAllocationSizeT(pCreateInfo);
385*03ce13f7SAndroid Build Coastguard Worker }
386*03ce13f7SAndroid Build Coastguard Worker 
ComputeRequiredAllocationSize(const VkRenderPassCreateInfo2KHR * pCreateInfo)387*03ce13f7SAndroid Build Coastguard Worker size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo2KHR *pCreateInfo)
388*03ce13f7SAndroid Build Coastguard Worker {
389*03ce13f7SAndroid Build Coastguard Worker 	size_t requiredMemory = ComputeRequiredAllocationSizeT(pCreateInfo);
390*03ce13f7SAndroid Build Coastguard Worker 
391*03ce13f7SAndroid Build Coastguard Worker 	// Calculate the memory required to handle depth stencil resolves
392*03ce13f7SAndroid Build Coastguard Worker 	bool usesDSR = false;
393*03ce13f7SAndroid Build Coastguard Worker 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; i++)
394*03ce13f7SAndroid Build Coastguard Worker 	{
395*03ce13f7SAndroid Build Coastguard Worker 		const auto &subpass = pCreateInfo->pSubpasses[i];
396*03ce13f7SAndroid Build Coastguard Worker 		const VkBaseInStructure *extension = reinterpret_cast<const VkBaseInStructure *>(subpass.pNext);
397*03ce13f7SAndroid Build Coastguard Worker 		while(extension)
398*03ce13f7SAndroid Build Coastguard Worker 		{
399*03ce13f7SAndroid Build Coastguard Worker 			switch(extension->sType)
400*03ce13f7SAndroid Build Coastguard Worker 			{
401*03ce13f7SAndroid Build Coastguard Worker 			case VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE:
402*03ce13f7SAndroid Build Coastguard Worker 				{
403*03ce13f7SAndroid Build Coastguard Worker 					const auto *ext = reinterpret_cast<const VkSubpassDescriptionDepthStencilResolve *>(extension);
404*03ce13f7SAndroid Build Coastguard Worker 					if(ext->pDepthStencilResolveAttachment != nullptr && ext->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED)
405*03ce13f7SAndroid Build Coastguard Worker 					{
406*03ce13f7SAndroid Build Coastguard Worker 						if(!usesDSR)
407*03ce13f7SAndroid Build Coastguard Worker 						{
408*03ce13f7SAndroid Build Coastguard Worker 							// If any subpass uses DSR, then allocate a VkSubpassDescriptionDepthStencilResolve
409*03ce13f7SAndroid Build Coastguard Worker 							// for all subpasses. This allows us to index into our DSR structs using the subpass index.
410*03ce13f7SAndroid Build Coastguard Worker 							//
411*03ce13f7SAndroid Build Coastguard Worker 							// Add a few bytes for alignment if necessary
412*03ce13f7SAndroid Build Coastguard Worker 							requiredMemory += sizeof(VkSubpassDescriptionDepthStencilResolve) * pCreateInfo->subpassCount + alignof(VkSubpassDescriptionDepthStencilResolve);
413*03ce13f7SAndroid Build Coastguard Worker 							usesDSR = true;
414*03ce13f7SAndroid Build Coastguard Worker 						}
415*03ce13f7SAndroid Build Coastguard Worker 						// For each subpass that actually uses DSR, allocate a VkAttachmentReference2.
416*03ce13f7SAndroid Build Coastguard Worker 						requiredMemory += sizeof(VkAttachmentReference2);
417*03ce13f7SAndroid Build Coastguard Worker 					}
418*03ce13f7SAndroid Build Coastguard Worker 				}
419*03ce13f7SAndroid Build Coastguard Worker 				break;
420*03ce13f7SAndroid Build Coastguard Worker 			default:
421*03ce13f7SAndroid Build Coastguard Worker 				UNSUPPORTED("VkRenderPassCreateInfo2KHR->subpass[%d]->pNext sType: %s",
422*03ce13f7SAndroid Build Coastguard Worker 				            i, vk::Stringify(extension->sType).c_str());
423*03ce13f7SAndroid Build Coastguard Worker 				break;
424*03ce13f7SAndroid Build Coastguard Worker 			}
425*03ce13f7SAndroid Build Coastguard Worker 
426*03ce13f7SAndroid Build Coastguard Worker 			extension = extension->pNext;
427*03ce13f7SAndroid Build Coastguard Worker 		}
428*03ce13f7SAndroid Build Coastguard Worker 	}
429*03ce13f7SAndroid Build Coastguard Worker 
430*03ce13f7SAndroid Build Coastguard Worker 	return requiredMemory;
431*03ce13f7SAndroid Build Coastguard Worker }
432*03ce13f7SAndroid Build Coastguard Worker 
getRenderAreaGranularity(VkExtent2D * pGranularity) const433*03ce13f7SAndroid Build Coastguard Worker void RenderPass::getRenderAreaGranularity(VkExtent2D *pGranularity) const
434*03ce13f7SAndroid Build Coastguard Worker {
435*03ce13f7SAndroid Build Coastguard Worker 	pGranularity->width = 1;
436*03ce13f7SAndroid Build Coastguard Worker 	pGranularity->height = 1;
437*03ce13f7SAndroid Build Coastguard Worker }
438*03ce13f7SAndroid Build Coastguard Worker 
MarkFirstUse(int attachment,int subpass)439*03ce13f7SAndroid Build Coastguard Worker void RenderPass::MarkFirstUse(int attachment, int subpass)
440*03ce13f7SAndroid Build Coastguard Worker {
441*03ce13f7SAndroid Build Coastguard Worker 	// FIXME: we may not actually need to track attachmentFirstUse if we're going to eagerly
442*03ce13f7SAndroid Build Coastguard Worker 	//  clear attachments at the start of the renderpass; can use attachmentViewMasks always instead.
443*03ce13f7SAndroid Build Coastguard Worker 
444*03ce13f7SAndroid Build Coastguard Worker 	if(attachmentFirstUse[attachment] == -1)
445*03ce13f7SAndroid Build Coastguard Worker 		attachmentFirstUse[attachment] = subpass;
446*03ce13f7SAndroid Build Coastguard Worker 
447*03ce13f7SAndroid Build Coastguard Worker 	if(isMultiView())
448*03ce13f7SAndroid Build Coastguard Worker 		attachmentViewMasks[attachment] |= viewMasks[subpass];
449*03ce13f7SAndroid Build Coastguard Worker }
450*03ce13f7SAndroid Build Coastguard Worker 
451*03ce13f7SAndroid Build Coastguard Worker }  // namespace vk
452