Skip to content

Commit e8bead9

Browse files
deepak-rawatRoland Scheidegger
authored andcommitted
drm/vmwgfx: Add support for streamoutput with mob commands
With SM5 capability a new version of streamoutput is supported by device which need backing mob and a new field. With this change the new command is supported in command buffer. v2: Also track streamoutput context binding in binding manager. v3: Track only one streamoutput as only one can be set to context. v4: Fix comment typos 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 403fef5 commit e8bead9

File tree

8 files changed

+630
-7
lines changed

8 files changed

+630
-7
lines changed

drivers/gpu/drm/vmwgfx/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
88
vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
99
vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
1010
vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \
11-
vmwgfx_validation.o vmwgfx_page_dirty.o \
11+
vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \
1212
ttm_object.o ttm_lock.o
1313

1414
obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o

drivers/gpu/drm/vmwgfx/vmwgfx_binding.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
* @index_buffer: Index buffer binding.
7979
* @per_shader: Per shader-type bindings.
8080
* @ua_views: UAV bindings.
81+
* @so_state: StreamOutput bindings.
8182
* @dirty: Bitmap tracking per binding-type changes that have not yet
8283
* been emitted to the device.
8384
* @dirty_vb: Bitmap tracking individual vertex buffer binding changes that
@@ -103,6 +104,7 @@ struct vmw_ctx_binding_state {
103104
struct vmw_ctx_bindinfo_ib index_buffer;
104105
struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE];
105106
struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE];
107+
struct vmw_ctx_bindinfo_so so_state;
106108

107109
unsigned long dirty;
108110
DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS);
@@ -127,6 +129,7 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind);
127129
static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind);
128130
static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
129131
static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
132+
static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind);
130133

131134
static void vmw_binding_build_asserts(void) __attribute__ ((unused));
132135

@@ -202,6 +205,9 @@ static const size_t vmw_binding_uav_offsets[] = {
202205
static const size_t vmw_binding_cs_uav_offsets[] = {
203206
offsetof(struct vmw_ctx_binding_state, ua_views[1].views),
204207
};
208+
static const size_t vmw_binding_so_offsets[] = {
209+
offsetof(struct vmw_ctx_binding_state, so_state),
210+
};
205211

206212
static const struct vmw_binding_info vmw_binding_infos[] = {
207213
[vmw_ctx_binding_shader] = {
@@ -256,6 +262,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = {
256262
.size = sizeof(struct vmw_ctx_bindinfo_view),
257263
.offsets = vmw_binding_cs_uav_offsets,
258264
.scrub_func = vmw_binding_scrub_cs_uav},
265+
[vmw_ctx_binding_so] = {
266+
.size = sizeof(struct vmw_ctx_bindinfo_so),
267+
.offsets = vmw_binding_so_offsets,
268+
.scrub_func = vmw_binding_scrub_so},
259269
};
260270

261271
/**
@@ -1290,6 +1300,33 @@ static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind)
12901300
return 0;
12911301
}
12921302

1303+
/**
1304+
* vmw_binding_scrub_so - Scrub a streamoutput binding from context.
1305+
* @bi: Single binding information.
1306+
* @rebind: Whether to issue a bind instead of scrub command.
1307+
*/
1308+
static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind)
1309+
{
1310+
struct vmw_ctx_bindinfo_so *binding =
1311+
container_of(bi, typeof(*binding), bi);
1312+
struct vmw_private *dev_priv = bi->ctx->dev_priv;
1313+
struct {
1314+
SVGA3dCmdHeader header;
1315+
SVGA3dCmdDXSetStreamOutput body;
1316+
} *cmd;
1317+
1318+
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
1319+
if (!cmd)
1320+
return -ENOMEM;
1321+
1322+
cmd->header.id = SVGA_3D_CMD_DX_SET_STREAMOUTPUT;
1323+
cmd->header.size = sizeof(cmd->body);
1324+
cmd->body.soid = rebind ? bi->res->id : SVGA3D_INVALID_ID;
1325+
vmw_fifo_commit(dev_priv, sizeof(*cmd));
1326+
1327+
return 0;
1328+
}
1329+
12931330
/**
12941331
* vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with
12951332
* memory accounting.
@@ -1393,7 +1430,7 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type)
13931430
};
13941431

13951432
/* Review this function as new bindings are added. */
1396-
BUILD_BUG_ON(vmw_ctx_binding_max != 13);
1433+
BUILD_BUG_ON(vmw_ctx_binding_max != 14);
13971434
return is_binding_dirtying[binding_type];
13981435
}
13991436

