Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/zink/zink_render_pass.c
4570 views
1
/*
2
* Copyright 2018 Collabora Ltd.
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
* on the rights to use, copy, modify, merge, publish, distribute, sub
8
* license, and/or sell copies of the Software, and to permit persons to whom
9
* the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
* USE OR OTHER DEALINGS IN THE SOFTWARE.
22
*/
23
24
#include "zink_render_pass.h"
25
26
#include "zink_screen.h"
27
28
#include "util/u_memory.h"
29
#include "util/u_string.h"
30
31
static VkRenderPass
32
create_render_pass(VkDevice dev, struct zink_render_pass_state *state)
33
{
34
35
VkAttachmentReference color_refs[PIPE_MAX_COLOR_BUFS], zs_ref;
36
VkAttachmentDescription attachments[PIPE_MAX_COLOR_BUFS + 1];
37
VkPipelineStageFlags dep_pipeline = 0;
38
VkAccessFlags dep_access = 0;
39
40
for (int i = 0; i < state->num_cbufs; i++) {
41
struct zink_rt_attrib *rt = state->rts + i;
42
attachments[i].flags = 0;
43
attachments[i].format = rt->format;
44
attachments[i].samples = rt->samples;
45
attachments[i].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR :
46
state->swapchain_init && rt->swapchain ?
47
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
48
VK_ATTACHMENT_LOAD_OP_LOAD;
49
attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
50
attachments[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
51
attachments[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
52
/* if layout changes are ever handled here, need VkAttachmentSampleLocationsEXT */
53
attachments[i].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
54
attachments[i].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
55
color_refs[i].attachment = i;
56
color_refs[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
57
dep_pipeline |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
58
dep_access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
59
if (attachments[i].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
60
dep_access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
61
}
62
63
int num_attachments = state->num_cbufs;
64
if (state->have_zsbuf) {
65
struct zink_rt_attrib *rt = state->rts + state->num_cbufs;
66
bool has_clear = rt->clear_color || rt->clear_stencil;
67
VkImageLayout layout = rt->needs_write || has_clear ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
68
attachments[num_attachments].flags = 0;
69
attachments[num_attachments].format = rt->format;
70
attachments[num_attachments].samples = rt->samples;
71
attachments[num_attachments].loadOp = rt->clear_color ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
72
attachments[num_attachments].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
73
attachments[num_attachments].stencilLoadOp = rt->clear_stencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
74
attachments[num_attachments].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
75
/* if layout changes are ever handled here, need VkAttachmentSampleLocationsEXT */
76
attachments[num_attachments].initialLayout = layout;
77
attachments[num_attachments].finalLayout = layout;
78
79
dep_pipeline |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
80
if (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
81
dep_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
82
if (attachments[num_attachments].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD ||
83
attachments[num_attachments].stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
84
dep_access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
85
86
zs_ref.attachment = num_attachments++;
87
zs_ref.layout = layout;
88
}
89
90
VkSubpassDependency deps[] = {
91
[0] = {VK_SUBPASS_EXTERNAL, 0, dep_pipeline, dep_pipeline, 0, dep_access, VK_DEPENDENCY_BY_REGION_BIT},
92
[1] = {0, VK_SUBPASS_EXTERNAL, dep_pipeline, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, dep_access, 0, VK_DEPENDENCY_BY_REGION_BIT}
93
};
94
95
VkSubpassDescription subpass = {0};
96
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
97
subpass.colorAttachmentCount = state->num_cbufs;
98
subpass.pColorAttachments = color_refs;
99
subpass.pDepthStencilAttachment = state->have_zsbuf ? &zs_ref : NULL;
100
101
VkRenderPassCreateInfo rpci = {0};
102
rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
103
rpci.attachmentCount = num_attachments;
104
rpci.pAttachments = attachments;
105
rpci.subpassCount = 1;
106
rpci.pSubpasses = &subpass;
107
rpci.dependencyCount = 2;
108
rpci.pDependencies = deps;
109
110
VkRenderPass render_pass;
111
if (vkCreateRenderPass(dev, &rpci, NULL, &render_pass) != VK_SUCCESS) {
112
debug_printf("vkCreateRenderPass failed\n");
113
return VK_NULL_HANDLE;
114
}
115
116
return render_pass;
117
}
118
119
struct zink_render_pass *
120
zink_create_render_pass(struct zink_screen *screen,
121
struct zink_render_pass_state *state)
122
{
123
struct zink_render_pass *rp = CALLOC_STRUCT(zink_render_pass);
124
if (!rp)
125
goto fail;
126
127
rp->render_pass = create_render_pass(screen->dev, state);
128
if (!rp->render_pass)
129
goto fail;
130
memcpy(&rp->state, state, sizeof(struct zink_render_pass_state));
131
return rp;
132
133
fail:
134
if (rp)
135
zink_destroy_render_pass(screen, rp);
136
return NULL;
137
}
138
139
void
140
zink_destroy_render_pass(struct zink_screen *screen,
141
struct zink_render_pass *rp)
142
{
143
vkDestroyRenderPass(screen->dev, rp->render_pass, NULL);
144
FREE(rp);
145
}
146
147
VkImageLayout
148
zink_render_pass_attachment_get_barrier_info(const struct zink_render_pass *rp, unsigned idx,
149
VkPipelineStageFlags *pipeline, VkAccessFlags *access)
150
{
151
*access = 0;
152
assert(idx < rp->state.num_rts);
153
const struct zink_rt_attrib *rt = &rp->state.rts[idx];
154
if (idx < rp->state.num_cbufs) {
155
*pipeline = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
156
*access |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
157
if (!rt->clear_color && (!rp->state.swapchain_init || !rt->swapchain))
158
*access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
159
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
160
}
161
162
assert(rp->state.have_zsbuf);
163
*pipeline = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
164
if (!rp->state.rts[idx].clear_color && !rp->state.rts[idx].clear_stencil)
165
*access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
166
if (!rp->state.rts[idx].clear_color && !rp->state.rts[idx].clear_stencil && !rp->state.rts[idx].needs_write)
167
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
168
*access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
169
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
170
}
171
172