Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/frontends/lavapipe/lvp_pass.c
4565 views
1
/*
2
* Copyright © 2019 Red Hat.
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 "lvp_private.h"
25
26
#include "vk_util.h"
27
28
static void
29
lvp_render_pass_compile(struct lvp_render_pass *pass)
30
{
31
for (uint32_t i = 0; i < pass->subpass_count; i++) {
32
struct lvp_subpass *subpass = &pass->subpasses[i];
33
34
for (uint32_t j = 0; j < subpass->attachment_count; j++) {
35
struct lvp_subpass_attachment *subpass_att =
36
&subpass->attachments[j];
37
if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
38
continue;
39
40
struct lvp_render_pass_attachment *pass_att =
41
&pass->attachments[subpass_att->attachment];
42
43
pass_att->first_subpass_idx = UINT32_MAX;
44
}
45
}
46
47
for (uint32_t i = 0; i < pass->subpass_count; i++) {
48
struct lvp_subpass *subpass = &pass->subpasses[i];
49
uint32_t color_sample_count = 1, depth_sample_count = 1;
50
51
/* We don't allow depth_stencil_attachment to be non-NULL and
52
* be VK_ATTACHMENT_UNUSED. This way something can just check
53
* for NULL and be guaranteed that they have a valid
54
* attachment.
55
*/
56
if (subpass->depth_stencil_attachment &&
57
subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
58
subpass->depth_stencil_attachment = NULL;
59
60
if (subpass->ds_resolve_attachment &&
61
subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)
62
subpass->ds_resolve_attachment = NULL;
63
64
for (uint32_t j = 0; j < subpass->attachment_count; j++) {
65
struct lvp_subpass_attachment *subpass_att =
66
&subpass->attachments[j];
67
if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
68
continue;
69
70
struct lvp_render_pass_attachment *pass_att =
71
&pass->attachments[subpass_att->attachment];
72
73
if (i < pass_att->first_subpass_idx)
74
pass_att->first_subpass_idx = i;
75
pass_att->last_subpass_idx = i;
76
}
77
78
subpass->has_color_att = false;
79
for (uint32_t j = 0; j < subpass->color_count; j++) {
80
struct lvp_subpass_attachment *subpass_att =
81
&subpass->color_attachments[j];
82
if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
83
continue;
84
85
subpass->has_color_att = true;
86
87
struct lvp_render_pass_attachment *pass_att =
88
&pass->attachments[subpass_att->attachment];
89
90
color_sample_count = pass_att->samples;
91
}
92
93
if (subpass->depth_stencil_attachment) {
94
const uint32_t a =
95
subpass->depth_stencil_attachment->attachment;
96
struct lvp_render_pass_attachment *pass_att =
97
&pass->attachments[a];
98
depth_sample_count = pass_att->samples;
99
}
100
101
subpass->max_sample_count = MAX2(color_sample_count,
102
depth_sample_count);
103
104
/* We have to handle resolve attachments specially */
105
subpass->has_color_resolve = false;
106
if (subpass->resolve_attachments) {
107
for (uint32_t j = 0; j < subpass->color_count; j++) {
108
struct lvp_subpass_attachment *resolve_att =
109
&subpass->resolve_attachments[j];
110
111
if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
112
continue;
113
114
subpass->has_color_resolve = true;
115
}
116
}
117
118
for (uint32_t j = 0; j < subpass->input_count; ++j) {
119
if (subpass->input_attachments[j].attachment == VK_ATTACHMENT_UNUSED)
120
continue;
121
122
for (uint32_t k = 0; k < subpass->color_count; ++k) {
123
if (subpass->color_attachments[k].attachment == subpass->input_attachments[j].attachment) {
124
subpass->input_attachments[j].in_render_loop = true;
125
subpass->color_attachments[k].in_render_loop = true;
126
}
127
}
128
129
if (subpass->depth_stencil_attachment &&
130
subpass->depth_stencil_attachment->attachment == subpass->input_attachments[j].attachment) {
131
subpass->input_attachments[j].in_render_loop = true;
132
subpass->depth_stencil_attachment->in_render_loop = true;
133
}
134
}
135
}
136
}
137
138
static unsigned
139
lvp_num_subpass_attachments2(const VkSubpassDescription2 *desc)
140
{
141
return desc->inputAttachmentCount +
142
desc->colorAttachmentCount +
143
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
144
(desc->pDepthStencilAttachment != NULL);
145
}
146
147
VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateRenderPass2(
148
VkDevice _device,
149
const VkRenderPassCreateInfo2* pCreateInfo,
150
const VkAllocationCallbacks* pAllocator,
151
VkRenderPass* pRenderPass)
152
{
153
LVP_FROM_HANDLE(lvp_device, device, _device);
154
struct lvp_render_pass *pass;
155
size_t attachments_offset;
156
size_t size;
157
158
size = sizeof(*pass);
159
size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
160
attachments_offset = size;
161
size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
162
163
pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
164
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
165
if (pass == NULL)
166
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
167
168
/* Clear the subpasses along with the parent pass. This required because
169
* each array member of lvp_subpass must be a valid pointer if not NULL.
170
*/
171
memset(pass, 0, size);
172
173
vk_object_base_init(&device->vk, &pass->base,
174
VK_OBJECT_TYPE_RENDER_PASS);
175
pass->attachment_count = pCreateInfo->attachmentCount;
176
pass->subpass_count = pCreateInfo->subpassCount;
177
pass->attachments = (struct lvp_render_pass_attachment *)((char *)pass + attachments_offset);
178
179
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
180
struct lvp_render_pass_attachment *att = &pass->attachments[i];
181
182
att->format = pCreateInfo->pAttachments[i].format;
183
att->samples = pCreateInfo->pAttachments[i].samples;
184
att->load_op = pCreateInfo->pAttachments[i].loadOp;
185
att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
186
att->final_layout = pCreateInfo->pAttachments[i].finalLayout;
187
att->first_subpass_idx = UINT32_MAX;
188
189
bool is_zs = util_format_is_depth_or_stencil(lvp_vk_format_to_pipe_format(att->format));
190
pass->has_zs_attachment |= is_zs;
191
pass->has_color_attachment |= !is_zs;
192
}
193
uint32_t subpass_attachment_count = 0;
194
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
195
subpass_attachment_count += lvp_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
196
}
197
198
if (subpass_attachment_count) {
199
pass->subpass_attachments =
200
vk_alloc2(&device->vk.alloc, pAllocator,
201
subpass_attachment_count * sizeof(struct lvp_subpass_attachment), 8,
202
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
203
if (pass->subpass_attachments == NULL) {
204
vk_free2(&device->vk.alloc, pAllocator, pass);
205
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
206
}
207
} else
208
pass->subpass_attachments = NULL;
209
210
struct lvp_subpass_attachment *p = pass->subpass_attachments;
211
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
212
const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i];
213
struct lvp_subpass *subpass = &pass->subpasses[i];
214
215
subpass->input_count = desc->inputAttachmentCount;
216
subpass->color_count = desc->colorAttachmentCount;
217
subpass->attachment_count = lvp_num_subpass_attachments2(desc);
218
subpass->attachments = p;
219
subpass->view_mask = desc->viewMask;
220
221
if (desc->inputAttachmentCount > 0) {
222
subpass->input_attachments = p;
223
p += desc->inputAttachmentCount;
224
225
for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
226
subpass->input_attachments[j] = (struct lvp_subpass_attachment) {
227
.attachment = desc->pInputAttachments[j].attachment,
228
.layout = desc->pInputAttachments[j].layout,
229
};
230
}
231
}
232
233
if (desc->colorAttachmentCount > 0) {
234
subpass->color_attachments = p;
235
p += desc->colorAttachmentCount;
236
237
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
238
subpass->color_attachments[j] = (struct lvp_subpass_attachment) {
239
.attachment = desc->pColorAttachments[j].attachment,
240
.layout = desc->pColorAttachments[j].layout,
241
};
242
}
243
}
244
245
if (desc->pResolveAttachments) {
246
subpass->resolve_attachments = p;
247
p += desc->colorAttachmentCount;
248
249
for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
250
subpass->resolve_attachments[j] = (struct lvp_subpass_attachment) {
251
.attachment = desc->pResolveAttachments[j].attachment,
252
.layout = desc->pResolveAttachments[j].layout,
253
};
254
}
255
}
256
257
if (desc->pDepthStencilAttachment) {
258
subpass->depth_stencil_attachment = p++;
259
260
*subpass->depth_stencil_attachment = (struct lvp_subpass_attachment) {
261
.attachment = desc->pDepthStencilAttachment->attachment,
262
.layout = desc->pDepthStencilAttachment->layout,
263
};
264
}
265
}
266
267
lvp_render_pass_compile(pass);
268
*pRenderPass = lvp_render_pass_to_handle(pass);
269
270
return VK_SUCCESS;
271
}
272
273
VKAPI_ATTR void VKAPI_CALL lvp_DestroyRenderPass(
274
VkDevice _device,
275
VkRenderPass _pass,
276
const VkAllocationCallbacks* pAllocator)
277
{
278
LVP_FROM_HANDLE(lvp_device, device, _device);
279
LVP_FROM_HANDLE(lvp_render_pass, pass, _pass);
280
281
if (!_pass)
282
return;
283
vk_object_base_finish(&pass->base);
284
vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments);
285
vk_free2(&device->vk.alloc, pAllocator, pass);
286
}
287
288
VKAPI_ATTR void VKAPI_CALL lvp_GetRenderAreaGranularity(
289
VkDevice device,
290
VkRenderPass renderPass,
291
VkExtent2D* pGranularity)
292
{
293
*pGranularity = (VkExtent2D) { 1, 1 };
294
}
295
296