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 "pipe/p_defines.h"
27 #include "util/u_bitmask.h"
28 #include "util/format/u_format.h"
29 #include "util/u_inlines.h"
30 #include "util/u_math.h"
31 #include "util/u_memory.h"
32
33 #include "svga_context.h"
34 #include "svga_cmd.h"
35 #include "svga_debug.h"
36 #include "svga_resource_buffer.h"
37 #include "svga_resource_texture.h"
38 #include "svga_surface.h"
39 #include "svga_sampler_view.h"
40 #include "svga_format.h"
41
42
43 /**
44 * Create a uav object for the specified shader buffer
45 */
46 SVGA3dUAViewId
svga_create_uav_buffer(struct svga_context * svga,const struct pipe_shader_buffer * buf,SVGA3dSurfaceFormat format,SVGA3dUABufferFlags bufFlag)47 svga_create_uav_buffer(struct svga_context *svga,
48 const struct pipe_shader_buffer *buf,
49 SVGA3dSurfaceFormat format,
50 SVGA3dUABufferFlags bufFlag)
51 {
52 SVGA3dUAViewDesc desc;
53 unsigned uaViewId;
54
55 assert(buf);
56
57 /* If there is not one defined, create one. */
58 memset(&desc, 0, sizeof(desc));
59 desc.buffer.firstElement = buf->buffer_offset / sizeof(uint32);
60 desc.buffer.numElements = buf->buffer_size / sizeof(uint32);
61 desc.buffer.flags = bufFlag;
62
63 uaViewId = svga_create_uav(svga, &desc, format,
64 SVGA3D_RESOURCE_BUFFER,
65 svga_buffer_handle(svga, buf->buffer,
66 PIPE_BIND_SHADER_BUFFER));
67 if (uaViewId == SVGA3D_INVALID_ID)
68 return uaViewId;
69
70 SVGA_DBG(DEBUG_UAV, "%s: resource=0x%x uaViewId=%d\n",
71 __func__, buf->buffer, uaViewId);
72
73 /* Mark this buffer as a uav bound buffer */
74 struct svga_buffer *sbuf = svga_buffer(buf->buffer);
75 sbuf->uav = true;
76
77 return uaViewId;
78 }
79
80
81 /**
82 * Set shader buffers.
83 */
84 static void
svga_set_shader_buffers(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned num,const struct pipe_shader_buffer * buffers,unsigned writeable_bitmask)85 svga_set_shader_buffers(struct pipe_context *pipe,
86 enum pipe_shader_type shader,
87 unsigned start, unsigned num,
88 const struct pipe_shader_buffer *buffers,
89 unsigned writeable_bitmask)
90 {
91 struct svga_context *svga = svga_context(pipe);
92 const struct pipe_shader_buffer *buf;
93
94 assert(svga_have_gl43(svga));
95
96 assert(start + num <= SVGA_MAX_SHADER_BUFFERS);
97
98 #ifdef DEBUG
99 const struct pipe_shader_buffer *b = buffers;
100 SVGA_DBG(DEBUG_UAV, "%s: shader=%d start=%d num=%d ",
101 __func__, shader, start, num);
102 if (buffers) {
103 for (unsigned i = 0; i < num; i++, b++) {
104 SVGA_DBG(DEBUG_UAV, " 0x%x ", b);
105 }
106 }
107 SVGA_DBG(DEBUG_UAV, "\n");
108 #endif
109
110 buf = buffers;
111 if (buffers) {
112 int last_buffer = -1;
113 for (unsigned i = start, j=0; i < start + num; i++, buf++, j++) {
114 struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
115
116 if (buf && buf->buffer) {
117 cbuf->desc = *buf;
118 pipe_resource_reference(&cbuf->resource, buf->buffer);
119
120 /* Mark the last bound shader buffer */
121 last_buffer = i;
122 }
123 else {
124 cbuf->desc.buffer = NULL;
125 pipe_resource_reference(&cbuf->resource, NULL);
126 }
127 cbuf->uav_index = -1;
128 cbuf->writeAccess = (writeable_bitmask & (1 << j)) != 0;
129 }
130 svga->curr.num_shader_buffers[shader] =
131 MAX2(svga->curr.num_shader_buffers[shader], last_buffer + 1);
132 }
133 else {
134 for (unsigned i = start; i < start + num; i++) {
135 struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
136 cbuf->desc.buffer = NULL;
137 cbuf->uav_index = -1;
138 pipe_resource_reference(&cbuf->resource, NULL);
139 }
140 if ((start + num) >= svga->curr.num_shader_buffers[shader])
141 svga->curr.num_shader_buffers[shader] = start;
142 }
143
144 #ifdef DEBUG
145 SVGA_DBG(DEBUG_UAV,
146 "%s: current num_shader_buffers=%d start=%d num=%d buffers=",
147 __func__, svga->curr.num_shader_buffers[shader],
148 start, num);
149
150 for (unsigned i = start; i < start + num; i++) {
151 struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
152 SVGA_DBG(DEBUG_UAV, " 0x%x ", cbuf->desc.buffer);
153 }
154
155 SVGA_DBG(DEBUG_UAV, "\n");
156 #endif
157
158 /* purge any unused uav objects */
159 svga_destroy_uav(svga);
160
161 svga->dirty |= SVGA_NEW_SHADER_BUFFER;
162 }
163
164
165 /**
166 * Set HW atomic buffers.
167 */
168 static void
svga_set_hw_atomic_buffers(struct pipe_context * pipe,unsigned start,unsigned num,const struct pipe_shader_buffer * buffers)169 svga_set_hw_atomic_buffers(struct pipe_context *pipe,
170 unsigned start, unsigned num,
171 const struct pipe_shader_buffer *buffers)
172 {
173 struct svga_context *svga = svga_context(pipe);
174 const struct pipe_shader_buffer *buf = buffers;
175
176 assert(svga_have_gl43(svga));
177
178 assert(start + num <= SVGA_MAX_ATOMIC_BUFFERS);
179
180 #ifdef DEBUG
181 SVGA_DBG(DEBUG_UAV, "%s: start=%d num=%d \n", __func__, start, num);
182 #endif
183
184 buf = buffers;
185 if (buffers) {
186 int last_buffer = -1;
187 for (unsigned i = start; i < start + num; i++, buf++) {
188 struct svga_shader_buffer *cbuf = &svga->curr.atomic_buffers[i];
189
190 if (buf && buf->buffer) {
191 cbuf->desc = *buf;
192 pipe_resource_reference(&cbuf->resource, buf->buffer);
193
194 last_buffer = i;
195
196 /* Mark the buffer as uav buffer so that a readback will
197 * be done at each read transfer. We can't rely on the
198 * dirty bit because it is reset after each read, but
199 * the uav buffer can be updated at each draw.
200 */
201 struct svga_buffer *sbuf = svga_buffer(cbuf->desc.buffer);
202 sbuf->uav = true;
203 }
204 else {
205 cbuf->desc.buffer = NULL;
206 pipe_resource_reference(&cbuf->resource, NULL);
207 }
208 cbuf->uav_index = -1;
209 }
210 svga->curr.num_atomic_buffers = MAX2(svga->curr.num_atomic_buffers,
211 last_buffer + 1);
212 }
213 else {
214 for (unsigned i = start; i < start + num; i++) {
215 struct svga_shader_buffer *cbuf = &svga->curr.atomic_buffers[i];
216 cbuf->desc.buffer = NULL;
217 cbuf->uav_index = -1;
218 pipe_resource_reference(&cbuf->resource, NULL);
219 }
220 if ((start + num) >= svga->curr.num_atomic_buffers)
221 svga->curr.num_atomic_buffers = start;
222 }
223
224 #ifdef DEBUG
225 SVGA_DBG(DEBUG_UAV, "%s: current num_atomic_buffers=%d start=%d num=%d ",
226 __func__, svga->curr.num_atomic_buffers,
227 start, num);
228
229 for (unsigned i = start; i < start + num; i++) {
230 struct svga_shader_buffer *cbuf = &svga->curr.atomic_buffers[i];
231 SVGA_DBG(DEBUG_UAV, " 0x%x ", cbuf->desc.buffer);
232 }
233
234 SVGA_DBG(DEBUG_UAV, "\n");
235 #endif
236
237 /* purge any unused uav objects */
238 svga_destroy_uav(svga);
239
240 svga->dirty |= SVGA_NEW_SHADER_BUFFER;
241 }
242
243
244 /**
245 * Initialize shader images gallium interface
246 */
247 void
svga_init_shader_buffer_functions(struct svga_context * svga)248 svga_init_shader_buffer_functions(struct svga_context *svga)
249 {
250 if (!svga_have_gl43(svga))
251 return;
252
253 svga->pipe.set_shader_buffers = svga_set_shader_buffers;
254 svga->pipe.set_hw_atomic_buffers = svga_set_hw_atomic_buffers;
255
256 /* Initialize shader buffers */
257 for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; ++shader) {
258 struct svga_shader_buffer *hw_buf =
259 &svga->state.hw_draw.shader_buffers[shader][0];
260 struct svga_shader_buffer *cur_buf =
261 &svga->curr.shader_buffers[shader][0];
262
263 /* Initialize uaViewId to SVGA3D_INVALID_ID for current shader buffers
264 * and shader buffers in hw state to avoid unintentional unbinding of
265 * shader buffers with uaViewId 0.
266 */
267 for (unsigned i = 0; i < ARRAY_SIZE(svga->curr.shader_buffers[shader]);
268 i++, hw_buf++, cur_buf++) {
269 hw_buf->resource = NULL;
270 hw_buf->uav_index = -1;
271 cur_buf->desc.buffer = NULL;
272 cur_buf->resource = NULL;
273 cur_buf->uav_index = -1;
274 }
275 }
276 memset(svga->state.hw_draw.num_shader_buffers, 0,
277 sizeof(svga->state.hw_draw.num_shader_buffers));
278
279 /* Initialize atomic buffers */
280
281 /* Initialize uaViewId to SVGA3D_INVALID_ID for current atomic buffers
282 * and atomic buffers in hw state to avoid unintentional unbinding of
283 * shader buffer with uaViewId 0.
284 */
285 for (unsigned i = 0; i < ARRAY_SIZE(svga->state.hw_draw.atomic_buffers); i++) {
286 svga->curr.atomic_buffers[i].resource = NULL;
287 svga->curr.atomic_buffers[i].uav_index = -1;
288 }
289 svga->state.hw_draw.num_atomic_buffers = 0;
290 }
291
292
293 /**
294 * Cleanup shader image state
295 */
296 void
svga_cleanup_shader_buffer_state(struct svga_context * svga)297 svga_cleanup_shader_buffer_state(struct svga_context *svga)
298 {
299 if (!svga_have_gl43(svga))
300 return;
301
302 svga_destroy_uav(svga);
303 }
304
305
306 /**
307 * Validate shader buffer resources to ensure any pending changes to the
308 * buffers are emitted before they are referenced.
309 * The helper function also rebinds the buffer resources if the rebind flag
310 * is specified.
311 */
312 enum pipe_error
svga_validate_shader_buffer_resources(struct svga_context * svga,unsigned count,struct svga_shader_buffer * bufs,bool rebind)313 svga_validate_shader_buffer_resources(struct svga_context *svga,
314 unsigned count,
315 struct svga_shader_buffer *bufs,
316 bool rebind)
317 {
318 assert(svga_have_gl43(svga));
319
320 struct svga_winsys_surface *surf;
321 enum pipe_error ret;
322 unsigned i;
323
324 for (i = 0; i < count; i++) {
325 if (bufs[i].resource) {
326 assert(bufs[i].resource == bufs[i].desc.buffer);
327
328 struct svga_buffer *sbuf = svga_buffer(bufs[i].resource);
329 surf = svga_buffer_handle(svga, bufs[i].desc.buffer,
330 PIPE_BIND_SHADER_BUFFER);
331 assert(surf);
332 if (rebind) {
333 ret = svga->swc->resource_rebind(svga->swc, surf, NULL,
334 SVGA_RELOC_READ|SVGA_RELOC_WRITE);
335 if (ret != PIPE_OK)
336 return ret;
337 }
338
339 /* Mark buffer as RENDERED */
340 svga_set_buffer_rendered_to(sbuf->bufsurf);
341 }
342 }
343
344 return PIPE_OK;
345 }
346
347
348 /**
349 * Returns TRUE if the shader buffer can be bound to SRV as raw buffer.
350 * It is TRUE if the shader buffer is readonly and the surface already
351 * has the RAW_BUFFER_VIEW bind flag set.
352 */
353 bool
svga_shader_buffer_can_use_srv(struct svga_context * svga,enum pipe_shader_type shader,unsigned index,struct svga_shader_buffer * buf)354 svga_shader_buffer_can_use_srv(struct svga_context *svga,
355 enum pipe_shader_type shader,
356 unsigned index,
357 struct svga_shader_buffer *buf)
358 {
359 if (buf->resource) {
360 struct svga_buffer *sbuf = svga_buffer(buf->resource);
361 if (sbuf && !buf->writeAccess && svga_has_raw_buffer_view(sbuf)) {
362 return true;
363 }
364 }
365 return false;
366 }
367
368
369 #define SVGA_SSBO_SRV_START SVGA_MAX_CONST_BUFS
370
371 /**
372 * Bind the shader buffer as SRV raw buffer.
373 */
374 enum pipe_error
svga_shader_buffer_bind_srv(struct svga_context * svga,enum pipe_shader_type shader,unsigned index,struct svga_shader_buffer * buf)375 svga_shader_buffer_bind_srv(struct svga_context *svga,
376 enum pipe_shader_type shader,
377 unsigned index,
378 struct svga_shader_buffer *buf)
379 {
380 enum pipe_error ret;
381 unsigned slot = index + SVGA_SSBO_SRV_START;
382
383 svga->state.raw_shaderbufs[shader] |= (1 << index);
384 ret = svga_emit_rawbuf(svga, slot, shader, buf->desc.buffer_offset,
385 buf->desc.buffer_size, buf->resource);
386 if (ret == PIPE_OK)
387 svga->state.hw_draw.enabled_raw_shaderbufs[shader] |= (1 << index);
388
389 return ret;
390 }
391
392
393 /**
394 * Unbind the shader buffer SRV.
395 */
396 enum pipe_error
svga_shader_buffer_unbind_srv(struct svga_context * svga,enum pipe_shader_type shader,unsigned index,struct svga_shader_buffer * buf)397 svga_shader_buffer_unbind_srv(struct svga_context *svga,
398 enum pipe_shader_type shader,
399 unsigned index,
400 struct svga_shader_buffer *buf)
401 {
402 enum pipe_error ret = PIPE_OK;
403 unsigned slot = index + SVGA_SSBO_SRV_START;
404
405 if ((svga->state.hw_draw.enabled_raw_shaderbufs[shader] & (1 << index))
406 != 0) {
407 ret = svga_emit_rawbuf(svga, slot, shader, 0, 0, NULL);
408 if (ret == PIPE_OK)
409 svga->state.hw_draw.enabled_raw_shaderbufs[shader] &= ~(1 << index);
410 }
411 svga->state.raw_shaderbufs[shader] &= ~(1 << index);
412 return ret;
413 }
414