xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_context.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
3  * The term “Broadcom” refers to Broadcom Inc.
4  * and/or its subsidiaries.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "svga_cmd.h"
9 
10 #include "pipe/p_defines.h"
11 #include "util/u_inlines.h"
12 #include "pipe/p_screen.h"
13 #include "util/u_memory.h"
14 #include "util/u_bitmask.h"
15 #include "util/u_upload_mgr.h"
16 
17 #include "svga_context.h"
18 #include "svga_screen.h"
19 #include "svga_surface.h"
20 #include "svga_resource_texture.h"
21 #include "svga_resource_buffer.h"
22 #include "svga_resource.h"
23 #include "svga_winsys.h"
24 #include "svga_swtnl.h"
25 #include "svga_draw.h"
26 #include "svga_debug.h"
27 #include "svga_state.h"
28 #include "svga_winsys.h"
29 #include "svga_streamout.h"
30 
31 #define CONST0_UPLOAD_DEFAULT_SIZE 65536
32 
33 DEBUG_GET_ONCE_BOOL_OPTION(no_swtnl, "SVGA_NO_SWTNL", false)
34 DEBUG_GET_ONCE_BOOL_OPTION(force_swtnl, "SVGA_FORCE_SWTNL", false);
35 DEBUG_GET_ONCE_BOOL_OPTION(use_min_mipmap, "SVGA_USE_MIN_MIPMAP", false);
36 DEBUG_GET_ONCE_BOOL_OPTION(no_line_width, "SVGA_NO_LINE_WIDTH", false);
37 DEBUG_GET_ONCE_BOOL_OPTION(force_hw_line_stipple, "SVGA_FORCE_HW_LINE_STIPPLE", false);
38 
39 
40 static void
svga_destroy(struct pipe_context * pipe)41 svga_destroy(struct pipe_context *pipe)
42 {
43    struct svga_context *svga = svga_context(pipe);
44    unsigned shader, i;
45 
46    /* free depthstencil_disable state */
47    if (svga->depthstencil_disable) {
48       pipe->delete_depth_stencil_alpha_state(pipe, svga->depthstencil_disable);
49    }
50 
51    /* free HW constant buffers */
52    for (shader = 0; shader < ARRAY_SIZE(svga->state.hw_draw.constbuf); shader++) {
53       for (i = 0; i < ARRAY_SIZE(svga->state.hw_draw.constbuf[0]); i++) {
54          pipe_resource_reference(&svga->state.hw_draw.constbuf[shader][i], NULL);
55       }
56    }
57 
58    pipe->delete_blend_state(pipe, svga->noop_blend);
59 
60    /* destroy stream output statistics queries */
61    svga_destroy_stream_output_queries(svga);
62 
63    /* free query gb object */
64    if (svga->gb_query) {
65       pipe->destroy_query(pipe, NULL);
66       svga->gb_query = NULL;
67    }
68 
69    util_blitter_destroy(svga->blitter);
70 
71    svga_cleanup_sampler_state(svga);
72    svga_cleanup_framebuffer(svga);
73    svga_cleanup_tss_binding(svga);
74    svga_cleanup_vertex_state(svga);
75    svga_cleanup_tcs_state(svga);
76    svga_cleanup_shader_image_state(svga);
77 
78    svga_destroy_swtnl(svga);
79    svga_hwtnl_destroy(svga->hwtnl);
80 
81    svga->swc->destroy(svga->swc);
82 
83    util_bitmask_destroy(svga->blend_object_id_bm);
84    util_bitmask_destroy(svga->ds_object_id_bm);
85    util_bitmask_destroy(svga->input_element_object_id_bm);
86    util_bitmask_destroy(svga->rast_object_id_bm);
87    util_bitmask_destroy(svga->sampler_object_id_bm);
88    util_bitmask_destroy(svga->sampler_view_id_bm);
89    util_bitmask_destroy(svga->shader_id_bm);
90    util_bitmask_destroy(svga->surface_view_id_bm);
91    util_bitmask_destroy(svga->stream_output_id_bm);
92    util_bitmask_destroy(svga->query_id_bm);
93    util_bitmask_destroy(svga->uav_id_bm);
94    util_bitmask_destroy(svga->uav_to_free_id_bm);
95 
96    u_upload_destroy(svga->const0_upload);
97    u_upload_destroy(svga->pipe.stream_uploader);
98    u_upload_destroy(svga->pipe.const_uploader);
99    svga_texture_transfer_map_upload_destroy(svga);
100 
101    /* free user's constant buffers */
102    for (shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
103       for (i = 0; i < ARRAY_SIZE(svga->curr.constbufs[shader]); ++i) {
104          pipe_resource_reference(&svga->curr.constbufs[shader][i].buffer, NULL);
105       }
106    }
107 
108    /* free any pending srvs that were created for rawbuf sr view for
109     * constant buf.
110     */
111    if (svga_have_gl43(svga)) {
112       svga_destroy_rawbuf_srv(svga);
113       util_bitmask_destroy(svga->sampler_view_to_free_id_bm);
114       pipe_resource_reference(&svga->dummy_resource, NULL);
115    }
116 
117    FREE(svga);
118 }
119 
120 
121 struct pipe_context *
svga_context_create(struct pipe_screen * screen,void * priv,unsigned flags)122 svga_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
123 {
124    struct svga_screen *svgascreen = svga_screen(screen);
125    struct svga_context *svga = NULL;
126    enum pipe_error ret;
127 
128    SVGA_STATS_TIME_PUSH(svgascreen->sws, SVGA_STATS_TIME_CREATECONTEXT);
129 
130    svga = CALLOC_STRUCT(svga_context);
131    if (!svga)
132       goto done;
133 
134    list_inithead(&svga->dirty_buffers);
135 
136    svga->pipe.screen = screen;
137    svga->pipe.priv = priv;
138    svga->pipe.destroy = svga_destroy;
139    svga->pipe.stream_uploader = u_upload_create(&svga->pipe, 1024 * 1024,
140                                                 PIPE_BIND_VERTEX_BUFFER |
141                                                 PIPE_BIND_INDEX_BUFFER,
142                                                 PIPE_USAGE_STREAM, 0);
143    if (!svga->pipe.stream_uploader)
144       goto cleanup;
145 
146    u_upload_disable_persistent(svga->pipe.stream_uploader);
147 
148    svga->pipe.const_uploader = u_upload_create(&svga->pipe, 128 * 1024,
149                                                PIPE_BIND_CONSTANT_BUFFER,
150                                                PIPE_USAGE_STREAM, 0);
151    if (!svga->pipe.const_uploader)
152       goto cleanup;
153 
154    u_upload_disable_persistent(svga->pipe.const_uploader);
155 
156    svga->swc = svgascreen->sws->context_create(svgascreen->sws);
157    if (!svga->swc)
158       goto cleanup;
159 
160    svga_init_resource_functions(svga);
161    svga_init_blend_functions(svga);
162    svga_init_blit_functions(svga);
163    svga_init_depth_stencil_functions(svga);
164    svga_init_draw_functions(svga);
165    svga_init_flush_functions(svga);
166    svga_init_misc_functions(svga);
167    svga_init_rasterizer_functions(svga);
168    svga_init_sampler_functions(svga);
169    svga_init_fs_functions(svga);
170    svga_init_vs_functions(svga);
171    svga_init_gs_functions(svga);
172    svga_init_ts_functions(svga);
173    svga_init_vertex_functions(svga);
174    svga_init_constbuffer_functions(svga);
175    svga_init_query_functions(svga);
176    svga_init_surface_functions(svga);
177    svga_init_stream_output_functions(svga);
178    svga_init_clear_functions(svga);
179    svga_init_tracked_state(svga);
180    svga_init_shader_image_functions(svga);
181    svga_init_shader_buffer_functions(svga);
182    svga_init_cs_functions(svga);
183 
184    /* init misc state */
185    svga->curr.sample_mask = ~0;
186 
187    /* debug */
188    svga->debug.no_swtnl = debug_get_option_no_swtnl();
189    svga->debug.force_swtnl = debug_get_option_force_swtnl();
190    svga->debug.use_min_mipmap = debug_get_option_use_min_mipmap();
191    svga->debug.no_line_width = debug_get_option_no_line_width();
192    svga->debug.force_hw_line_stipple = debug_get_option_force_hw_line_stipple();
193 
194    if (!(svga->blend_object_id_bm = util_bitmask_create()))
195       goto cleanup;
196 
197    if (!(svga->ds_object_id_bm = util_bitmask_create()))
198       goto cleanup;
199 
200    if (!(svga->input_element_object_id_bm = util_bitmask_create()))
201       goto cleanup;
202 
203    if (!(svga->rast_object_id_bm = util_bitmask_create()))
204       goto cleanup;
205 
206    if (!(svga->sampler_object_id_bm = util_bitmask_create()))
207       goto cleanup;
208 
209    if (!(svga->sampler_view_id_bm = util_bitmask_create()))
210       goto cleanup;
211 
212    if (!(svga->shader_id_bm = util_bitmask_create()))
213       goto cleanup;
214 
215    if (!(svga->surface_view_id_bm = util_bitmask_create()))
216       goto cleanup;
217 
218    if (!(svga->stream_output_id_bm = util_bitmask_create()))
219       goto cleanup;
220 
221    if (!(svga->query_id_bm = util_bitmask_create()))
222       goto cleanup;
223 
224    if (!(svga->uav_id_bm = util_bitmask_create()))
225       goto cleanup;
226 
227    if (!(svga->uav_to_free_id_bm = util_bitmask_create()))
228       goto cleanup;
229 
230    if (!(svga->sampler_view_to_free_id_bm = util_bitmask_create()))
231       goto cleanup;
232 
233    svga->hwtnl = svga_hwtnl_create(svga);
234    if (svga->hwtnl == NULL)
235       goto cleanup;
236 
237    if (!svga_init_swtnl(svga))
238       goto cleanup;
239 
240    ret = svga_emit_initial_state(svga);
241    if (ret != PIPE_OK)
242       goto cleanup;
243 
244    svga->const0_upload = u_upload_create(&svga->pipe,
245                                          CONST0_UPLOAD_DEFAULT_SIZE,
246                                          PIPE_BIND_CONSTANT_BUFFER |
247                                          PIPE_BIND_CUSTOM,
248                                          PIPE_USAGE_STREAM, 0);
249    if (!svga->const0_upload)
250       goto cleanup;
251 
252    u_upload_disable_persistent(svga->const0_upload);
253 
254    if (!svga_texture_transfer_map_upload_create(svga))
255       goto cleanup;
256 
257    /* Avoid shortcircuiting state with initial value of zero.
258     */
259    memset(&svga->state.hw_clear, 0xcd, sizeof(svga->state.hw_clear));
260    memset(&svga->state.hw_clear.framebuffer, 0x0,
261           sizeof(svga->state.hw_clear.framebuffer));
262    memset(&svga->state.hw_clear.rtv, 0, sizeof(svga->state.hw_clear.rtv));
263    svga->state.hw_clear.num_rendertargets = 0;
264    svga->state.hw_clear.dsv = NULL;
265 
266    memset(&svga->state.hw_draw, 0xcd, sizeof(svga->state.hw_draw));
267    memset(&svga->state.hw_draw.views, 0x0, sizeof(svga->state.hw_draw.views));
268    memset(&svga->state.hw_draw.num_samplers, 0,
269       sizeof(svga->state.hw_draw.num_samplers));
270    memset(&svga->state.hw_draw.num_sampler_views, 0,
271       sizeof(svga->state.hw_draw.num_sampler_views));
272    memset(svga->state.hw_draw.sampler_views, 0,
273           sizeof(svga->state.hw_draw.sampler_views));
274    svga->state.hw_draw.num_views = 0;
275    svga->state.hw_draw.num_backed_views = 0;
276    svga->state.hw_draw.rasterizer_discard = false;
277 
278    /* Initialize uavs */
279    svga->state.hw_draw.uavSpliceIndex = -1;
280    svga->state.hw_draw.num_uavs = 0;
281    svga->state.hw_draw.num_cs_uavs = 0;
282 
283    /* Initialize the shader pointers */
284    svga->state.hw_draw.vs = NULL;
285    svga->state.hw_draw.gs = NULL;
286    svga->state.hw_draw.fs = NULL;
287    svga->state.hw_draw.tcs = NULL;
288    svga->state.hw_draw.tes = NULL;
289 
290    /* Initialize the currently bound buffer resources */
291    memset(svga->state.hw_draw.constbuf, 0,
292           sizeof(svga->state.hw_draw.constbuf));
293    memset(svga->state.hw_draw.default_constbuf_size, 0,
294           sizeof(svga->state.hw_draw.default_constbuf_size));
295    memset(svga->state.hw_draw.enabled_constbufs, 0,
296           sizeof(svga->state.hw_draw.enabled_constbufs));
297    memset(svga->state.hw_draw.enabled_rawbufs, 0,
298           sizeof(svga->state.hw_draw.enabled_rawbufs));
299    memset(svga->state.hw_draw.enabled_raw_shaderbufs, 0,
300           sizeof(svga->state.hw_draw.enabled_raw_shaderbufs));
301    memset(svga->state.hw_draw.rawbufs, 0,
302           sizeof(svga->state.hw_draw.rawbufs));
303    svga->state.hw_draw.ib = NULL;
304    svga->state.hw_draw.num_vbuffers = 0;
305    memset(svga->state.hw_draw.vbuffers, 0,
306           sizeof(svga->state.hw_draw.vbuffers));
307    svga->state.hw_draw.const0_buffer = NULL;
308    svga->state.hw_draw.const0_handle = NULL;
309 
310    if (svga_have_gl43(svga)) {
311       for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
312          for (unsigned i = 0;
313               i < ARRAY_SIZE(svga->state.hw_draw.rawbufs[shader]); i++) {
314             svga->state.hw_draw.rawbufs[shader][i].srvid = SVGA3D_INVALID_ID;
315          }
316       }
317       svga_uav_cache_init(svga);
318       svga->dummy_resource = NULL;
319    }
320 
321    /* Create a no-operation blend state which we will bind whenever the
322     * requested blend state is impossible (e.g. due to having an integer
323     * render target attached).
324     *
325     * XXX: We will probably actually need 16 of these, one for each possible
326     * RGBA color mask (4 bits).  Then, we would bind the one with a color mask
327     * matching the blend state it is replacing.
328     */
329    {
330       struct pipe_blend_state noop_tmpl = {0};
331       unsigned i;
332 
333       for (i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
334          // Set the color mask to all-ones.  Later this may change.
335          noop_tmpl.rt[i].colormask = PIPE_MASK_RGBA;
336       }
337       svga->noop_blend = svga->pipe.create_blend_state(&svga->pipe, &noop_tmpl);
338    }
339 
340    svga->dirty = SVGA_NEW_ALL;
341    svga->pred.query_id = SVGA3D_INVALID_ID;
342    svga->disable_rasterizer = false;
343 
344    /**
345     * Create stream output statistics queries used in the workaround for auto
346     * draw with stream instancing.
347     */
348    svga_create_stream_output_queries(svga);
349 
350    goto done;
351 
352 cleanup:
353    svga_destroy_swtnl(svga);
354 
355    if (svga->const0_upload)
356       u_upload_destroy(svga->const0_upload);
357    if (svga->pipe.const_uploader)
358       u_upload_destroy(svga->pipe.const_uploader);
359    if (svga->pipe.stream_uploader)
360       u_upload_destroy(svga->pipe.stream_uploader);
361    svga_texture_transfer_map_upload_destroy(svga);
362    if (svga->hwtnl)
363       svga_hwtnl_destroy(svga->hwtnl);
364    if (svga->swc)
365       svga->swc->destroy(svga->swc);
366    util_bitmask_destroy(svga->blend_object_id_bm);
367    util_bitmask_destroy(svga->ds_object_id_bm);
368    util_bitmask_destroy(svga->input_element_object_id_bm);
369    util_bitmask_destroy(svga->rast_object_id_bm);
370    util_bitmask_destroy(svga->sampler_object_id_bm);
371    util_bitmask_destroy(svga->shader_id_bm);
372    util_bitmask_destroy(svga->surface_view_id_bm);
373    util_bitmask_destroy(svga->stream_output_id_bm);
374    util_bitmask_destroy(svga->query_id_bm);
375 
376    util_bitmask_destroy(svga->uav_id_bm);
377    util_bitmask_destroy(svga->uav_to_free_id_bm);
378    util_bitmask_destroy(svga->sampler_view_id_bm);
379 
380    FREE(svga);
381    svga = NULL;
382 
383 done:
384    SVGA_STATS_TIME_POP(svgascreen->sws);
385    return svga ? &svga->pipe:NULL;
386 }
387 
388 
389 void
svga_context_flush(struct svga_context * svga,struct pipe_fence_handle ** pfence)390 svga_context_flush(struct svga_context *svga,
391                    struct pipe_fence_handle **pfence)
392 {
393    struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
394    struct pipe_fence_handle *fence = NULL;
395    uint64_t t0;
396 
397    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFLUSH);
398 
399    svga->curr.nr_fbs = 0;
400 
401    /* Unmap the 0th/default constant buffer.  The u_upload_unmap() function
402     * will call pipe_context::transfer_flush_region() to indicate the
403     * region of the buffer which was modified (and needs to be uploaded).
404     */
405    if (svga->state.hw_draw.const0_handle) {
406       assert(svga->state.hw_draw.const0_buffer);
407       u_upload_unmap(svga->const0_upload);
408       pipe_resource_reference(&svga->state.hw_draw.const0_buffer, NULL);
409       svga->state.hw_draw.const0_handle = NULL;
410    }
411 
412    /* Ensure that texture dma uploads are processed
413     * before submitting commands.
414     */
415    svga_context_flush_buffers(svga);
416 
417    svga->hud.command_buffer_size +=
418       svga->swc->get_command_buffer_size(svga->swc);
419 
420    /* Flush pending commands to hardware:
421     */
422    t0 = svga_get_time(svga);
423    svga->swc->flush(svga->swc, &fence);
424    svga->hud.flush_time += (svga_get_time(svga) - t0);
425 
426    svga->hud.num_flushes++;
427 
428    svga_screen_cache_flush(svgascreen, svga, fence);
429 
430    SVGA3D_ResetLastCommand(svga->swc);
431 
432    /* To force the re-emission of rendertargets and texture sampler bindings on
433     * the next command buffer.
434     */
435    svga->rebind.flags.rendertargets = true;
436    svga->rebind.flags.texture_samplers = true;
437 
438    if (svga_have_gb_objects(svga)) {
439 
440       svga->rebind.flags.constbufs = true;
441       svga->rebind.flags.vs = true;
442       svga->rebind.flags.fs = true;
443       svga->rebind.flags.gs = true;
444 
445       if (svga_have_sm5(svga)) {
446          svga->rebind.flags.tcs = true;
447          svga->rebind.flags.tes = true;
448       }
449 
450       if (svga_need_to_rebind_resources(svga)) {
451          svga->rebind.flags.query = true;
452       }
453 
454       if (svga_sws(svga)->have_index_vertex_buffer_offset_cmd) {
455          svga->rebind.flags.vertexbufs = true;
456          svga->rebind.flags.indexbuf = true;
457       }
458    }
459 
460    if (SVGA_DEBUG & DEBUG_SYNC) {
461       if (fence)
462          svga->pipe.screen->fence_finish(svga->pipe.screen, NULL, fence,
463                                           OS_TIMEOUT_INFINITE);
464    }
465 
466    if (pfence)
467       svgascreen->sws->fence_reference(svgascreen->sws, pfence, fence);
468 
469    svgascreen->sws->fence_reference(svgascreen->sws, &fence, NULL);
470 
471    SVGA_STATS_TIME_POP(svga_sws(svga));
472 }
473 
474 
475 /**
476  * Flush pending commands and wait for completion with a fence.
477  */
478 void
svga_context_finish(struct svga_context * svga)479 svga_context_finish(struct svga_context *svga)
480 {
481    struct pipe_screen *screen = svga->pipe.screen;
482    struct pipe_fence_handle *fence = NULL;
483 
484    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CONTEXTFINISH);
485 
486    svga_context_flush(svga, &fence);
487    screen->fence_finish(screen, NULL, fence, OS_TIMEOUT_INFINITE);
488    screen->fence_reference(screen, &fence, NULL);
489 
490    SVGA_STATS_TIME_POP(svga_sws(svga));
491 }
492 
493 
494 /**
495  * Emit pending drawing commands to the command buffer.
496  * If the command buffer overflows, we flush it and retry.
497  * \sa svga_hwtnl_flush()
498  */
499 void
svga_hwtnl_flush_retry(struct svga_context * svga)500 svga_hwtnl_flush_retry(struct svga_context *svga)
501 {
502    enum pipe_error ret = PIPE_OK;
503 
504    SVGA_RETRY_OOM(svga, ret, svga_hwtnl_flush(svga->hwtnl));
505    assert(ret == PIPE_OK);
506 }
507 
508 
509 /**
510  * Flush the primitive queue if this buffer is referred.
511  *
512  * Otherwise DMA commands on the referred buffer will be emitted too late.
513  */
514 void
svga_hwtnl_flush_buffer(struct svga_context * svga,struct pipe_resource * buffer)515 svga_hwtnl_flush_buffer(struct svga_context *svga,
516                         struct pipe_resource *buffer)
517 {
518    if (svga_hwtnl_is_buffer_referred(svga->hwtnl, buffer)) {
519       svga_hwtnl_flush_retry(svga);
520    }
521 }
522 
523 
524 /**
525  * Emit all operations pending on host surfaces.
526  */
527 void
svga_surfaces_flush(struct svga_context * svga)528 svga_surfaces_flush(struct svga_context *svga)
529 {
530    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_SURFACEFLUSH);
531 
532    /* Emit buffered drawing commands.
533     */
534    svga_hwtnl_flush_retry(svga);
535 
536    /* Emit back-copy from render target views to textures.
537     */
538    svga_propagate_rendertargets(svga);
539 
540    SVGA_STATS_TIME_POP(svga_sws(svga));
541 }
542 
543 
544 struct svga_winsys_context *
svga_winsys_context(struct pipe_context * pipe)545 svga_winsys_context(struct pipe_context *pipe)
546 {
547    return svga_context(pipe)->swc;
548 }
549