~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/svga/svga_shader_buffer.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#include "tgsi/tgsi_parse.h"
33
 
 
34
 
#include "svga_context.h"
35
 
#include "svga_cmd.h"
36
 
#include "svga_debug.h"
37
 
#include "svga_resource_buffer.h"
38
 
#include "svga_resource_texture.h"
39
 
#include "svga_surface.h"
40
 
#include "svga_sampler_view.h"
41
 
#include "svga_format.h"
42
 
 
43
 
 
44
 
/**
45
 
 * Create a uav object for the specified shader buffer
46
 
 */
47
 
SVGA3dUAViewId
48
 
svga_create_uav_buffer(struct svga_context *svga,
49
 
                       const struct pipe_shader_buffer *buf,
50
 
                       SVGA3dSurfaceFormat format,
51
 
                       SVGA3dUABufferFlags bufFlag)
52
 
{
53
 
   SVGA3dUAViewDesc desc;
54
 
   unsigned uaViewId;
55
 
 
56
 
   assert(buf);
57
 
 
58
 
   /* If there is not one defined, create one. */
59
 
   memset(&desc, 0, sizeof(desc));
60
 
   desc.buffer.firstElement = buf->buffer_offset / sizeof(uint32);
61
 
   desc.buffer.numElements = buf->buffer_size / sizeof(uint32);
62
 
   desc.buffer.flags = bufFlag;
63
 
 
64
 
   uaViewId = svga_create_uav(svga, &desc, format,
65
 
                              SVGA3D_RESOURCE_BUFFER,
66
 
                              svga_buffer_handle(svga, buf->buffer,
67
 
                                                 PIPE_BIND_SHADER_BUFFER));
68
 
   if (uaViewId == SVGA3D_INVALID_ID)
69
 
      return uaViewId;
70
 
 
71
 
   SVGA_DBG(DEBUG_UAV, "%s: resource=0x%x uaViewId=%d\n",
72
 
            __FUNCTION__, buf->buffer, uaViewId);
73
 
 
74
 
   /* Mark this buffer as a uav bound buffer */
75
 
   struct svga_buffer *sbuf = svga_buffer(buf->buffer);
76
 
   sbuf->uav = TRUE;
77
 
 
78
 
   return uaViewId;
79
 
}
80
 
 
81
 
 
82
 
/**
83
 
 * Set shader buffers.
84
 
 */
85
 
static void
86
 
svga_set_shader_buffers(struct pipe_context *pipe,
87
 
                        enum pipe_shader_type shader,
88
 
                        unsigned start, unsigned num,
89
 
                        const struct pipe_shader_buffer *buffers,
90
 
                        unsigned writeable_bitmask)
91
 
{
92
 
   struct svga_context *svga = svga_context(pipe);
93
 
   const struct pipe_shader_buffer *buf;
94
 
 
95
 
   assert(svga_have_gl43(svga));
96
 
 
97
 
   assert(start + num <= SVGA_MAX_SHADER_BUFFERS);
98
 
 
99
 
#ifdef DEBUG
100
 
   const struct pipe_shader_buffer *b = buffers;
101
 
   SVGA_DBG(DEBUG_UAV, "%s: shader=%d start=%d num=%d ",
102
 
            __FUNCTION__, shader, start, num);
103
 
   if (buffers) {
104
 
      for (unsigned i = 0; i < num; i++, b++) {
105
 
         SVGA_DBG(DEBUG_UAV, " 0x%x ", b);
106
 
      }
107
 
   }
108
 
   SVGA_DBG(DEBUG_UAV, "\n");
109
 
#endif
110
 
 
111
 
   buf = buffers;
112
 
   if (buffers) {
113
 
      int last_buffer = -1;
114
 
      for (unsigned i = start; i < start + num; i++, buf++) {
115
 
         struct svga_shader_buffer *cbuf = &svga->curr.shader_buffers[shader][i];
116
 
 
117
 
         if (buf && buf->buffer) {
118
 
            cbuf->desc = *buf;
119
 
            pipe_resource_reference(&cbuf->resource, buf->buffer);
120
 
 
121
 
            /* Mark the last bound shader buffer */
122
 
            last_buffer = i;
123
 
         }
124
 
         else {
125
 
            cbuf->desc.buffer = NULL;
126
 
            pipe_resource_reference(&cbuf->resource, NULL);
127
 
         }
128
 
         cbuf->uav_index = -1;
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
 
            __FUNCTION__, 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
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", __FUNCTION__, 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
 
            __FUNCTION__, 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
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
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
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
 
}