xref: /aosp_15_r20/external/mesa3d/src/nouveau/vulkan/nvk_cmd_meta.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Collabora Ltd. and Red Hat Inc.
3  * SPDX-License-Identifier: MIT
4  */
5 #include "nvk_buffer.h"
6 #include "nvk_cmd_buffer.h"
7 #include "nvk_descriptor_set.h"
8 #include "nvk_device.h"
9 #include "nvk_entrypoints.h"
10 #include "nvk_image.h"
11 #include "nvk_physical_device.h"
12 
13 #include "nv_push_cl9097.h"
14 #include "nv_push_clb197.h"
15 
16 static VkResult
nvk_cmd_bind_map_buffer(struct vk_command_buffer * vk_cmd,struct vk_meta_device * meta,VkBuffer _buffer,void ** map_out)17 nvk_cmd_bind_map_buffer(struct vk_command_buffer *vk_cmd,
18                         struct vk_meta_device *meta,
19                         VkBuffer _buffer, void **map_out)
20 {
21    struct nvk_cmd_buffer *cmd =
22       container_of(vk_cmd, struct nvk_cmd_buffer, vk);
23    VK_FROM_HANDLE(nvk_buffer, buffer, _buffer);
24    VkResult result;
25 
26    uint64_t addr;
27    assert(buffer->vk.size < UINT_MAX);
28    result = nvk_cmd_buffer_upload_alloc(cmd, buffer->vk.size, 16,
29                                         &addr, map_out);
30    if (unlikely(result != VK_SUCCESS))
31       return result;
32 
33    buffer->addr = addr;
34 
35    return VK_SUCCESS;
36 }
37 
38 VkResult
nvk_device_init_meta(struct nvk_device * dev)39 nvk_device_init_meta(struct nvk_device *dev)
40 {
41    struct nvk_physical_device *pdev = nvk_device_physical(dev);
42 
43    VkResult result = vk_meta_device_init(&dev->vk, &dev->meta);
44    if (result != VK_SUCCESS)
45       return result;
46 
47    dev->meta.use_gs_for_layer = pdev->info.cls_eng3d < MAXWELL_B,
48    dev->meta.cmd_bind_map_buffer = nvk_cmd_bind_map_buffer;
49    dev->meta.max_bind_map_buffer_size_B = 64 * 1024; /* TODO */
50 
51    return VK_SUCCESS;
52 }
53 
54 void
nvk_device_finish_meta(struct nvk_device * dev)55 nvk_device_finish_meta(struct nvk_device *dev)
56 {
57    vk_meta_device_finish(&dev->vk, &dev->meta);
58 }
59 
60 struct nvk_meta_save {
61    struct vk_vertex_input_state _dynamic_vi;
62    struct vk_sample_locations_state _dynamic_sl;
63    struct vk_dynamic_graphics_state dynamic;
64    struct nvk_shader *shaders[MESA_SHADER_MESH + 1];
65    struct nvk_addr_range vb0;
66    struct nvk_descriptor_set_binding desc0;
67    struct nvk_buffer_address desc0_set_addr;
68    struct nvk_push_descriptor_set push_desc0;
69    uint8_t set_dynamic_buffer_start[NVK_MAX_SETS];
70    uint8_t push[NVK_MAX_PUSH_SIZE];
71 };
72 
73 static void
nvk_meta_begin(struct nvk_cmd_buffer * cmd,struct nvk_meta_save * save)74 nvk_meta_begin(struct nvk_cmd_buffer *cmd,
75                struct nvk_meta_save *save)
76 {
77    const struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors;
78 
79    save->dynamic = cmd->vk.dynamic_graphics_state;
80    save->_dynamic_vi = cmd->state.gfx._dynamic_vi;
81    save->_dynamic_sl = cmd->state.gfx._dynamic_sl;
82 
83    STATIC_ASSERT(sizeof(cmd->state.gfx.shaders) == sizeof(save->shaders));
84    memcpy(save->shaders, cmd->state.gfx.shaders, sizeof(save->shaders));
85 
86    save->vb0 = cmd->state.gfx.vb0;
87 
88    save->desc0 = desc->sets[0];
89    nvk_descriptor_state_get_root(desc, sets[0], &save->desc0_set_addr);
90    if (desc->sets[0].push != NULL)
91       save->push_desc0 = *desc->sets[0].push;
92 
93    nvk_descriptor_state_get_root_array(desc, set_dynamic_buffer_start,
94                                        0, NVK_MAX_SETS,
95                                        save->set_dynamic_buffer_start);
96    nvk_descriptor_state_get_root_array(desc, push, 0, NVK_MAX_PUSH_SIZE,
97                                        save->push);
98 
99    struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
100    P_IMMD(p, NV9097, SET_STATISTICS_COUNTER, {
101       .da_vertices_generated_enable = false,
102       .da_primitives_generated_enable = false,
103       .vs_invocations_enable = false,
104       .gs_invocations_enable = false,
105       .gs_primitives_generated_enable = false,
106       .streaming_primitives_succeeded_enable = false,
107       .streaming_primitives_needed_enable = false,
108       .clipper_invocations_enable = false,
109       .clipper_primitives_generated_enable = false,
110       .ps_invocations_enable = false,
111       .ti_invocations_enable = false,
112       .ts_invocations_enable = false,
113       .ts_primitives_generated_enable = false,
114       .total_streaming_primitives_needed_succeeded_enable = false,
115       .vtg_primitives_out_enable = false,
116    });
117 }
118 
119 static void
nvk_meta_init_render(struct nvk_cmd_buffer * cmd,struct vk_meta_rendering_info * info)120 nvk_meta_init_render(struct nvk_cmd_buffer *cmd,
121                      struct vk_meta_rendering_info *info)
122 {
123    const struct nvk_rendering_state *render = &cmd->state.gfx.render;
124 
125    *info = (struct vk_meta_rendering_info) {
126       .view_mask = render->view_mask,
127       .color_attachment_count = render->color_att_count,
128       .depth_attachment_format = render->depth_att.vk_format,
129       .stencil_attachment_format = render->stencil_att.vk_format,
130    };
131    for (uint32_t a = 0; a < render->color_att_count; a++) {
132       info->color_attachment_formats[a] = render->color_att[a].vk_format;
133       info->color_attachment_write_masks[a] =
134          VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
135          VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
136    }
137 }
138 
139 static void
nvk_meta_end(struct nvk_cmd_buffer * cmd,struct nvk_meta_save * save)140 nvk_meta_end(struct nvk_cmd_buffer *cmd,
141              struct nvk_meta_save *save)
142 {
143    struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors;
144 
145    switch (save->desc0.type) {
146    case NVK_DESCRIPTOR_SET_TYPE_NONE:
147       desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_NONE;
148       break;
149 
150    case NVK_DESCRIPTOR_SET_TYPE_SET: {
151       desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_SET;
152       desc->sets[0].set = save->desc0.set;
153       struct nvk_buffer_address addr = nvk_descriptor_set_addr(save->desc0.set);
154       nvk_descriptor_state_set_root(cmd, desc, sets[0], addr);
155       break;
156    }
157 
158    case NVK_DESCRIPTOR_SET_TYPE_PUSH:
159       desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_PUSH;
160       desc->sets[0].set = NULL;
161       *desc->sets[0].push = save->push_desc0;
162       desc->push_dirty |= BITFIELD_BIT(0);
163       break;
164 
165    case NVK_DESCRIPTOR_SET_TYPE_BUFFER:
166       desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_BUFFER;
167       desc->sets[0].set = NULL;
168       nvk_descriptor_state_set_root(cmd, desc, sets[0], save->desc0_set_addr);
169       break;
170 
171    default:
172       unreachable("Unknown descriptor set type");
173    }
174    nvk_cmd_dirty_cbufs_for_descriptors(cmd, ~0, 0, 1, 0, 0);
175 
176    /* Restore set_dynaic_buffer_start because meta binding set 0 can disturb
177     * all dynamic buffers starts for all sets.
178     */
179    nvk_descriptor_state_set_root_array(cmd, desc, set_dynamic_buffer_start,
180                                        0, NVK_MAX_SETS,
181                                        save->set_dynamic_buffer_start);
182 
183    /* Restore the dynamic state */
184    assert(save->dynamic.vi == &cmd->state.gfx._dynamic_vi);
185    assert(save->dynamic.ms.sample_locations == &cmd->state.gfx._dynamic_sl);
186    cmd->vk.dynamic_graphics_state = save->dynamic;
187    cmd->state.gfx._dynamic_vi = save->_dynamic_vi;
188    cmd->state.gfx._dynamic_sl = save->_dynamic_sl;
189    memcpy(cmd->vk.dynamic_graphics_state.dirty,
190           cmd->vk.dynamic_graphics_state.set,
191           sizeof(cmd->vk.dynamic_graphics_state.set));
192 
193    for (uint32_t stage = 0; stage < ARRAY_SIZE(save->shaders); stage++) {
194       if (stage == MESA_SHADER_COMPUTE)
195          continue;
196 
197       nvk_cmd_bind_graphics_shader(cmd, stage, save->shaders[stage]);
198    }
199 
200    nvk_cmd_bind_vertex_buffer(cmd, 0, save->vb0);
201 
202    nvk_descriptor_state_set_root_array(cmd, desc, push, 0, sizeof(save->push),
203                                        save->push);
204 
205    struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
206    P_IMMD(p, NV9097, SET_STATISTICS_COUNTER, {
207       .da_vertices_generated_enable = true,
208       .da_primitives_generated_enable = true,
209       .vs_invocations_enable = true,
210       .gs_invocations_enable = true,
211       .gs_primitives_generated_enable = true,
212       .streaming_primitives_succeeded_enable = true,
213       .streaming_primitives_needed_enable = true,
214       .clipper_invocations_enable = true,
215       .clipper_primitives_generated_enable = true,
216       .ps_invocations_enable = true,
217       .ti_invocations_enable = true,
218       .ts_invocations_enable = true,
219       .ts_primitives_generated_enable = true,
220       .total_streaming_primitives_needed_succeeded_enable = true,
221       .vtg_primitives_out_enable = true,
222    });
223 }
224 
225 VKAPI_ATTR void VKAPI_CALL
nvk_CmdBlitImage2(VkCommandBuffer commandBuffer,const VkBlitImageInfo2 * pBlitImageInfo)226 nvk_CmdBlitImage2(VkCommandBuffer commandBuffer,
227                   const VkBlitImageInfo2 *pBlitImageInfo)
228 {
229    VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
230    struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
231 
232    struct nvk_meta_save save;
233    nvk_meta_begin(cmd, &save);
234 
235    vk_meta_blit_image2(&cmd->vk, &dev->meta, pBlitImageInfo);
236 
237    nvk_meta_end(cmd, &save);
238 }
239 
240 VKAPI_ATTR void VKAPI_CALL
nvk_CmdResolveImage2(VkCommandBuffer commandBuffer,const VkResolveImageInfo2 * pResolveImageInfo)241 nvk_CmdResolveImage2(VkCommandBuffer commandBuffer,
242                      const VkResolveImageInfo2 *pResolveImageInfo)
243 {
244    VK_FROM_HANDLE(nvk_cmd_buffer, cmd, commandBuffer);
245    struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
246 
247    struct nvk_meta_save save;
248    nvk_meta_begin(cmd, &save);
249 
250    vk_meta_resolve_image2(&cmd->vk, &dev->meta, pResolveImageInfo);
251 
252    nvk_meta_end(cmd, &save);
253 }
254 
255 void
nvk_meta_resolve_rendering(struct nvk_cmd_buffer * cmd,const VkRenderingInfo * pRenderingInfo)256 nvk_meta_resolve_rendering(struct nvk_cmd_buffer *cmd,
257                            const VkRenderingInfo *pRenderingInfo)
258 {
259    struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
260 
261    struct nvk_meta_save save;
262    nvk_meta_begin(cmd, &save);
263 
264    vk_meta_resolve_rendering(&cmd->vk, &dev->meta, pRenderingInfo);
265 
266    nvk_meta_end(cmd, &save);
267 }
268