diff options
author | Deepak Rawat <drawat.floss@gmail.com> | 2018-12-13 13:51:08 -0800 |
---|---|---|
committer | Roland Scheidegger <sroland@vmware.com> | 2020-03-23 22:39:34 +0100 |
commit | 5e8ec0d919a4911f7cde01affa2bfd78a74b9b0f (patch) | |
tree | efab0451c314d4b9a56fb3b8a11802439015b19a /drivers | |
parent | d2e90ab3744f911c45823b3390fda25b102e76ee (diff) |
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 <drawat.floss@gmail.com>
Signed-off-by: Neha Bhende <bhenden@vmware.com>
Reviewed-by: Thomas Hellström (VMware) <thomas_os@shipmail.org>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Signed-off-by: Roland Scheidegger <sroland@vmware.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 129 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 144 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_so.h | 6 |
7 files changed, 319 insertions, 18 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index 5a7e8db3e826..f0a576698266 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -59,7 +59,9 @@ #define VMW_BINDING_PS_BIT 1 #define VMW_BINDING_SO_BIT 2 #define VMW_BINDING_VB_BIT 3 -#define VMW_BINDING_NUM_BITS 4 +#define VMW_BINDING_UAV_BIT 4 +#define VMW_BINDING_CS_UAV_BIT 5 +#define VMW_BINDING_NUM_BITS 6 #define VMW_BINDING_PS_SR_BIT 0 @@ -75,6 +77,7 @@ * @vertex_buffers: Vertex buffer bindings. * @index_buffer: Index buffer binding. * @per_shader: Per shader-type bindings. + * @ua_views: UAV bindings. * @dirty: Bitmap tracking per binding-type changes that have not yet * been emitted to the device. * @dirty_vb: Bitmap tracking individual vertex buffer binding changes that @@ -99,6 +102,7 @@ struct vmw_ctx_binding_state { struct vmw_ctx_bindinfo_vb vertex_buffers[SVGA3D_DX_MAX_VERTEXBUFFERS]; struct vmw_ctx_bindinfo_ib index_buffer; struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE]; + struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE]; unsigned long dirty; DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS); @@ -121,6 +125,9 @@ static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind); + static void vmw_binding_build_asserts(void) __attribute__ ((unused)); typedef int (*vmw_scrub_func)(struct vmw_ctx_bindinfo *, bool); @@ -189,6 +196,12 @@ static const size_t vmw_binding_vb_offsets[] = { static const size_t vmw_binding_ib_offsets[] = { offsetof(struct vmw_ctx_binding_state, index_buffer), }; +static const size_t vmw_binding_uav_offsets[] = { + offsetof(struct vmw_ctx_binding_state, ua_views[0].views), +}; +static const size_t vmw_binding_cs_uav_offsets[] = { + offsetof(struct vmw_ctx_binding_state, ua_views[1].views), +}; static const struct vmw_binding_info vmw_binding_infos[] = { [vmw_ctx_binding_shader] = { @@ -235,6 +248,14 @@ static const struct vmw_binding_info vmw_binding_infos[] = { .size = sizeof(struct vmw_ctx_bindinfo_ib), .offsets = vmw_binding_ib_offsets, .scrub_func = vmw_binding_scrub_ib}, + [vmw_ctx_binding_uav] = { + .size = sizeof(struct vmw_ctx_bindinfo_view), + .offsets = vmw_binding_uav_offsets, + .scrub_func = vmw_binding_scrub_uav}, + [vmw_ctx_binding_cs_uav] = { + .size = sizeof(struct vmw_ctx_bindinfo_view), + .offsets = vmw_binding_cs_uav_offsets, + .scrub_func = vmw_binding_scrub_cs_uav}, }; /** @@ -321,6 +342,18 @@ void vmw_binding_add(struct vmw_ctx_binding_state *cbs, } /** + * vmw_binding_add_uav_index - Add UAV index for tracking. + * @cbs: Pointer to the context binding state tracker. + * @slot: UAV type to which bind this index. + * @index: The splice index to track. + */ +void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs, uint32 slot, + uint32 index) +{ + cbs->ua_views[slot].index = index; +} + +/** * vmw_binding_transfer: Transfer a context binding tracking entry. * * @cbs: Pointer to the persistent context binding state tracker. @@ -459,6 +492,10 @@ void vmw_binding_state_commit(struct vmw_ctx_binding_state *to, vmw_binding_transfer(to, from, entry); vmw_binding_drop(entry); } + + /* Also transfer uav splice indices */ + to->ua_views[0].index = from->ua_views[0].index; + to->ua_views[1].index = from->ua_views[1].index; } /** @@ -1014,6 +1051,66 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs) return 0; } +static int vmw_emit_set_uav(struct vmw_ctx_binding_state *cbs) +{ + const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[0].views[0].bi; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetUAViews body; + } *cmd; + size_t cmd_size, view_id_size; + const struct vmw_resource *ctx = vmw_cbs_context(cbs); + + vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS); + view_id_size = cbs->bind_cmd_count*sizeof(uint32); + cmd_size = sizeof(*cmd) + view_id_size; + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_UA_VIEWS; + cmd->header.size = sizeof(cmd->body) + view_id_size; + + /* Splice index is specified user-space */ + cmd->body.uavSpliceIndex = cbs->ua_views[0].index; + + memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size); + + vmw_fifo_commit(ctx->dev_priv, cmd_size); + + return 0; +} + +static int vmw_emit_set_cs_uav(struct vmw_ctx_binding_state *cbs) +{ + const struct vmw_ctx_bindinfo *loc = &cbs->ua_views[1].views[0].bi; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetCSUAViews body; + } *cmd; + size_t cmd_size, view_id_size; + const struct vmw_resource *ctx = vmw_cbs_context(cbs); + + vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_UAVIEWS); + view_id_size = cbs->bind_cmd_count*sizeof(uint32); + cmd_size = sizeof(*cmd) + view_id_size; + cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_CS_UA_VIEWS; + cmd->header.size = sizeof(cmd->body) + view_id_size; + + /* Start index is specified user-space */ + cmd->body.startIndex = cbs->ua_views[1].index; + + memcpy(&cmd[1], cbs->bind_cmd_buffer, view_id_size); + + vmw_fifo_commit(ctx->dev_priv, cmd_size); + + return 0; +} + /** * vmw_binding_emit_dirty - Issue delayed binding commands * @@ -1045,6 +1142,12 @@ static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs) case VMW_BINDING_VB_BIT: ret = vmw_emit_set_vb(cbs); break; + case VMW_BINDING_UAV_BIT: + ret = vmw_emit_set_uav(cbs); + break; + case VMW_BINDING_CS_UAV_BIT: + ret = vmw_emit_set_cs_uav(cbs); + break; default: BUG(); } @@ -1171,6 +1274,22 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind) return 0; } +static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); + + __set_bit(VMW_BINDING_UAV_BIT, &cbs->dirty); + return 0; +} + +static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); + + __set_bit(VMW_BINDING_CS_UAV_BIT, &cbs->dirty); + return 0; +} + /** * vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with * memory accounting. @@ -1257,8 +1376,8 @@ void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs) * Each time a resource is put on the validation list as the result of a * context binding referencing it, we need to determine whether that resource * will be dirtied (written to by the GPU) as a result of the corresponding - * GPU operation. Currently rendertarget-, depth-stencil-, and - * stream-output-target bindings are capable of dirtying its resource. + * GPU operation. Currently rendertarget-, depth-stencil-, stream-output-target + * and unordered access view bindings are capable of dirtying its resource. * * Return: Whether the binding type dirties the resource its binding points to. */ @@ -1269,10 +1388,12 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type) [vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_so] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_uav] = VMW_RES_DIRTY_SET, + [vmw_ctx_binding_cs_uav] = VMW_RES_DIRTY_SET, }; /* Review this function as new bindings are added. */ - BUILD_BUG_ON(vmw_ctx_binding_max != 11); + BUILD_BUG_ON(vmw_ctx_binding_max != 13); return is_binding_dirtying[binding_type]; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h index cd9805c045cb..da67cbc9cd73 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h @@ -33,6 +33,8 @@ #define VMW_MAX_VIEW_BINDINGS 128 +#define VMW_MAX_UAV_BIND_TYPE 2 + struct vmw_private; struct vmw_ctx_binding_state; @@ -51,6 +53,8 @@ enum vmw_ctx_binding_type { vmw_ctx_binding_so, vmw_ctx_binding_vb, vmw_ctx_binding_ib, + vmw_ctx_binding_uav, + vmw_ctx_binding_cs_uav, vmw_ctx_binding_max }; @@ -189,9 +193,21 @@ struct vmw_dx_shader_bindings { unsigned long dirty; }; +/** + * struct vmw_ctx_bindinfo_uav - UAV context binding state. + * @views: UAV view bindings. + * @splice_index: The device splice index set by user-space. + */ +struct vmw_ctx_bindinfo_uav { + struct vmw_ctx_bindinfo_view views[SVGA3D_MAX_UAVIEWS]; + uint32 index; +}; + extern void vmw_binding_add(struct vmw_ctx_binding_state *cbs, const struct vmw_ctx_bindinfo *ci, u32 shader_slot, u32 slot); +extern void vmw_binding_add_uav_index(struct vmw_ctx_binding_state *cbs, + uint32 slot, uint32 splice_index); extern void vmw_binding_state_commit(struct vmw_ctx_binding_state *to, struct vmw_ctx_binding_state *from); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index 0477d9a74fe8..61c246335e66 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -36,7 +36,7 @@ struct vmw_user_context { struct vmw_resource res; struct vmw_ctx_binding_state *cbs; struct vmw_cmdbuf_res_manager *man; - struct vmw_resource *cotables[SVGA_COTABLE_DX10_MAX]; + struct vmw_resource *cotables[SVGA_COTABLE_MAX]; spinlock_t cotable_lock; struct vmw_buffer_object *dx_query_mob; }; @@ -116,12 +116,15 @@ static const struct vmw_res_func vmw_dx_context_func = { * Context management: */ -static void vmw_context_cotables_unref(struct vmw_user_context *uctx) +static void vmw_context_cotables_unref(struct vmw_private *dev_priv, + struct vmw_user_context *uctx) { struct vmw_resource *res; int i; + u32 cotable_max = has_sm5_context(dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + for (i = 0; i < cotable_max; ++i) { spin_lock(&uctx->cotable_lock); res = uctx->cotables[i]; uctx->cotables[i] = NULL; @@ -155,7 +158,7 @@ static void vmw_hw_context_destroy(struct vmw_resource *res) !dev_priv->query_cid_valid) __vmw_execbuf_release_pinned_bo(dev_priv, NULL); mutex_unlock(&dev_priv->cmdbuf_mutex); - vmw_context_cotables_unref(uctx); + vmw_context_cotables_unref(dev_priv, uctx); return; } @@ -208,7 +211,9 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, spin_lock_init(&uctx->cotable_lock); if (dx) { - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + u32 cotable_max = has_sm5_context(dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; + for (i = 0; i < cotable_max; ++i) { uctx->cotables[i] = vmw_cotable_alloc(dev_priv, &uctx->res, i); if (IS_ERR(uctx->cotables[i])) { @@ -222,7 +227,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv, return 0; out_cotables: - vmw_context_cotables_unref(uctx); + vmw_context_cotables_unref(dev_priv, uctx); out_err: if (res_free) res_free(res); @@ -545,10 +550,12 @@ void vmw_dx_context_scrub_cotables(struct vmw_resource *ctx, { struct vmw_user_context *uctx = container_of(ctx, struct vmw_user_context, res); + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; int i; vmw_binding_state_scrub(uctx->cbs); - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + for (i = 0; i < cotable_max; ++i) { struct vmw_resource *res; /* Avoid racing with ongoing cotable destruction. */ @@ -839,7 +846,10 @@ struct vmw_cmdbuf_res_manager *vmw_context_res_man(struct vmw_resource *ctx) struct vmw_resource *vmw_context_cotable(struct vmw_resource *ctx, SVGACOTableType cotable_type) { - if (cotable_type >= SVGA_COTABLE_DX10_MAX) + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; + + if (cotable_type >= cotable_max) return ERR_PTR(-EINVAL); return container_of(ctx, struct vmw_user_context, res)-> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 3ca5cf375b01..08c5b2ccca98 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -82,7 +82,8 @@ static const struct vmw_cotable_info co_info[] = { {1, sizeof(SVGACOTableDXSamplerEntry), NULL}, {1, sizeof(SVGACOTableDXStreamOutputEntry), NULL}, {1, sizeof(SVGACOTableDXQueryEntry), NULL}, - {1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub} + {1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub}, + {1, sizeof(SVGACOTableDXUAViewEntry), &vmw_view_cotable_list_destroy} }; /* @@ -102,6 +103,7 @@ const SVGACOTableType vmw_cotable_scrub_order[] = { SVGA_COTABLE_SAMPLER, SVGA_COTABLE_STREAMOUTPUT, SVGA_COTABLE_DXQUERY, + SVGA_COTABLE_UAVIEW, }; static int vmw_cotable_bind(struct vmw_resource *res, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 4abed135c013..ed56d9918c6a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -459,11 +459,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, int ret = 0; struct vmw_resource *res; u32 i; + u32 cotable_max = has_sm5_context(ctx->dev_priv) ? + SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX; /* Add all cotables to the validation list. */ if (has_sm4_context(dev_priv) && vmw_res_type(ctx) == vmw_res_dx_context) { - for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { + for (i = 0; i < cotable_max; ++i) { res = vmw_context_cotable(ctx, i); if (IS_ERR(res)) continue; @@ -2814,6 +2816,128 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, &cmd->body.surface.sid, NULL); } +static int vmw_cmd_sm5_view_define(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_dx_view_define(dev_priv, sw_context, header); +} + +static int vmw_cmd_sm5_view_remove(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_dx_view_remove(dev_priv, sw_context, header); +} + +static int vmw_cmd_clear_uav_uint(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXClearUAViewUint body; + } *cmd = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + ret = vmw_view_id_val_add(sw_context, vmw_view_ua, + cmd->body.uaViewId); + + return PTR_ERR_OR_ZERO(ret); +} + +static int vmw_cmd_clear_uav_float(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXClearUAViewFloat body; + } *cmd = container_of(header, typeof(*cmd), header); + struct vmw_resource *ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + ret = vmw_view_id_val_add(sw_context, vmw_view_ua, + cmd->body.uaViewId); + + return PTR_ERR_OR_ZERO(ret); +} + +static int vmw_cmd_set_uav(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetUAViews body; + } *cmd = container_of(header, typeof(*cmd), header); + u32 num_uav = (cmd->header.size - sizeof(cmd->body)) / + sizeof(SVGA3dUAViewId); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (num_uav > SVGA3D_MAX_UAVIEWS) { + VMW_DEBUG_USER("Invalid UAV binding.\n"); + return -EINVAL; + } + + ret = vmw_view_bindings_add(sw_context, vmw_view_ua, + vmw_ctx_binding_uav, 0, (void *)&cmd[1], + num_uav, 0); + if (ret) + return ret; + + vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 0, + cmd->body.uavSpliceIndex); + + return ret; +} + +static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetCSUAViews body; + } *cmd = container_of(header, typeof(*cmd), header); + u32 num_uav = (cmd->header.size - sizeof(cmd->body)) / + sizeof(SVGA3dUAViewId); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (num_uav > SVGA3D_MAX_UAVIEWS) { + VMW_DEBUG_USER("Invalid UAV binding.\n"); + return -EINVAL; + } + + ret = vmw_view_bindings_add(sw_context, vmw_view_ua, + vmw_ctx_binding_cs_uav, 0, (void *)&cmd[1], + num_uav, 0); + if (ret) + return ret; + + vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 1, + cmd->body.startIndex); + + return ret; +} + static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, void *buf, uint32_t *size) @@ -3163,6 +3287,24 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_INTRA_SURFACE_COPY, &vmw_cmd_intra_surface_copy, true, false, true), + + /* + * SM5 commands + */ + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_UA_VIEW, &vmw_cmd_sm5_view_define, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_UA_VIEW, &vmw_cmd_sm5_view_remove, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT, &vmw_cmd_clear_uav_uint, + true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT, + &vmw_cmd_clear_uav_float, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT, &vmw_cmd_invalid, true, + false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_UA_VIEWS, &vmw_cmd_set_uav, true, false, + true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_CS_UA_VIEWS, &vmw_cmd_set_cs_uav, true, + false, true), }; bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c index 63807361e16f..3f97b61dd5d8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.c @@ -319,7 +319,8 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man, static const size_t vmw_view_define_sizes[] = { [vmw_view_sr] = sizeof(SVGA3dCmdDXDefineShaderResourceView), [vmw_view_rt] = sizeof(SVGA3dCmdDXDefineRenderTargetView), - [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView) + [vmw_view_ds] = sizeof(SVGA3dCmdDXDefineDepthStencilView), + [vmw_view_ua] = sizeof(SVGA3dCmdDXDefineUAView) }; struct vmw_private *dev_priv = ctx->dev_priv; @@ -499,8 +500,8 @@ struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man, * Each time a resource is put on the validation list as the result of a * view pointing to it, we need to determine whether that resource will * be dirtied (written to by the GPU) as a result of the corresponding - * GPU operation. Currently only rendertarget- and depth-stencil views are - * capable of dirtying its resource. + * GPU operation. Currently only rendertarget-, depth-stencil and unordered + * access views are capable of dirtying its resource. * * Return: Whether the view type of @res dirties the resource it points to. */ @@ -509,10 +510,11 @@ u32 vmw_view_dirtying(struct vmw_resource *res) static u32 view_is_dirtying[vmw_view_max] = { [vmw_view_rt] = VMW_RES_DIRTY_SET, [vmw_view_ds] = VMW_RES_DIRTY_SET, + [vmw_view_ua] = VMW_RES_DIRTY_SET, }; /* Update this function as we add more view types */ - BUILD_BUG_ON(vmw_view_max != 3); + BUILD_BUG_ON(vmw_view_max != 4); return view_is_dirtying[vmw_view(res)->view_type]; } @@ -520,12 +522,14 @@ const u32 vmw_view_destroy_cmds[] = { [vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW, [vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW, [vmw_view_ds] = SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW, + [vmw_view_ua] = SVGA_3D_CMD_DX_DESTROY_UA_VIEW, }; const SVGACOTableType vmw_view_cotables[] = { [vmw_view_sr] = SVGA_COTABLE_SRVIEW, [vmw_view_rt] = SVGA_COTABLE_RTVIEW, [vmw_view_ds] = SVGA_COTABLE_DSVIEW, + [vmw_view_ua] = SVGA_COTABLE_UAVIEW, }; const SVGACOTableType vmw_so_cotables[] = { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h index 12565047bc55..22b4f5720908 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h @@ -30,6 +30,7 @@ enum vmw_view_type { vmw_view_sr, vmw_view_rt, vmw_view_ds, + vmw_view_ua, vmw_view_max, }; @@ -61,6 +62,7 @@ union vmw_view_destroy { struct SVGA3dCmdDXDestroyRenderTargetView rtv; struct SVGA3dCmdDXDestroyShaderResourceView srv; struct SVGA3dCmdDXDestroyDepthStencilView dsv; + struct SVGA3dCmdDXDestroyUAView uav; u32 view_id; }; @@ -87,6 +89,10 @@ static inline enum vmw_view_type vmw_view_cmd_to_type(u32 id) { u32 tmp = (id - SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW) / 2; + if (id == SVGA_3D_CMD_DX_DEFINE_UA_VIEW || + id == SVGA_3D_CMD_DX_DESTROY_UA_VIEW) + return vmw_view_ua; + if (tmp > (u32)vmw_view_max) return vmw_view_max; |