Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/vulkan/util/vk_render_pass.c
7132 views
1
/*
2
* Copyright © 2020 Valve Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "vk_alloc.h"
25
#include "vk_common_entrypoints.h"
26
#include "vk_device.h"
27
#include "vk_format.h"
28
#include "vk_util.h"
29
30
#include "util/log.h"
31
32
static void
33
translate_references(VkAttachmentReference2 **reference_ptr,
34
uint32_t reference_count,
35
const VkAttachmentReference *reference,
36
const VkRenderPassCreateInfo *pass_info,
37
bool is_input_attachment)
38
{
39
VkAttachmentReference2 *reference2 = *reference_ptr;
40
*reference_ptr += reference_count;
41
for (uint32_t i = 0; i < reference_count; i++) {
42
reference2[i] = (VkAttachmentReference2) {
43
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
44
.pNext = NULL,
45
.attachment = reference[i].attachment,
46
.layout = reference[i].layout,
47
};
48
49
if (is_input_attachment &&
50
reference2[i].attachment != VK_ATTACHMENT_UNUSED) {
51
assert(reference2[i].attachment < pass_info->attachmentCount);
52
const VkAttachmentDescription *att =
53
&pass_info->pAttachments[reference2[i].attachment];
54
reference2[i].aspectMask = vk_format_aspects(att->format);
55
}
56
}
57
}
58
59
VKAPI_ATTR VkResult VKAPI_CALL
60
vk_common_CreateRenderPass(VkDevice _device,
61
const VkRenderPassCreateInfo *pCreateInfo,
62
const VkAllocationCallbacks *pAllocator,
63
VkRenderPass *pRenderPass)
64
{
65
VK_FROM_HANDLE(vk_device, device, _device);
66
67
uint32_t reference_count = 0;
68
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
69
reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount;
70
reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
71
if (pCreateInfo->pSubpasses[i].pResolveAttachments)
72
reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount;
73
if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment)
74
reference_count += 1;
75
}
76
77
VK_MULTIALLOC(ma);
78
VK_MULTIALLOC_DECL(&ma, VkRenderPassCreateInfo2, create_info, 1);
79
VK_MULTIALLOC_DECL(&ma, VkSubpassDescription2, subpasses,
80
pCreateInfo->subpassCount);
81
VK_MULTIALLOC_DECL(&ma, VkAttachmentDescription2, attachments,
82
pCreateInfo->attachmentCount);
83
VK_MULTIALLOC_DECL(&ma, VkSubpassDependency2, dependencies,
84
pCreateInfo->dependencyCount);
85
VK_MULTIALLOC_DECL(&ma, VkAttachmentReference2, references,
86
reference_count);
87
if (!vk_multialloc_alloc2(&ma, &device->alloc, pAllocator,
88
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND))
89
return VK_ERROR_OUT_OF_HOST_MEMORY;
90
91
VkAttachmentReference2 *reference_ptr = references;
92
93
const VkRenderPassMultiviewCreateInfo *multiview_info = NULL;
94
const VkRenderPassInputAttachmentAspectCreateInfo *aspect_info = NULL;
95
vk_foreach_struct(ext, pCreateInfo->pNext) {
96
switch (ext->sType) {
97
case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
98
aspect_info = (const VkRenderPassInputAttachmentAspectCreateInfo *)ext;
99
/* We don't care about this information */
100
break;
101
102
case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO:
103
multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext;
104
break;
105
106
default:
107
mesa_logd("%s: ignored VkStructureType %u\n", __func__, ext->sType);
108
break;
109
}
110
}
111
112
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
113
attachments[i] = (VkAttachmentDescription2) {
114
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
115
.pNext = NULL,
116
.flags = pCreateInfo->pAttachments[i].flags,
117
.format = pCreateInfo->pAttachments[i].format,
118
.samples = pCreateInfo->pAttachments[i].samples,
119
.loadOp = pCreateInfo->pAttachments[i].loadOp,
120
.storeOp = pCreateInfo->pAttachments[i].storeOp,
121
.stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp,
122
.stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp,
123
.initialLayout = pCreateInfo->pAttachments[i].initialLayout,
124
.finalLayout = pCreateInfo->pAttachments[i].finalLayout,
125
};
126
}
127
128
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
129
subpasses[i] = (VkSubpassDescription2) {
130
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
131
.pNext = NULL,
132
.flags = pCreateInfo->pSubpasses[i].flags,
133
.pipelineBindPoint = pCreateInfo->pSubpasses[i].pipelineBindPoint,
134
.viewMask = 0,
135
.inputAttachmentCount = pCreateInfo->pSubpasses[i].inputAttachmentCount,
136
.colorAttachmentCount = pCreateInfo->pSubpasses[i].colorAttachmentCount,
137
.preserveAttachmentCount = pCreateInfo->pSubpasses[i].preserveAttachmentCount,
138
.pPreserveAttachments = pCreateInfo->pSubpasses[i].pPreserveAttachments,
139
};
140
141
if (multiview_info && multiview_info->subpassCount) {
142
assert(multiview_info->subpassCount == pCreateInfo->subpassCount);
143
subpasses[i].viewMask = multiview_info->pViewMasks[i];
144
}
145
146
subpasses[i].pInputAttachments = reference_ptr;
147
translate_references(&reference_ptr,
148
subpasses[i].inputAttachmentCount,
149
pCreateInfo->pSubpasses[i].pInputAttachments,
150
pCreateInfo, true);
151
subpasses[i].pColorAttachments = reference_ptr;
152
translate_references(&reference_ptr,
153
subpasses[i].colorAttachmentCount,
154
pCreateInfo->pSubpasses[i].pColorAttachments,
155
pCreateInfo, false);
156
subpasses[i].pResolveAttachments = NULL;
157
if (pCreateInfo->pSubpasses[i].pResolveAttachments) {
158
subpasses[i].pResolveAttachments = reference_ptr;
159
translate_references(&reference_ptr,
160
subpasses[i].colorAttachmentCount,
161
pCreateInfo->pSubpasses[i].pResolveAttachments,
162
pCreateInfo, false);
163
}
164
subpasses[i].pDepthStencilAttachment = NULL;
165
if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) {
166
subpasses[i].pDepthStencilAttachment = reference_ptr;
167
translate_references(&reference_ptr, 1,
168
pCreateInfo->pSubpasses[i].pDepthStencilAttachment,
169
pCreateInfo, false);
170
}
171
}
172
173
assert(reference_ptr == references + reference_count);
174
175
if (aspect_info != NULL) {
176
for (uint32_t i = 0; i < aspect_info->aspectReferenceCount; i++) {
177
const VkInputAttachmentAspectReference *ref =
178
&aspect_info->pAspectReferences[i];
179
180
assert(ref->subpass < pCreateInfo->subpassCount);
181
VkSubpassDescription2 *subpass = &subpasses[ref->subpass];
182
183
assert(ref->inputAttachmentIndex < subpass->inputAttachmentCount);
184
VkAttachmentReference2 *att = (VkAttachmentReference2 *)
185
&subpass->pInputAttachments[ref->inputAttachmentIndex];
186
187
att->aspectMask = ref->aspectMask;
188
}
189
}
190
191
for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
192
dependencies[i] = (VkSubpassDependency2) {
193
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
194
.pNext = NULL,
195
.srcSubpass = pCreateInfo->pDependencies[i].srcSubpass,
196
.dstSubpass = pCreateInfo->pDependencies[i].dstSubpass,
197
.srcStageMask = pCreateInfo->pDependencies[i].srcStageMask,
198
.dstStageMask = pCreateInfo->pDependencies[i].dstStageMask,
199
.srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask,
200
.dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask,
201
.dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags,
202
.viewOffset = 0,
203
};
204
205
if (multiview_info && multiview_info->dependencyCount) {
206
assert(multiview_info->dependencyCount == pCreateInfo->dependencyCount);
207
dependencies[i].viewOffset = multiview_info->pViewOffsets[i];
208
}
209
}
210
211
*create_info = (VkRenderPassCreateInfo2) {
212
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
213
.pNext = pCreateInfo->pNext,
214
.flags = pCreateInfo->flags,
215
.attachmentCount = pCreateInfo->attachmentCount,
216
.pAttachments = attachments,
217
.subpassCount = pCreateInfo->subpassCount,
218
.pSubpasses = subpasses,
219
.dependencyCount = pCreateInfo->dependencyCount,
220
.pDependencies = dependencies,
221
};
222
223
if (multiview_info && multiview_info->correlationMaskCount > 0) {
224
create_info->correlatedViewMaskCount = multiview_info->correlationMaskCount;
225
create_info->pCorrelatedViewMasks = multiview_info->pCorrelationMasks;
226
}
227
228
VkResult result =
229
device->dispatch_table.CreateRenderPass2(_device, create_info,
230
pAllocator, pRenderPass);
231
232
vk_free2(&device->alloc, pAllocator, create_info);
233
234
return result;
235
}
236
237
VKAPI_ATTR void VKAPI_CALL
238
vk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
239
const VkRenderPassBeginInfo* pRenderPassBegin,
240
VkSubpassContents contents)
241
{
242
/* We don't have a vk_command_buffer object but we can assume, since we're
243
* using common dispatch, that it's a vk_object of some sort.
244
*/
245
struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
246
247
VkSubpassBeginInfo info = {
248
.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
249
.contents = contents,
250
};
251
252
disp->device->dispatch_table.CmdBeginRenderPass2(commandBuffer,
253
pRenderPassBegin, &info);
254
}
255
256
VKAPI_ATTR void VKAPI_CALL
257
vk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer)
258
{
259
/* We don't have a vk_command_buffer object but we can assume, since we're
260
* using common dispatch, that it's a vk_object of some sort.
261
*/
262
struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
263
264
VkSubpassEndInfo info = {
265
.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
266
};
267
268
disp->device->dispatch_table.CmdEndRenderPass2(commandBuffer, &info);
269
}
270
271
VKAPI_ATTR void VKAPI_CALL
272
vk_common_CmdNextSubpass(VkCommandBuffer commandBuffer,
273
VkSubpassContents contents)
274
{
275
/* We don't have a vk_command_buffer object but we can assume, since we're
276
* using common dispatch, that it's a vk_object of some sort.
277
*/
278
struct vk_object_base *disp = (struct vk_object_base *)commandBuffer;
279
280
VkSubpassBeginInfo begin_info = {
281
.sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO,
282
.contents = contents,
283
};
284
285
VkSubpassEndInfo end_info = {
286
.sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO,
287
};
288
289
disp->device->dispatch_table.CmdNextSubpass2(commandBuffer, &begin_info,
290
&end_info);
291
}
292
293