xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/svga/svga_pipe_cs.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (c) 2022-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 "compiler/nir/nir.h"
9 #include "compiler/glsl/gl_nir.h"
10 #include "nir/nir_to_tgsi.h"
11 
12 #include "util/u_inlines.h"
13 #include "util/u_memory.h"
14 #include "util/u_bitmask.h"
15 #include "tgsi/tgsi_parse.h"
16 
17 #include "svga_context.h"
18 #include "svga_cmd.h"
19 #include "svga_debug.h"
20 #include "svga_shader.h"
21 #include "svga_streamout.h"
22 #include "svga_resource_buffer.h"
23 #include "svga_tgsi.h"
24 
25 /**
26  * Create the compute program.
27  */
28 static void *
svga_create_compute_state(struct pipe_context * pipe,const struct pipe_compute_state * templ)29 svga_create_compute_state(struct pipe_context *pipe,
30                           const struct pipe_compute_state *templ)
31 {
32    struct svga_context *svga = svga_context(pipe);
33 
34    struct svga_compute_shader *cs = CALLOC_STRUCT(svga_compute_shader);
35    nir_shader *nir = (nir_shader *)templ->prog;
36 
37    if (!cs)
38       return NULL;
39 
40    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATECS);
41 
42    assert(templ->ir_type == PIPE_SHADER_IR_NIR);
43    /* nir_to_tgsi requires lowered images */
44    NIR_PASS_V(nir, gl_nir_lower_images, false);
45 
46    cs->base.tokens = nir_to_tgsi((void *)nir, pipe->screen);
47 
48    struct svga_shader *shader = &cs->base;
49    shader->id = svga->debug.shader_id++;
50    shader->type = PIPE_SHADER_IR_TGSI;
51    shader->stage = PIPE_SHADER_COMPUTE;
52 
53    /* Collect shader basic info */
54    svga_tgsi_scan_shader(&cs->base);
55 
56    cs->shared_mem_size = templ->static_shared_mem;
57 
58    SVGA_STATS_TIME_POP(svga_sws(svga));
59    return cs;
60 }
61 
62 
63 /**
64  * Bind the compute program.
65  */
66 static void
svga_bind_compute_state(struct pipe_context * pipe,void * shader)67 svga_bind_compute_state(struct pipe_context *pipe, void *shader)
68 {
69    struct svga_context *svga = svga_context(pipe);
70    struct svga_compute_shader *cs = (struct svga_compute_shader *)shader;
71 
72    svga->curr.cs = cs;
73    svga->dirty |= SVGA_NEW_CS;
74 
75    /* Check if the shader uses samplers */
76    svga_set_curr_shader_use_samplers_flag(svga, PIPE_SHADER_COMPUTE,
77                                           svga_shader_use_samplers(&cs->base));
78 }
79 
80 
81 /**
82  * Delete the compute program.
83  */
84 static void
svga_delete_compute_state(struct pipe_context * pipe,void * shader)85 svga_delete_compute_state(struct pipe_context *pipe, void *shader)
86 {
87    struct svga_context *svga = svga_context(pipe);
88    struct svga_compute_shader *cs = (struct svga_compute_shader *)shader;
89    struct svga_compute_shader *next_cs;
90    struct svga_shader_variant *variant, *tmp;
91 
92    svga_hwtnl_flush_retry(svga);
93 
94    /* Free the list of compute shaders */
95    while (cs) {
96       next_cs = (struct svga_compute_shader *)cs->base.next;
97 
98       for (variant = cs->base.variants; variant; variant = tmp) {
99          tmp = variant->next;
100 
101          /* Check if deleting currently bound shader */
102          if (variant == svga->state.hw_draw.cs) {
103             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, NULL));
104             svga->state.hw_draw.cs = NULL;
105          }
106 
107          svga_destroy_shader_variant(svga, variant);
108       }
109 
110       FREE((void *)cs->base.tokens);
111       FREE(cs);
112       cs = next_cs;
113    }
114 }
115 
116 
117 /**
118  * Bind an array of shader resources that will be used by the
119  * compute program.  Any resources that were previously bound to
120  * the specified range will be unbound after this call.
121  */
122 static void
svga_set_compute_resources(struct pipe_context * pipe,unsigned start,unsigned count,struct pipe_surface ** resources)123 svga_set_compute_resources(struct pipe_context *pipe,
124                            unsigned start, unsigned count,
125                            struct pipe_surface **resources)
126 {
127    //TODO
128    return;
129 }
130 
131 
132 /**
133  * Bind an array of buffers to be mapped into the address space of
134  * the GLOBAL resource.  Any buffers that were previously bound
135  * between [first, first + count - 1] are unbound after this call.
136  */
137 static void
svga_set_global_binding(struct pipe_context * pipe,unsigned first,unsigned count,struct pipe_resource ** resources,uint32_t ** handles)138 svga_set_global_binding(struct pipe_context *pipe,
139                         unsigned first, unsigned count,
140                         struct pipe_resource **resources,
141                         uint32_t **handles)
142 {
143    //TODO
144    return;
145 }
146 
147 
148 /**
149  */
150 static void
svga_validate_compute_resources(struct svga_context * svga)151 svga_validate_compute_resources(struct svga_context *svga)
152 {
153    /* validate sampler view resources */
154    SVGA_RETRY(svga,
155               svga_validate_sampler_resources(svga, SVGA_PIPE_COMPUTE));
156 
157    /* validate constant buffer resources */
158    SVGA_RETRY(svga,
159               svga_validate_constant_buffers(svga, SVGA_PIPE_COMPUTE));
160 
161    /* validate image view resources */
162    SVGA_RETRY(svga,
163               svga_validate_image_views(svga, SVGA_PIPE_COMPUTE));
164 
165    /* validate shader buffer resources */
166    SVGA_RETRY(svga,
167               svga_validate_shader_buffers(svga, SVGA_PIPE_COMPUTE));
168 }
169 
170 
171 /**
172  * Launch the compute kernel starting from instruction pc of the
173  * currently bound compute program.
174  */
175 static void
svga_launch_grid(struct pipe_context * pipe,const struct pipe_grid_info * info)176 svga_launch_grid(struct pipe_context *pipe,
177                  const struct pipe_grid_info *info)
178 {
179    struct svga_context *svga = svga_context(pipe);
180    struct svga_winsys_context *swc = svga->swc;
181 
182    assert(svga_have_gl43(svga));
183 
184    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_LAUNCHGRID);
185 
186    if (info->indirect) {
187       svga->curr.grid_info.indirect= info->indirect;
188    }
189 
190    svga_update_compute_state(svga);
191 
192    /* validate compute resources */
193    svga_validate_compute_resources(svga);
194 
195    if (info->indirect) {
196       struct svga_winsys_surface *indirect_surf;
197       indirect_surf = svga_buffer_handle(svga, info->indirect,
198                                          PIPE_BIND_COMMAND_ARGS_BUFFER);
199       SVGA_RETRY(svga, SVGA3D_sm5_DispatchIndirect(swc, indirect_surf,
200                                                    info->indirect_offset));
201    }
202    else {
203       svga->curr.grid_info.size[0] = info->grid[0];
204       svga->curr.grid_info.size[1] = info->grid[1];
205       svga->curr.grid_info.size[2] = info->grid[2];
206 
207       SVGA_RETRY(svga, SVGA3D_sm5_Dispatch(swc, info->grid));
208    }
209 
210    SVGA_STATS_TIME_POP(svga_sws(svga));
211    return;
212 }
213 
214 
215 /**
216  * Initialize the compute interface function pointers.
217  */
218 void
svga_init_cs_functions(struct svga_context * svga)219 svga_init_cs_functions(struct svga_context *svga)
220 {
221    svga->pipe.create_compute_state = svga_create_compute_state;
222    svga->pipe.bind_compute_state = svga_bind_compute_state;
223    svga->pipe.delete_compute_state = svga_delete_compute_state;
224    svga->pipe.set_compute_resources = svga_set_compute_resources;
225    svga->pipe.set_global_binding = svga_set_global_binding;
226    svga->pipe.launch_grid = svga_launch_grid;
227 }
228