• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************
2  * Copyright 2022 VMware, Inc.  All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  **********************************************************/
25 
26 #include "nir/nir_to_tgsi.h"
27 #include "util/u_inlines.h"
28 #include "util/u_memory.h"
29 #include "util/u_bitmask.h"
30 #include "tgsi/tgsi_parse.h"
31 #include "tgsi/tgsi_text.h"
32 
33 #include "svga_context.h"
34 #include "svga_cmd.h"
35 #include "svga_debug.h"
36 #include "svga_shader.h"
37 #include "svga_streamout.h"
38 #include "svga_resource_buffer.h"
39 #include "svga_tgsi.h"
40 
41 /**
42  * Create the compute program.
43  */
44 static void *
svga_create_compute_state(struct pipe_context * pipe,const struct pipe_compute_state * templ)45 svga_create_compute_state(struct pipe_context *pipe,
46                           const struct pipe_compute_state *templ)
47 {
48    struct svga_context *svga = svga_context(pipe);
49 
50    struct svga_compute_shader *cs = CALLOC_STRUCT(svga_compute_shader);
51 
52    if (!cs)
53       return NULL;
54 
55    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATECS);
56 
57    if (templ->ir_type == PIPE_SHADER_IR_NIR) {
58       cs->base.tokens = nir_to_tgsi((void *)templ->prog, pipe->screen);
59    } else {
60       assert(templ->ir_type == PIPE_SHADER_IR_TGSI);
61       /* we need to keep a local copy of the tokens */
62       cs->base.tokens = tgsi_dup_tokens(templ->prog);
63    }
64    assert(templ->ir_type == PIPE_SHADER_IR_TGSI);
65    struct svga_shader *shader = &cs->base;
66    shader->id = svga->debug.shader_id++;
67    shader->type = templ->ir_type;
68    shader->stage = PIPE_SHADER_COMPUTE;
69 
70    /* Collect shader basic info */
71    svga_tgsi_scan_shader(&cs->base);
72 
73    cs->shared_mem_size = templ->req_local_mem;
74 
75    SVGA_STATS_TIME_POP(svga_sws(svga));
76    return cs;
77 }
78 
79 
80 /**
81  * Bind the compute program.
82  */
83 static void
svga_bind_compute_state(struct pipe_context * pipe,void * shader)84 svga_bind_compute_state(struct pipe_context *pipe, void *shader)
85 {
86    struct svga_context *svga = svga_context(pipe);
87    struct svga_compute_shader *cs = (struct svga_compute_shader *)shader;
88 
89    svga->curr.cs = cs;
90    svga->dirty |= SVGA_NEW_CS;
91 }
92 
93 
94 /**
95  * Delete the compute program.
96  */
97 static void
svga_delete_compute_state(struct pipe_context * pipe,void * shader)98 svga_delete_compute_state(struct pipe_context *pipe, void *shader)
99 {
100    struct svga_context *svga = svga_context(pipe);
101    struct svga_compute_shader *cs = (struct svga_compute_shader *)shader;
102    struct svga_compute_shader *next_cs;
103    struct svga_shader_variant *variant, *tmp;
104 
105    svga_hwtnl_flush_retry(svga);
106 
107    /* Free the list of compute shaders */
108    while (cs) {
109       next_cs = (struct svga_compute_shader *)cs->base.next;
110 
111       for (variant = cs->base.variants; variant; variant = tmp) {
112          tmp = variant->next;
113 
114          /* Check if deleting currently bound shader */
115          if (variant == svga->state.hw_draw.cs) {
116             SVGA_RETRY(svga, svga_set_shader(svga, SVGA3D_SHADERTYPE_CS, NULL));
117             svga->state.hw_draw.cs = NULL;
118          }
119 
120          svga_destroy_shader_variant(svga, variant);
121       }
122 
123       FREE((void *)cs->base.tokens);
124       FREE(cs);
125       cs = next_cs;
126    }
127 }
128 
129 
130 /**
131  * Bind an array of shader resources that will be used by the
132  * compute program.  Any resources that were previously bound to
133  * the specified range will be unbound after this call.
134  */
135 static void
svga_set_compute_resources(struct pipe_context * pipe,unsigned start,unsigned count,struct pipe_surface ** resources)136 svga_set_compute_resources(struct pipe_context *pipe,
137                            unsigned start, unsigned count,
138                            struct pipe_surface **resources)
139 {
140    //TODO
141    return;
142 }
143 
144 
145 /**
146  * Bind an array of buffers to be mapped into the address space of
147  * the GLOBAL resource.  Any buffers that were previously bound
148  * between [first, first + count - 1] are unbound after this call.
149  */
150 static void
svga_set_global_binding(struct pipe_context * pipe,unsigned first,unsigned count,struct pipe_resource ** resources,uint32_t ** handles)151 svga_set_global_binding(struct pipe_context *pipe,
152                         unsigned first, unsigned count,
153                         struct pipe_resource **resources,
154                         uint32_t **handles)
155 {
156    //TODO
157    return;
158 }
159 
160 
161 /**
162  */
163 static void
svga_validate_compute_resources(struct svga_context * svga)164 svga_validate_compute_resources(struct svga_context *svga)
165 {
166    /* validate sampler view resources */
167    SVGA_RETRY(svga,
168               svga_validate_sampler_resources(svga, SVGA_PIPE_COMPUTE));
169 
170    /* validate constant buffer resources */
171    SVGA_RETRY(svga,
172               svga_validate_constant_buffers(svga, SVGA_PIPE_COMPUTE));
173 
174    /* validate image view resources */
175    SVGA_RETRY(svga,
176               svga_validate_image_views(svga, SVGA_PIPE_COMPUTE));
177 
178    /* validate shader buffer resources */
179    SVGA_RETRY(svga,
180               svga_validate_shader_buffers(svga, SVGA_PIPE_COMPUTE));
181 }
182 
183 
184 /**
185  * Launch the compute kernel starting from instruction pc of the
186  * currently bound compute program.
187  */
188 static void
svga_launch_grid(struct pipe_context * pipe,const struct pipe_grid_info * info)189 svga_launch_grid(struct pipe_context *pipe,
190                  const struct pipe_grid_info *info)
191 {
192    struct svga_context *svga = svga_context(pipe);
193    struct svga_winsys_context *swc = svga->swc;
194 
195    assert(svga_have_gl43(svga));
196 
197    SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_LAUNCHGRID);
198 
199    if (info->indirect) {
200       svga->curr.grid_info.indirect= info->indirect;
201    }
202 
203    svga_update_compute_state(svga);
204 
205    /* validate compute resources */
206    svga_validate_compute_resources(svga);
207 
208    if (info->indirect) {
209       struct svga_winsys_surface *indirect_surf;
210       indirect_surf = svga_buffer_handle(svga, info->indirect,
211                                          PIPE_BIND_COMMAND_ARGS_BUFFER);
212       SVGA_RETRY(svga, SVGA3D_sm5_DispatchIndirect(swc, indirect_surf,
213                                                    info->indirect_offset));
214    }
215    else {
216       svga->curr.grid_info.size[0] = info->grid[0];
217       svga->curr.grid_info.size[1] = info->grid[1];
218       svga->curr.grid_info.size[2] = info->grid[2];
219 
220       SVGA_RETRY(svga, SVGA3D_sm5_Dispatch(swc, info->grid));
221    }
222 
223    SVGA_STATS_TIME_POP(svga_sws(svga));
224    return;
225 }
226 
227 
228 /**
229  * Initialize the compute interface function pointers.
230  */
231 void
svga_init_cs_functions(struct svga_context * svga)232 svga_init_cs_functions(struct svga_context *svga)
233 {
234    svga->pipe.create_compute_state = svga_create_compute_state;
235    svga->pipe.bind_compute_state = svga_bind_compute_state;
236    svga->pipe.delete_compute_state = svga_delete_compute_state;
237    svga->pipe.set_compute_resources = svga_set_compute_resources;
238    svga->pipe.set_global_binding = svga_set_global_binding;
239    svga->pipe.launch_grid = svga_launch_grid;
240 }
241