Skip to content

Commit 5e8ec0d

Browse files
deepak-rawatRoland Scheidegger
authored andcommitted
drm/vmwgfx: Add support for UA view commands
Virtual device now support new commands to manage unordered access views. Allow them as part of user-space command buffer. This involves adding UA view cotable, binding tracker info, new view type and command verifier functions. v2: fix comment typo v3: style fixes (don't use deprecated PTR_RET) Signed-off-by: Deepak Rawat <[email protected]> Signed-off-by: Neha Bhende <[email protected]> Reviewed-by: Thomas Hellström (VMware) <[email protected]> Reviewed-by: Roland Scheidegger <[email protected]> Signed-off-by: Roland Scheidegger <[email protected]>
1 parent d2e90ab commit 5e8ec0d

File tree

7 files changed

+319
-18
lines changed

7 files changed

+319
-18
lines changed

drivers/gpu/drm/vmwgfx/vmwgfx_binding.c

Lines changed: 125 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
#define VMW_BINDING_PS_BIT 1
6060
#define VMW_BINDING_SO_BIT 2
6161
#define VMW_BINDING_VB_BIT 3
62-
#define VMW_BINDING_NUM_BITS 4
62+
#define VMW_BINDING_UAV_BIT 4
63+
#define VMW_BINDING_CS_UAV_BIT 5
64+
#define VMW_BINDING_NUM_BITS 6
6365

6466
#define VMW_BINDING_PS_SR_BIT 0
6567

@@ -75,6 +77,7 @@
7577
* @vertex_buffers: Vertex buffer bindings.
7678
* @index_buffer: Index buffer binding.
7779
* @per_shader: Per shader-type bindings.
80+
* @ua_views: UAV bindings.
7881
* @dirty: Bitmap tracking per binding-type changes that have not yet
7982
* been emitted to the device.
8083
* @dirty_vb: Bitmap tracking individual vertex buffer binding changes that
@@ -99,6 +102,7 @@ struct vmw_ctx_binding_state {
99102
struct vmw_ctx_bindinfo_vb vertex_buffers[SVGA3D_DX_MAX_VERTEXBUFFERS];
100103
struct vmw_ctx_bindinfo_ib index_buffer;
101104
struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE];
105+
struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE];
102106

103107
unsigned long dirty;
104108
DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS);
@@ -121,6 +125,9 @@ static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi,
121125
bool rebind);
122126
static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind);
123127
static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind);
128+
static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
129+
static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
130+
124131
static void vmw_binding_build_asserts(void) __attribute__ ((unused));
125132

126133
typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool);
@@ -189,6 +196,12 @@ static const size_t vmw_binding_vb_offsets[] = {
189196
static const size_t vmw_binding_ib_offsets[] = {
190197
offsetof(struct vmw_ctx_binding_state, index_buffer),
191198
};
199+
static const size_t vmw_binding_uav_offsets[] = {
200+
offsetof(struct vmw_ctx_binding_state, ua_views[0].views),
201+
};
202+
static const size_t vmw_binding_cs_uav_offsets[] = {
203+
offsetof(struct vmw_ctx_binding_state, ua_views[1].views),
204+
};
192205

193206
static const struct vmw_binding_info vmw_binding_infos[] = {
194207
[vmw_ctx_binding_shader] = {
@@ -235,6 +248,14 @@ static const struct vmw_binding_info vmw_binding_infos[] = {
235248
.size = sizeof(struct vmw_ctx_bindinfo_ib),
236249
.offsets = vmw_binding_ib_offsets,
237250
.scrub_func = vmw_binding_scrub_ib},
251+
[vmw_ctx_binding_uav] = {
252+
.size = sizeof(struct vmw_ctx_bindinfo_view),
253+
.offsets = vmw_binding_uav_offsets,
254+
.scrub_func = vmw_binding_scrub_uav},
255+
[vmw_ctx_binding_cs_uav] = {
256+
.size = sizeof(struct vmw_ctx_bindinfo_view),
257+
.offsets = vmw_binding_cs_uav_offsets,
258+
.scrub_func = vmw_binding_scrub_cs_uav},
238259
};
239260

240261
/**
@@ -320,6 +341,18 @@ void vmw_binding_add(struct vmw_ctx_binding_state *cbs,
320341
INIT_LIST_HEAD(&loc->res_list);
321342
}
322343

344+
/**
345+
* vmw_binding_add_uav_index - Add UAV index for tracking.
346+
* @cbs: Pointer to the context binding state tracker.
347+
* @slot: UAV type to which bind this index.
348+
* @index: The splice index to track.
349+
*/
350+
void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs, uint32 slot,
351+
uint32 index)
352+
{
353+
cbs->ua_views[slot].index = index;
354+
}
355+
323356
/**
324357
* vmw_binding_transfer: Transfer a context binding tracking entry.
325358
*
@@ -459,6 +492,10 @@ void vmw_binding_state_commit(struct vmw_ctx_binding_state *to,
459492
vmw_binding_transfer(to, from, entry);
460493
vmw_binding_drop(entry);
461494
}
495+
496+
/* Also transfer uav splice indices */
497+
to->ua_views[0].index = from->ua_views[0].index;
498+
to->ua_views[1].index = from->ua_views[1].index;
462499
}
463500