drivers/gpu/drm/vmwgfx/vmwgfx_binding.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ enum vmw_ctx_binding_type {
5555
vmw_ctx_binding_ib,
5656
vmw_ctx_binding_uav,
5757
vmw_ctx_binding_cs_uav,
58+
vmw_ctx_binding_so,
5859
vmw_ctx_binding_max
5960
};
6061

@@ -203,6 +204,16 @@ struct vmw_ctx_bindinfo_uav {
203204
uint32 index;
204205
};
205206

207+
/**
208+
* struct vmw_ctx_bindinfo_so - Stream output binding metadata.
209+
* @bi: struct vmw_ctx_bindinfo we derive from.
210+
* @slot: Device data used to reconstruct binding command.
211+
*/
212+
struct vmw_ctx_bindinfo_so {
213+
struct vmw_ctx_bindinfo bi;
214+
uint32 slot;
215+
};
216+
206217
extern void vmw_binding_add(struct vmw_ctx_binding_state *cbs,
207218
const struct vmw_ctx_bindinfo *ci,
208219
u32 shader_slot, u32 slot);

drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static const struct vmw_cotable_info co_info[] = {
8080
{1, sizeof(SVGACOTableDXDepthStencilEntry), NULL},
8181
{1, sizeof(SVGACOTableDXRasterizerStateEntry), NULL},
8282
{1, sizeof(SVGACOTableDXSamplerEntry), NULL},
83-
{1, sizeof(SVGACOTableDXStreamOutputEntry), NULL},
83+
{1, sizeof(SVGACOTableDXStreamOutputEntry), &vmw_dx_streamoutput_cotable_list_scrub},
8484
{1, sizeof(SVGACOTableDXQueryEntry), NULL},
8585
{1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub},
8686
{1, sizeof(SVGACOTableDXUAViewEntry), &vmw_view_cotable_list_destroy}

drivers/gpu/drm/vmwgfx/vmwgfx_drv.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ enum vmw_res_type {
202202
vmw_res_dx_context,
203203
vmw_res_cotable,
204204
vmw_res_view,
205+
vmw_res_streamoutput,
205206
vmw_res_max
206207
};
207208

@@ -210,7 +211,8 @@ enum vmw_res_type {
210211
*/
211212
enum vmw_cmdbuf_res_type {
212213
vmw_cmdbuf_res_shader,
213-
vmw_cmdbuf_res_view
214+
vmw_cmdbuf_res_view,
215+
vmw_cmdbuf_res_streamoutput
214216
};
215217

216218
struct vmw_cmdbuf_res_manager;
@@ -1307,6 +1309,24 @@ extern struct vmw_resource *
13071309
vmw_shader_lookup(struct vmw_cmdbuf_res_manager *man,
13081310
u32 user_key, SVGA3dShaderType shader_type);
13091311

1312+
/*
1313+
* Streamoutput management
1314+
*/
1315+
struct vmw_resource *
1316+
vmw_dx_streamoutput_lookup(struct vmw_cmdbuf_res_manager *man,
1317+
u32 user_key);
1318+
int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man,
1319+
struct vmw_resource *ctx,
1320+
SVGA3dStreamOutputId user_key,
1321+
struct list_head *list);
1322+
void vmw_dx_streamoutput_set_size(struct vmw_resource *res, u32 size);
1323+
int vmw_dx_streamoutput_remove(struct vmw_cmdbuf_res_manager *man,
1324+
SVGA3dStreamOutputId user_key,
1325+
struct list_head *list);
1326+
void vmw_dx_streamoutput_cotable_list_scrub(struct vmw_private *dev_priv,
1327+
struct list_head *list,
1328+
bool readback);
1329+
13101330
/*
13111331
* Command buffer managed resources - vmwgfx_cmdbuf_res.c
13121332
*/

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c

Lines changed: 170 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,6 +2948,169 @@ static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv,
29482948
return ret;
29492949
}
29502950

