xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_pipe_gs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2014-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 "draw/draw_context.h"
9 #include "nir/nir_to_tgsi.h"
10 #include "util/u_inlines.h"
11 #include "util/u_memory.h"
12 #include "util/u_bitmask.h"
13 
14 #include "svga_context.h"
15 #include "svga_cmd.h"
16 #include "svga_debug.h"
17 #include "svga_shader.h"
18 #include "svga_streamout.h"
19 
20 static void *
svga_create_gs_state(struct pipe_context * pipe,const struct pipe_shader_state * templ)21 svga_create_gs_state(struct pipe_context *pipe,
22                      const struct pipe_shader_state *templ)
23 {
24    struct svga_context *svga = svga_context(pipe);
25    struct svga_geometry_shader *gs;
26 
27    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATEGS);
28 
29    gs = (struct svga_geometry_shader *)
30             svga_create_shader(pipe, templ, PIPE_SHADER_GEOMETRY,
31                                sizeof(struct svga_geometry_shader));
32 
33    if (!gs)
34       goto done;
35 
36    /* Original shader IR could have been deleted if it is converted from
37     * NIR to TGSI. So need to explicitly set the shader state type to TGSI
38     * before passing it to draw.
39     */
40    struct pipe_shader_state tmp = *templ;
41    tmp.type = PIPE_SHADER_IR_TGSI;
42    tmp.tokens = gs->base.tokens;
43 
44    gs->base.get_dummy_shader = svga_get_compiled_dummy_geometry_shader;
45    gs->draw_shader = draw_create_geometry_shader(svga->swtnl.draw, &tmp);
46 
47 done:
48    SVGA_STATS_TIME_POP(svga_sws(svga));
49    return gs;
50 }
51 
52 
53 static void
svga_bind_gs_state(struct pipe_context * pipe,void * shader)54 svga_bind_gs_state(struct pipe_context *pipe, void *shader)
55 {
56    struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
57    struct svga_context *svga = svga_context(pipe);
58 
59    svga->curr.user_gs = gs;
60    svga->dirty |= SVGA_NEW_GS;
61 
62    /* Check if the shader uses samplers */
63    svga_set_curr_shader_use_samplers_flag(svga, PIPE_SHADER_GEOMETRY,
64                                           svga_shader_use_samplers(&gs->base));
65 }
66 
67 
68 static void
svga_delete_gs_state(struct pipe_context * pipe,void * shader)69 svga_delete_gs_state(struct pipe_context *pipe, void *shader)
70 {
71    struct svga_context *svga = svga_context(pipe);
72    struct svga_geometry_shader *gs = (struct svga_geometry_shader *)shader;
73    struct svga_geometry_shader *next_gs;
74    struct svga_shader_variant *variant, *tmp;
75 
76    svga_hwtnl_flush_retry(svga);
77 
78    /* Start deletion from the original geometry shader state */
79    if (gs->base.parent != NULL)
80       gs = (struct svga_geometry_shader *)gs->base.parent;
81 
82    /* Free the list of geometry shaders */
83    while (gs) {
84       next_gs = (struct svga_geometry_shader *)gs->base.next;
85 
86       if (gs->base.stream_output != NULL)
87          svga_delete_stream_output(svga, gs->base.stream_output);
88 
89       draw_delete_geometry_shader(svga->swtnl.draw, gs->draw_shader);
90 
91       for (variant = gs->base.variants; variant; variant = tmp) {
92          tmp = variant->next;
93 
94          /* Check if deleting currently bound shader */
95          if (variant == svga->state.hw_draw.gs) {
96             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_GS, NULL));
97             svga->state.hw_draw.gs = NULL;
98          }
99 
100          svga_destroy_shader_variant(svga, variant);
101       }
102 
103       FREE((void *)gs->base.tokens);
104       FREE(gs);
105       gs = next_gs;
106    }
107 }
108 
109 
110 void
svga_init_gs_functions(struct svga_context * svga)111 svga_init_gs_functions(struct svga_context *svga)
112 {
113    svga->pipe.create_gs_state = svga_create_gs_state;
114    svga->pipe.bind_gs_state = svga_bind_gs_state;
115    svga->pipe.delete_gs_state = svga_delete_gs_state;
116 }
117