464501
/**
@@ -1014,6 +1051,66 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
10141051
return 0;
10151052
}
10161053

1054+
static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs)
1055+
{
1056+
const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi;
1057+
struct {
1058+
SVGA3dCmdHeader header;
1059+
SVGA3dCmdDXSetUAViews body;
1060+
} *cmd;
1061+
size_t cmd_size, view_id_size;
1062+
const struct vmw_resource *ctx = vmw_cbs_context(cbs);
1063+
1064+
vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS);
1065+
view_id_size = cbs->bind_cmd_count*sizeof(uint32);
1066+
cmd_size = sizeof(*cmd) + view_id_size;
1067+
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
1068+
if (!cmd)
1069+
return -ENOMEM;
1070+
1071+
cmd->header.id = SVGA_3D_CMD_DX_SET_UA_VIEWS;
1072+
cmd->header.size = sizeof(cmd->body) + view_id_size;
1073+
1074+
/* Splice index is specified user-space */
1075+
cmd->body.uavSpliceIndex = cbs->ua_views[0].index;
1076+
1077+
memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size);
1078+
1079+
vmw_fifo_commit(ctx->dev_priv, cmd_size);
1080+
1081+
return 0;
1082+
}
1083+
1084+
static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs)
1085+
{
1086+
const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi;
1087+
struct {
1088+
SVGA3dCmdHeader header;
1089+
SVGA3dCmdDXSetCSUAViews body;
1090+
} *cmd;
1091+
size_t cmd_size, view_id_size;
1092+
const struct vmw_resource *ctx = vmw_cbs_context(cbs);
1093+
1094+
vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS);
1095+
view_id_size = cbs->bind_cmd_count*sizeof(uint32);
1096+
cmd_size = sizeof(*cmd) + view_id_size;
1097+
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
1098+
if (!cmd)
1099+
return -ENOMEM;
1100+
1101+
cmd->header.id = SVGA_3D_CMD_DX_SET_CS_UA_VIEWS;
1102+
cmd->header.size = sizeof(cmd->body) + view_id_size;
1103+
1104+
/* Start index is specified user-space */
1105+
cmd->body.startIndex = cbs->ua_views[1].index;
1106+
1107+
memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size);
1108+
1109+
vmw_fifo_commit(ctx->dev_priv, cmd_size);
1110+
1111+
return 0;
1112+
}
1113+
10171114
/**
10181115
* vmw_binding_emit_dirty - Issue delayed binding commands
10191116
*
@@ -1045,6 +1142,12 @@ static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs)
10451142
case VMW_BINDING_VB_BIT:
10461143
ret = vmw_emit_set_vb(cbs);
10471144
break;
1145+
case VMW_BINDING_UAV_BIT:
1146+
ret = vmw_emit_set_uav(cbs);
1147+
break;
1148+
case VMW_BINDING_CS_UAV_BIT:
1149+
ret = vmw_emit_set_cs_uav(cbs);
1150+
break;
10481151
default:
10491152
BUG();
10501153
}
@@ -1171,6 +1274,22 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind)
11711274
return 0;
11721275
}
11731276

1277+
static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind)
1278+
{
1279+
struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx);
1280+
1281+
__set_bit(VMW_BINDING_UAV_BIT, &cbs->dirty);
1282+
return 0;
1283+
}
1284+
1285+
static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind)
1286+
{
1287+
struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx);
1288+
1289+
__set_bit(VMW_BINDING_CS_UAV_BIT, &cbs->dirty);
1290+
return 0;
1291+
}
1292+
11741293
/**
11751294
* vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with
11761295
* memory accounting.
@@ -1257,8 +1376,8 @@ void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs)
12571376
* Each time a resource is put on the validation list as the result of a
12581377
* context binding referencing it, we need to determine whether that resource
12591378
* will be dirtied (written to by the GPU) as a result of the corresponding
1260-
* GPU operation. Currently rendertarget-, depth-stencil-, and
1261-
* stream-output-target bindings are capable of dirtying its resource.
1379+
* GPU operation. Currently rendertarget-, depth-stencil-, stream-output-target
1380+
* and unordered access view bindings are capable of dirtying its resource.
12621381
*
12631382
* Return: Whether the binding type dirties the resource its binding points to.
12641383
*/
@@ -1269,10 +1388,12 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type)
12691388
[vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET,
12701389
[vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET,
12711390
[vmw_ctx_binding_so] = VMW_RES_DIRTY_SET,
1391+
[vmw_ctx_binding_uav] = VMW_RES_DIRTY_SET,
1392+
[vmw_ctx_binding_cs_uav] = VMW_RES_DIRTY_SET,
12721393
};
12731394

12741395
/* Review this function as new bindings are added. */
1275-
BUILD_BUG_ON(vmw_ctx_binding_max != 11);
1396+
BUILD_BUG_ON(vmw_ctx_binding_max != 13);
12761397
return is_binding_dirtying[binding_type];
12771398
}
12781399