2951+
static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv,
2952+
struct vmw_sw_context *sw_context,
2953+
SVGA3dCmdHeader *header)
2954+
{
2955+
struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
2956+
struct vmw_resource *res;
2957+
struct {
2958+
SVGA3dCmdHeader header;
2959+
SVGA3dCmdDXDefineStreamOutputWithMob body;
2960+
} *cmd = container_of(header, typeof(*cmd), header);
2961+
int ret;
2962+
2963+
if (!has_sm5_context(dev_priv))
2964+
return -EINVAL;
2965+
2966+
if (!ctx_node) {
2967+
DRM_ERROR("DX Context not set.\n");
2968+
return -EINVAL;
2969+
}
2970+
2971+
res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT);
2972+
ret = vmw_cotable_notify(res, cmd->body.soid);
2973+
if (ret)
2974+
return ret;
2975+
2976+
return vmw_dx_streamoutput_add(sw_context->man, ctx_node->ctx,
2977+
cmd->body.soid,
2978+
&sw_context->staged_cmd_res);
2979+
}
2980+
2981+
static int vmw_cmd_dx_destroy_streamoutput(struct vmw_private *dev_priv,
2982+
struct vmw_sw_context *sw_context,
2983+
SVGA3dCmdHeader *header)
2984+
{
2985+
struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
2986+
struct vmw_resource *res;
2987+
struct {
2988+
SVGA3dCmdHeader header;
2989+
SVGA3dCmdDXDestroyStreamOutput body;
2990+
} *cmd = container_of(header, typeof(*cmd), header);
2991+
2992+
if (!ctx_node) {
2993+
DRM_ERROR("DX Context not set.\n");
2994+
return -EINVAL;
2995+
}
2996+
2997+
/*
2998+
* When device does not support SM5 then streamoutput with mob command is
2999+
* not available to user-space. Simply return in this case.
3000+
*/
3001+
if (!has_sm5_context(dev_priv))
3002+
return 0;
3003+
3004+
/*
3005+
* With SM5 capable device if lookup fails then user-space probably used
3006+
* old streamoutput define command. Return without an error.
3007+
*/
3008+
res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3009+
cmd->body.soid);
3010+
if (IS_ERR(res))
3011+
return 0;
3012+
3013+
return vmw_dx_streamoutput_remove(sw_context->man, cmd->body.soid,
3014+
&sw_context->staged_cmd_res);
3015+
}
3016+
3017+
static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv,
3018+
struct vmw_sw_context *sw_context,
3019+
SVGA3dCmdHeader *header)
3020+
{
3021+
struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3022+
struct vmw_resource *res;
3023+
struct {
3024+
SVGA3dCmdHeader header;
3025+
SVGA3dCmdDXBindStreamOutput body;
3026+
} *cmd = container_of(header, typeof(*cmd), header);
3027+
int ret;
3028+
3029+
if (!has_sm5_context(dev_priv))
3030+
return -EINVAL;
3031+
3032+
if (!ctx_node) {
3033+
DRM_ERROR("DX Context not set.\n");
3034+
return -EINVAL;
3035+
}
3036+
3037+
res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3038+
cmd->body.soid);
3039+
if (IS_ERR(res)) {
3040+
DRM_ERROR("Cound not find streamoutput to bind.\n");
3041+
return PTR_ERR(res);
3042+
}
3043+
3044+
vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes);
3045+
3046+
ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3047+
VMW_RES_DIRTY_NONE);
3048+
if (ret) {
3049+
DRM_ERROR("Error creating resource validation node.\n");
3050+
return ret;
3051+
}
3052+
3053+
return vmw_cmd_res_switch_backup(dev_priv, sw_context, res,
3054+
&cmd->body.mobid,
3055+
cmd->body.offsetInBytes);
3056+
}
3057+
3058+
static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv,
3059+
struct vmw_sw_context *sw_context,
3060+
SVGA3dCmdHeader *header)
3061+
{
3062+
struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3063+
struct vmw_resource *res;
3064+
struct vmw_ctx_bindinfo_so binding;
3065+
struct {
3066+
SVGA3dCmdHeader header;
3067+
SVGA3dCmdDXSetStreamOutput body;
3068+
} *cmd = container_of(header, typeof(*cmd), header);
3069+
int ret;
3070+
3071+
if (!ctx_node) {
3072+
DRM_ERROR("DX Context not set.\n");
3073+
return -EINVAL;
3074+
}
3075+
3076+
if (cmd->body.soid == SVGA3D_INVALID_ID)
3077+
return 0;
3078+
3079+
/*
3080+
* When device does not support SM5 then streamoutput with mob command is
3081+
* not available to user-space. Simply return in this case.
3082+
*/
3083+
if (!has_sm5_context(dev_priv))
3084+
return 0;
3085+
3086+
/*
3087+
* With SM5 capable device if lookup fails then user-space probably used
3088+
* old streamoutput define command. Return without an error.
3089+
*/
3090+
res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3091+
cmd->body.soid);
3092+
if (IS_ERR(res)) {
3093+
return 0;
3094+
}
3095+
3096+
ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3097+
VMW_RES_DIRTY_NONE);
3098+
if (ret) {
3099+
DRM_ERROR("Error creating resource validation node.\n");
3100+
return ret;
3101+
}
3102+
3103+
binding.bi.ctx = ctx_node->ctx;
3104+
binding.bi.res = res;
3105+
binding.bi.bt = vmw_ctx_binding_so;
3106+
binding.slot = 0; /* Only one SO set to context at a time. */
3107+
3108+
vmw_binding_add(sw_context->dx_ctx_node->staged, &binding.bi, 0,
3109+
binding.slot);
3110+
3111+
return ret;
3112+
}
3113+
29513114
static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv,
29523115
struct vmw_sw_context *sw_context,
29533116
SVGA3dCmdHeader *header)
@@ -3330,9 +3493,9 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
33303493
VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT,
33313494
&vmw_cmd_dx_so_define, true, false, true),
33323495
VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT,
3333-
&vmw_cmd_dx_cid_check, true, false, true),
3334-
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, &vmw_cmd_dx_cid_check,
3335-
true, false, true),
3496+
&vmw_cmd_dx_destroy_streamoutput, true, false, true),
3497+
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT,
3498+
&vmw_cmd_dx_set_streamoutput, true, false, true),
33363499
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SOTARGETS,
33373500
&vmw_cmd_dx_set_so_targets, true, false, true),
33383501
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT,
@@ -3375,6 +3538,10 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
33753538
false, true),
33763539
VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2,
33773540
&vmw_cmd_sm5_view_define, true, false, true),
3541+
VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB,
3542+
&vmw_cmd_dx_define_streamoutput, true, false, true),
3543+
VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_STREAMOUTPUT,
3544+
&vmw_cmd_dx_bind_streamoutput, true, false, true),
33783545
};
33793546

33803547
bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd)

drivers/gpu/drm/vmwgfx/vmwgfx_so.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ static inline enum vmw_so_type vmw_so_cmd_to_type(u32 id)
129129
case SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE:
130130
return vmw_so_ss;
131131
case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT:
132+
case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB:
132133
case SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT:
133134
return vmw_so_so;
134135
default:

0 commit comments

Comments
 (0)