1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "VkRenderPass.hpp"
16 #include <cstring>
17 
18 namespace vk
19 {
20 
RenderPass(const VkRenderPassCreateInfo * pCreateInfo,void * mem)21 RenderPass::RenderPass(const VkRenderPassCreateInfo* pCreateInfo, void* mem) :
22 	attachmentCount(pCreateInfo->attachmentCount),
23 	subpassCount(pCreateInfo->subpassCount),
24 	dependencyCount(pCreateInfo->dependencyCount)
25 {
26 	char* hostMemory = reinterpret_cast<char*>(mem);
27 
28 	// subpassCount must be greater than 0
29 	ASSERT(pCreateInfo->subpassCount > 0);
30 
31 	size_t subpassesSize = pCreateInfo->subpassCount * sizeof(VkSubpassDescription);
32 	subpasses = reinterpret_cast<VkSubpassDescription*>(hostMemory);
33 	memcpy(subpasses, pCreateInfo->pSubpasses, subpassesSize);
34 	hostMemory += subpassesSize;
35 
36 	if(pCreateInfo->attachmentCount > 0)
37 	{
38 		size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription);
39 		attachments = reinterpret_cast<VkAttachmentDescription*>(hostMemory);
40 		memcpy(attachments, pCreateInfo->pAttachments, attachmentSize);
41 		hostMemory += attachmentSize;
42 	}
43 
44 	// Deep copy subpasses
45 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
46 	{
47 		const auto& subpass = pCreateInfo->pSubpasses[i];
48 		subpasses[i].pInputAttachments = nullptr;
49 		subpasses[i].pColorAttachments = nullptr;
50 		subpasses[i].pResolveAttachments = nullptr;
51 		subpasses[i].pDepthStencilAttachment = nullptr;
52 		subpasses[i].pPreserveAttachments = nullptr;
53 
54 		if(subpass.inputAttachmentCount > 0)
55 		{
56 			size_t inputAttachmentsSize = subpass.inputAttachmentCount * sizeof(VkAttachmentReference);
57 			subpasses[i].pInputAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory);
58 			memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pInputAttachments),
59 			       pCreateInfo->pSubpasses[i].pInputAttachments, inputAttachmentsSize);
60 			hostMemory += inputAttachmentsSize;
61 		}
62 
63 		if(subpass.colorAttachmentCount > 0)
64 		{
65 			size_t colorAttachmentsSize = subpass.colorAttachmentCount * sizeof(VkAttachmentReference);
66 			subpasses[i].pColorAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory);
67 			memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pColorAttachments),
68 			       pCreateInfo->pSubpasses[i].pColorAttachments, colorAttachmentsSize);
69 			hostMemory += colorAttachmentsSize;
70 
71 			if(subpass.pResolveAttachments != nullptr)
72 			{
73 				subpasses[i].pResolveAttachments = reinterpret_cast<VkAttachmentReference*>(hostMemory);
74 				memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pResolveAttachments),
75 				       pCreateInfo->pSubpasses[i].pResolveAttachments, colorAttachmentsSize);
76 				hostMemory += colorAttachmentsSize;
77 			}
78 		}
79 
80 		if(subpass.pDepthStencilAttachment != nullptr)
81 		{
82 			subpasses[i].pDepthStencilAttachment = reinterpret_cast<VkAttachmentReference*>(hostMemory);
83 			memcpy(const_cast<VkAttachmentReference*>(subpasses[i].pDepthStencilAttachment),
84 				pCreateInfo->pSubpasses[i].pDepthStencilAttachment, sizeof(VkAttachmentReference));
85 			hostMemory += sizeof(VkAttachmentReference);
86 		}
87 
88 		if(subpass.preserveAttachmentCount > 0)
89 		{
90 			size_t preserveAttachmentSize = subpass.preserveAttachmentCount * sizeof(uint32_t);
91 			subpasses[i].pPreserveAttachments = reinterpret_cast<uint32_t*>(hostMemory);
92 			memcpy(const_cast<uint32_t*>(subpasses[i].pPreserveAttachments),
93 			       pCreateInfo->pSubpasses[i].pPreserveAttachments, preserveAttachmentSize);
94 			hostMemory += preserveAttachmentSize;
95 		}
96 	}
97 
98 	if(pCreateInfo->dependencyCount > 0)
99 	{
100 		size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
101 		dependencies = reinterpret_cast<VkSubpassDependency*>(hostMemory);
102 		memcpy(dependencies, pCreateInfo->pDependencies, dependenciesSize);
103 	}
104 }
105 
destroy(const VkAllocationCallbacks * pAllocator)106 void RenderPass::destroy(const VkAllocationCallbacks* pAllocator)
107 {
108 	vk::deallocate(subpasses, pAllocator); // attachments and dependencies are in the same allocation
109 }
110 
ComputeRequiredAllocationSize(const VkRenderPassCreateInfo * pCreateInfo)111 size_t RenderPass::ComputeRequiredAllocationSize(const VkRenderPassCreateInfo* pCreateInfo)
112 {
113 	size_t attachmentSize = pCreateInfo->attachmentCount * sizeof(VkAttachmentDescription);
114 	size_t subpassesSize = 0;
115 	for(uint32_t i = 0; i < pCreateInfo->subpassCount; ++i)
116 	{
117 		const auto& subpass = pCreateInfo->pSubpasses[i];
118 		uint32_t nbAttachments = subpass.inputAttachmentCount + subpass.colorAttachmentCount;
119 		if(subpass.pResolveAttachments != nullptr)
120 		{
121 			nbAttachments += subpass.colorAttachmentCount;
122 		}
123 		if(subpass.pDepthStencilAttachment != nullptr)
124 		{
125 			nbAttachments += 1;
126 		}
127 		subpassesSize += sizeof(VkSubpassDescription) +
128 		                 sizeof(VkAttachmentReference) * nbAttachments +
129 		                 sizeof(uint32_t) * subpass.preserveAttachmentCount;
130 	}
131 	size_t dependenciesSize = pCreateInfo->dependencyCount * sizeof(VkSubpassDependency);
132 
133 	return attachmentSize + subpassesSize + dependenciesSize;
134 }
135 
begin()136 void RenderPass::begin()
137 {
138 	currentSubpass = 0;
139 }
140 
nextSubpass()141 void RenderPass::nextSubpass()
142 {
143 	++currentSubpass;
144 	ASSERT(currentSubpass < subpassCount);
145 }
146 
end()147 void RenderPass::end()
148 {
149 	currentSubpass = 0;
150 }
151 
152 } // namespace vk