drivers/gpu/drm/vmwgfx/vmwgfx_binding.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#define VMW_MAX_VIEW_BINDINGS 128
3535

36+
#define VMW_MAX_UAV_BIND_TYPE 2
37+
3638
struct vmw_private;
3739
struct vmw_ctx_binding_state;
3840

@@ -51,6 +53,8 @@ enum vmw_ctx_binding_type {
5153
vmw_ctx_binding_so,
5254
vmw_ctx_binding_vb,
5355
vmw_ctx_binding_ib,
56+
vmw_ctx_binding_uav,
57+
vmw_ctx_binding_cs_uav,
5458
vmw_ctx_binding_max
5559
};
5660

@@ -189,9 +193,21 @@ struct vmw_dx_shader_bindings {
189193
unsigned long dirty;
190194
};
191195

196+
/**
197+
* struct vmw_ctx_bindinfo_uav - UAV context binding state.
198+
* @views: UAV view bindings.
199+
* @splice_index: The device splice index set by user-space.
200+
*/
201+
struct vmw_ctx_bindinfo_uav {
202+
struct vmw_ctx_bindinfo_view views[SVGA3D_MAX_UAVIEWS];
203+
uint32 index;
204+
};
205+
192206
extern void vmw_binding_add(struct vmw_ctx_binding_state *cbs,
193207
const struct vmw_ctx_bindinfo *ci,
194208
u32 shader_slot, u32 slot);
209+
extern void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs,
210+
uint32 slot, uint32 splice_index);
195211
extern void
196212
vmw_binding_state_commit(struct vmw_ctx_binding_state *to,
197213
struct vmw_ctx_binding_state *from);

