1
/**********************************************************
2
* Copyright 2022 VMware, Inc. All rights reserved.
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:
12
* The above copyright notice and this permission notice shall be
13
* included in all copies or substantial portions of the Software.
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
24
**********************************************************/
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"
34
#include "svga_context.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"
45
* Create a uav object for the specified shader buffer
48
svga_create_uav_buffer(struct svga_context *svga,
49
const struct pipe_shader_buffer *buf,
50
SVGA3dSurfaceFormat format,
51
SVGA3dUABufferFlags bufFlag)
53
SVGA3dUAViewDesc desc;
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;
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)
71
SVGA_DBG(DEBUG_UAV, "%s: resource=0x%x uaViewId=%d\n",
72
__FUNCTION__, buf->buffer, uaViewId);
74
/* Mark this buffer as a uav bound buffer */
75
struct svga_buffer *sbuf = svga_buffer(buf->buffer);
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)
92
struct svga_context *svga = svga_context(pipe);
93
const struct pipe_shader_buffer *buf;
95
assert(svga_have_gl43(svga));
97
assert(start + num <= SVGA_MAX_SHADER_BUFFERS);
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);
104
for (unsigned i = 0; i < num; i++, b++) {
105
SVGA_DBG(DEBUG_UAV, " 0x%x ", b);
108
SVGA_DBG(DEBUG_UAV, "\n");
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];
117
if (buf && buf->buffer) {
119
pipe_resource_reference(&cbuf->resource, buf->buffer);
121
/* Mark the last bound shader buffer */
125
cbuf->desc.buffer = NULL;
126
pipe_resource_reference(&cbuf->resource, NULL);
128
cbuf->uav_index = -1;
130
svga->curr.num_shader_buffers[shader] =
131
MAX2(svga->curr.num_shader_buffers[shader], last_buffer + 1);
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);
140
if ((start + num) >= svga->curr.num_shader_buffers[shader])
141
svga->curr.num_shader_buffers[shader] = start;
146
"%s: current num_shader_buffers=%d start=%d num=%d buffers=",
147
__FUNCTION__, svga->curr.num_shader_buffers[shader],
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);
155
SVGA_DBG(DEBUG_UAV, "\n");
158
/* purge any unused uav objects */
159
svga_destroy_uav(svga);
161
svga->dirty |= SVGA_NEW_SHADER_BUFFER;
166
* Set HW atomic buffers.
169
svga_set_hw_atomic_buffers(struct pipe_context *pipe,
170
unsigned start, unsigned num,
171
const struct pipe_shader_buffer *buffers)
173
struct svga_context *svga = svga_context(pipe);
174
const struct pipe_shader_buffer *buf = buffers;
176
assert(svga_have_gl43(svga));
178
assert(start + num <= SVGA_MAX_ATOMIC_BUFFERS);
181
SVGA_DBG(DEBUG_UAV, "%s: start=%d num=%d \n", __FUNCTION__, start, num);
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];
190
if (buf && buf->buffer) {
192
pipe_resource_reference(&cbuf->resource, buf->buffer);
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.
201
struct svga_buffer *sbuf = svga_buffer(cbuf->desc.buffer);
205
cbuf->desc.buffer = NULL;
206
pipe_resource_reference(&cbuf->resource, NULL);
208
cbuf->uav_index = -1;
210
svga->curr.num_atomic_buffers = MAX2(svga->curr.num_atomic_buffers,
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);
220
if ((start + num) >= svga->curr.num_atomic_buffers)
221
svga->curr.num_atomic_buffers = start;
225
SVGA_DBG(DEBUG_UAV, "%s: current num_atomic_buffers=%d start=%d num=%d ",
226
__FUNCTION__, svga->curr.num_atomic_buffers,
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);
234
SVGA_DBG(DEBUG_UAV, "\n");
237
/* purge any unused uav objects */
238
svga_destroy_uav(svga);
240
svga->dirty |= SVGA_NEW_SHADER_BUFFER;
245
* Initialize shader images gallium interface
248
svga_init_shader_buffer_functions(struct svga_context *svga)
250
if (!svga_have_gl43(svga))
253
svga->pipe.set_shader_buffers = svga_set_shader_buffers;
254
svga->pipe.set_hw_atomic_buffers = svga_set_hw_atomic_buffers;
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];
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.
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;
276
memset(svga->state.hw_draw.num_shader_buffers, 0,
277
sizeof(svga->state.hw_draw.num_shader_buffers));
279
/* Initialize atomic buffers */
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.
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;
289
svga->state.hw_draw.num_atomic_buffers = 0;
294
* Cleanup shader image state
297
svga_cleanup_shader_buffer_state(struct svga_context *svga)
299
if (!svga_have_gl43(svga))
302
svga_destroy_uav(svga);
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
313
svga_validate_shader_buffer_resources(struct svga_context *svga,
315
struct svga_shader_buffer *bufs,
318
assert(svga_have_gl43(svga));
320
struct svga_winsys_surface *surf;
324
for (i = 0; i < count; i++) {
325
if (bufs[i].resource) {
326
assert(bufs[i].resource == bufs[i].desc.buffer);
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);
333
ret = svga->swc->resource_rebind(svga->swc, surf, NULL,
334
SVGA_RELOC_READ|SVGA_RELOC_WRITE);
339
/* Mark buffer as RENDERED */
340
svga_set_buffer_rendered_to(sbuf->bufsurf);