OSDN Git Service

Implement indirect draws
[android-x86/external-swiftshader.git] / src / Vulkan / VkRenderPass.cpp
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
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
106 void RenderPass::destroy(const VkAllocationCallbacks* pAllocator)
107 {
108         vk::deallocate(subpasses, pAllocator); // attachments and dependencies are in the same allocation
109 }
110
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
136 void RenderPass::getRenderAreaGranularity(VkExtent2D* pGranularity) const\r
137 {\r
138         pGranularity->width = 1;\r
139         pGranularity->height = 1;\r
140 }\r
141
142 void RenderPass::begin()
143 {
144         currentSubpass = 0;
145 }
146
147 void RenderPass::nextSubpass()
148 {
149         ++currentSubpass;
150         ASSERT(currentSubpass < subpassCount);
151 }
152
153 void RenderPass::end()
154 {
155         currentSubpass = 0;
156 }
157
158 } // namespace vk