drivers/gpu/drm/vmwgfx/vmwgfx_context.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct vmw_user_context {
3636
struct vmw_resource res;
3737
struct vmw_ctx_binding_state *cbs;
3838
struct vmw_cmdbuf_res_manager *man;
39-
struct vmw_resource *cotables[SVGA_COTABLE_DX10_MAX];
39+
struct vmw_resource *cotables[SVGA_COTABLE_MAX];
4040
spinlock_t cotable_lock;
4141
struct vmw_buffer_object *dx_query_mob;
4242
};
@@ -116,12 +116,15 @@ static const struct vmw_res_func vmw_dx_context_func = {
116116
* Context management:
117117
*/
118118

119-
static void vmw_context_cotables_unref(struct vmw_user_context *uctx)
119+
static void vmw_context_cotables_unref(struct vmw_private *dev_priv,
120+
struct vmw_user_context *uctx)
120121
{
121122
struct vmw_resource *res;
122123
int i;
124+
u32 cotable_max = has_sm5_context(dev_priv) ?
125+
SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX;
123126

124-
for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) {
127+
for (i = 0; i < cotable_max; ++i) {
125128
spin_lock(&uctx->cotable_lock);
126129
res = uctx->cotables[i];
127130
uctx->cotables[i] = NULL;
@@ -155,7 +158,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
155158
!dev_priv->query_cid_valid)
156159
__vmw_execbuf_release_pinned_bo(dev_priv, NULL);
157160
mutex_unlock(&dev_priv->cmdbuf_mutex);
158-
vmw_context_cotables_unref(uctx);
161+
vmw_context_cotables_unref(dev_priv, uctx);
159162
return;
160163
}
161164

@@ -208,7 +211,9 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
208211
spin_lock_init(&uctx->cotable_lock);
209212

210213
if (dx) {
211-
for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) {
214+
u32 cotable_max = has_sm5_context(dev_priv) ?
215+
SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX;
216+
for (i = 0; i < cotable_max; ++i) {
212217
uctx->cotables[i] = vmw_cotable_alloc(dev_priv,
213218
&uctx->res, i);
214219
if (IS_ERR(uctx->cotables[i])) {
@@ -222,7 +227,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
222227
return 0;
223228

224229
out_cotables:
225-
vmw_context_cotables_unref(uctx);
230+
vmw_context_cotables_unref(dev_priv, uctx);
226231
out_err:
227232
if (res_free)
228233
res_free(res);
@@ -545,10 +550,12 @@ void vmw_dx_context_scrub_cotables(struct vmw_resource *ctx,
545550
{
546551
struct vmw_user_context *uctx =
547552
container_of(ctx, struct vmw_user_context, res);
553+
u32 cotable_max = has_sm5_context(ctx->dev_priv) ?
554+
SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX;
548555
int i;
549556

550557
vmw_binding_state_scrub(uctx->cbs);
551-
for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) {
558+
for (i = 0; i < cotable_max; ++i) {
552559
struct vmw_resource *res;
553560

554561
/* Avoid racing with ongoing cotable destruction. */
@@ -839,7 +846,10 @@ struct vmw_cmdbuf_res_manager *vmw_context_res_man(struct vmw_resource *ctx)
839846
struct vmw_resource *vmw_context_cotable(struct vmw_resource *ctx,
840847
SVGACOTableType cotable_type)
841848
{
842-
if (cotable_type >= SVGA_COTABLE_DX10_MAX)
849+
u32 cotable_max = has_sm5_context(ctx->dev_priv) ?
850+
SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX;
851+
852+
if (cotable_type >= cotable_max)
843853
return ERR_PTR(-EINVAL);
844854

845855
return container_of(ctx, struct vmw_user_context, res)->

drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ static const struct vmw_cotable_info co_info[] = {
8282
{1, sizeof(SVGACOTableDXSamplerEntry), NULL},
8383
{1, sizeof(SVGACOTableDXStreamOutputEntry), NULL},
8484
{1, sizeof(SVGACOTableDXQueryEntry), NULL},
85-
{1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub}
85+
{1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub},
86+
{1, sizeof(SVGACOTableDXUAViewEntry), &vmw_view_cotable_list_destroy}
8687
};
8788

8889
/*
@@ -102,6 +103,7 @@ const SVGACOTableType vmw_cotable_scrub_order[] = {
102103
SVGA_COTABLE_SAMPLER,
103104
SVGA_COTABLE_STREAMOUTPUT,
104105
SVGA_COTABLE_DXQUERY,
106+
SVGA_COTABLE_UAVIEW,
105107
};
106108

107109
static int vmw_cotable_bind(struct vmw_resource *res,

0 commit comments

Comments
 (0)