From ef7c7b7497d6aba37a8932205411c872972dae5d Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 11:36:31 -0800 Subject: drm/vmwgfx: Also check for SVGA_CAP_DX before reading DX context support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Virtual device consider SVGA_CAP_DX and SVGA3D_DEVCAP_DXCONTEXT independent of each other. Some of the commands in cmd_buf depends on SVGA_CAP_DX, so better to check for that as well. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4f58364421ce..f976dabe18de 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -883,7 +883,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) } } - if (dev_priv->has_mob) { + if (dev_priv->has_mob && (dev_priv->capabilities & SVGA_CAP_DX)) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); -- cgit 1.4.1 From 0652ff336386322a866df314fee193d5e035b6c8 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 11:51:14 -0800 Subject: drm/vmwgfx: Sync legacy multisampling device capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In favor of SM4.1 multisampling capability, virtual device deprecated old multisampling device capability. Mark legacy multisampling device capability as dead. Rename the function that masks legacy multisample capability to reflect that now it is masking a deprecated feature. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h | 13 +++++++++---- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 11 +++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h index f256560049bf..2de878b5ba16 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h @@ -163,10 +163,15 @@ typedef enum { SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = 67, SVGA3D_DEVCAP_SURFACEFMT_UYVY = 68, SVGA3D_DEVCAP_SURFACEFMT_YUY2 = 69, - SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES = 70, - SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES = 71, - SVGA3D_DEVCAP_ALPHATOCOVERAGE = 72, - SVGA3D_DEVCAP_SUPERSAMPLE = 73, + + /* + * Deprecated. + */ + SVGA3D_DEVCAP_DEAD4 = 70, + SVGA3D_DEVCAP_DEAD5 = 71, + SVGA3D_DEVCAP_DEAD7 = 72, + SVGA3D_DEVCAP_DEAD6 = 73, + SVGA3D_DEVCAP_AUTOGENMIPMAPS = 74, SVGA3D_DEVCAP_SURFACEFMT_NV12 = 75, SVGA3D_DEVCAP_SURFACEFMT_AYUV = 76, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index a15375eb476e..09b255465f99 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -126,14 +126,17 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, return 0; } -static u32 vmw_mask_multisample(unsigned int cap, u32 fmt_value) +static u32 vmw_mask_legacy_multisample(unsigned int cap, u32 fmt_value) { /* * A version of user-space exists which use MULTISAMPLE_MASKABLESAMPLES * to check the sample count supported by virtual device. Since there * never was support for multisample count for backing MOB return 0. + * + * MULTISAMPLE_MASKABLESAMPLES devcap is marked as deprecated by virtual + * device. */ - if (cap == SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES) + if (cap == SVGA3D_DEVCAP_DEAD5) return 0; return fmt_value; @@ -164,7 +167,7 @@ static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, for (i = 0; i < max_size; ++i) { vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); compat_cap->pairs[i][0] = i; - compat_cap->pairs[i][1] = vmw_mask_multisample + compat_cap->pairs[i][1] = vmw_mask_legacy_multisample (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); } spin_unlock(&dev_priv->cap_lock); @@ -220,7 +223,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, spin_lock(&dev_priv->cap_lock); for (i = 0; i < num; ++i) { vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); - *bounce32++ = vmw_mask_multisample + *bounce32++ = vmw_mask_legacy_multisample (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); } spin_unlock(&dev_priv->cap_lock); -- cgit 1.4.1 From 3d143954229ef89ca7bae5fe260ab77496f6582c Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 11:55:57 -0800 Subject: drm/vmwgfx: Deprecate logic ops commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logic ops commands are marked as deprecated by virtual device and were never used by vmwgfx. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h | 12 ++++++------ drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 18 ++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h index 9cbba0e8ce6a..84ea8d385b0e 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h @@ -104,12 +104,12 @@ typedef enum { SVGA_3D_CMD_DEAD1 = 1083, SVGA_3D_CMD_DEAD2 = 1084, - SVGA_3D_CMD_LOGICOPS_BITBLT = 1085, - SVGA_3D_CMD_LOGICOPS_TRANSBLT = 1086, - SVGA_3D_CMD_LOGICOPS_STRETCHBLT = 1087, - SVGA_3D_CMD_LOGICOPS_COLORFILL = 1088, - SVGA_3D_CMD_LOGICOPS_ALPHABLEND = 1089, - SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND = 1090, + SVGA_3D_CMD_DEAD12 = 1085, + SVGA_3D_CMD_DEAD13 = 1086, + SVGA_3D_CMD_DEAD14 = 1087, + SVGA_3D_CMD_DEAD15 = 1088, + SVGA_3D_CMD_DEAD16 = 1089, + SVGA_3D_CMD_DEAD17 = 1090, SVGA_3D_CMD_SET_OTABLE_BASE = 1091, SVGA_3D_CMD_READBACK_OTABLE = 1092, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 73489a45decb..74a2c7ec9198 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2922,18 +2922,12 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { false, false, false), VMW_CMD_DEF(SVGA_3D_CMD_DEAD2, &vmw_cmd_invalid, false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_BITBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_TRANSBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_STRETCHBLT, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_COLORFILL, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_ALPHABLEND, &vmw_cmd_invalid, - false, false, false), - VMW_CMD_DEF(SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND, &vmw_cmd_invalid, - false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD12, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD13, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD14, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD15, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD16, &vmw_cmd_invalid, false, false, false), + VMW_CMD_DEF(SVGA_3D_CMD_DEAD17, &vmw_cmd_invalid, false, false, false), VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE, &vmw_cmd_invalid, false, false, true), VMW_CMD_DEF(SVGA_3D_CMD_READBACK_OTABLE, &vmw_cmd_invalid, -- cgit 1.4.1 From 878c6ecd3e24dc215a9f5e1c32b9873be35c1ff0 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 11:44:42 -0800 Subject: drm/vmwgfx: Use enum to represent graphics context capabilities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of having different bool in device private to represent incremental graphics context capabilities, add a new sm type enum. v2: Use enum instead of bit flag. v3: Incorporated review comments. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 34 ++++++++++++++-------------- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 40 +++++++++++++++++++++++++++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 6 +++-- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 4 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_mob.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 10 ++++----- 8 files changed, 69 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index a56c9d802382..0477d9a74fe8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -731,7 +731,7 @@ static int vmw_context_define(struct drm_device *dev, void *data, }; int ret; - if (!dev_priv->has_dx && dx) { + if (!has_sm4_context(dev_priv) && dx) { VMW_DEBUG_USER("DX contexts not supported by device.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index f976dabe18de..5277b9832d58 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -449,7 +449,7 @@ static int vmw_request_device(struct vmw_private *dev_priv) dev_priv->cman = vmw_cmdbuf_man_create(dev_priv); if (IS_ERR(dev_priv->cman)) { dev_priv->cman = NULL; - dev_priv->has_dx = false; + dev_priv->sm_type = VMW_SM_LEGACY; } ret = vmw_request_device_late(dev_priv); @@ -886,11 +886,22 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv->has_mob && (dev_priv->capabilities & SVGA_CAP_DX)) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); - dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4; spin_unlock(&dev_priv->cap_lock); } vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); + + /* SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 support */ + if (has_sm4_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX2)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM41); + + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4_1; + } + ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) goto out_no_kms; @@ -900,23 +911,12 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) goto out_no_fifo; - if (dev_priv->has_dx) { - /* - * SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 - * support - */ - if ((dev_priv->capabilities2 & SVGA_CAP2_DX2) != 0) { - vmw_write(dev_priv, SVGA_REG_DEV_CAP, - SVGA3D_DEVCAP_SM41); - dev_priv->has_sm4_1 = vmw_read(dev_priv, - SVGA_REG_DEV_CAP); - } - } - - DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) ? "yes." : "no."); - DRM_INFO("SM4_1: %s\n", dev_priv->has_sm4_1 ? "yes." : "no."); + if (dev_priv->sm_type == VMW_SM_4_1) + DRM_INFO("SM4_1 support available.\n"); + if (dev_priv->sm_type == VMW_SM_4) + DRM_INFO("SM4 support available.\n"); snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index b70d73225707..243731813887 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -441,6 +441,20 @@ enum { VMW_IRQTHREAD_MAX }; +/** + * enum vmw_sm_type - Graphics context capability supported by device. + * @VMW_SM_LEGACY: Pre DX context. + * @VMW_SM_4: Context support upto SM4. + * @VMW_SM_4_1: Context support upto SM4_1. + * @VMW_SM_MAX: Should be the last. + */ +enum vmw_sm_type { + VMW_SM_LEGACY = 0, + VMW_SM_4, + VMW_SM_4_1, + VMW_SM_MAX +}; + struct vmw_private { struct ttm_bo_device bdev; @@ -475,9 +489,9 @@ struct vmw_private { bool has_mob; spinlock_t hw_lock; spinlock_t cap_lock; - bool has_dx; bool assume_16bpp; - bool has_sm4_1; + + enum vmw_sm_type sm_type; /* * Framebuffer info. @@ -648,6 +662,28 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, return val; } +/** + * has_sm4_context - Does the device support SM4 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4 context or not. + */ +static inline bool has_sm4_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4); +} + +/** + * has_sm4_1_context - Does the device support SM4_1 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4_1 context or not. + */ +static inline bool has_sm4_1_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4_1); +} + extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 74a2c7ec9198..73f19f0fec88 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -461,7 +461,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, u32 i; /* Add all cotables to the validation list. */ - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { res = vmw_context_cotable(ctx, i); if (IS_ERR(res)) @@ -489,7 +490,8 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv, break; } - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { struct vmw_buffer_object *dx_query_mob; dx_query_mob = vmw_context_get_dx_query_mob(ctx); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 09b255465f99..0af42875ba4e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -114,10 +114,10 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, (dev_priv->active_display_unit == vmw_du_screen_target); break; case DRM_VMW_PARAM_DX: - param->value = dev_priv->has_dx; + param->value = has_sm4_context(dev_priv); break; case DRM_VMW_PARAM_SM4_1: - param->value = dev_priv->has_sm4_1; + param->value = has_sm4_1_context(dev_priv); break; default: return -EINVAL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 52e086a5691e..04b79e8975ce 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -941,7 +941,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * For DX, surface format validation is done when surface->scanout * is set. */ - if (!dev_priv->has_dx && format != surface->format) { + if (!has_sm4_context(dev_priv) && format != surface->format) { DRM_ERROR("Invalid surface format for requested mode.\n"); return -EINVAL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index 0a6bbac00896..e8eb42933ca2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -320,7 +320,7 @@ int vmw_otables_setup(struct vmw_private *dev_priv) struct vmw_otable **otables = &dev_priv->otable_batch.otables; int ret; - if (dev_priv->has_dx) { + if (has_sm4_context(dev_priv)) { *otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL); if (!(*otables)) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index ec893cd17b50..4bad6e2a700d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1092,12 +1092,12 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); } else if (srf->array_size > 0) { - /* has_dx checked on creation time. */ + /* VMW_SM_4 support verified at creation time. */ cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2; cmd_len = sizeof(cmd2->body); submit_len = sizeof(*cmd2); @@ -1115,7 +1115,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; @@ -1443,7 +1443,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, } /* array_size must be null for non-GL3 host. */ - if (array_size > 0 && !dev_priv->has_dx) { + if (array_size > 0 && !has_sm4_context(dev_priv)) { VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); return -EINVAL; } @@ -1601,7 +1601,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits, req->base.svga3d_flags); - if (!dev_priv->has_sm4_1) { + if (!has_sm4_1_context(dev_priv)) { /* * If SM4_1 is not support then cannot send 64-bit flag to * device. -- cgit 1.4.1 From 0651dfabd96c35fddd1c2f455e5b638ba6c58993 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 13:39:11 -0800 Subject: drm/vmwgfx: Sync virtual device headers for new feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Get the latest device headers for SM5 and other features development. v2: sync to newer bits (merge later commits) v3: sync to even newer bits Co-developed-by: Roland Scheidegger Signed-off-by: Deepak Rawat Signed-off-by: Neha Bhende Signed-off-by: Charmaine Lee Signed-off-by: Roland Scheidegger Reviewed-by: Thomas Hellström (VMware) --- drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h | 149 +++- .../gpu/drm/vmwgfx/device_include/svga3d_devcaps.h | 792 +++++++++++---------- drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h | 466 +++++++++++- .../gpu/drm/vmwgfx/device_include/svga3d_limits.h | 36 +- .../drm/vmwgfx/device_include/svga3d_surfacedefs.h | 58 +- .../gpu/drm/vmwgfx/device_include/svga3d_types.h | 347 +++++++-- drivers/gpu/drm/vmwgfx/device_include/svga_reg.h | 382 +++++++--- drivers/gpu/drm/vmwgfx/device_include/svga_types.h | 1 + 8 files changed, 1646 insertions(+), 585 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h index 84ea8d385b0e..799bc0963f7a 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_cmd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 1998-2015 VMware, Inc. + * Copyright 1998-2020 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -261,30 +261,23 @@ typedef enum { SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET = 1220, SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET = 1221, SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET = 1222, - - /* - * Reserve some IDs to be used for the SM5 shader types. - */ - SVGA_3D_CMD_DX_RESERVED1 = 1223, - SVGA_3D_CMD_DX_RESERVED2 = 1224, - SVGA_3D_CMD_DX_RESERVED3 = 1225, + SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET = 1223, + SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET = 1224, + SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET = 1225, SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER = 1226, SVGA_3D_CMD_DX_MAX = 1227, SVGA_3D_CMD_SCREEN_COPY = 1227, - /* - * Reserve some IDs to be used for video. - */ - SVGA_3D_CMD_VIDEO_RESERVED1 = 1228, - SVGA_3D_CMD_VIDEO_RESERVED2 = 1229, - SVGA_3D_CMD_VIDEO_RESERVED3 = 1230, - SVGA_3D_CMD_VIDEO_RESERVED4 = 1231, - SVGA_3D_CMD_VIDEO_RESERVED5 = 1232, - SVGA_3D_CMD_VIDEO_RESERVED6 = 1233, - SVGA_3D_CMD_VIDEO_RESERVED7 = 1234, - SVGA_3D_CMD_VIDEO_RESERVED8 = 1235, + SVGA_3D_CMD_RESERVED1 = 1228, + SVGA_3D_CMD_RESERVED2 = 1229, + SVGA_3D_CMD_RESERVED3 = 1230, + SVGA_3D_CMD_RESERVED4 = 1231, + SVGA_3D_CMD_RESERVED5 = 1232, + SVGA_3D_CMD_RESERVED6 = 1233, + SVGA_3D_CMD_RESERVED7 = 1234, + SVGA_3D_CMD_RESERVED8 = 1235, SVGA_3D_CMD_GROW_OTABLE = 1236, SVGA_3D_CMD_DX_GROW_COTABLE = 1237, @@ -298,7 +291,46 @@ typedef enum { SVGA_3D_CMD_DX_PRED_CONVERT = 1243, SVGA_3D_CMD_WHOLE_SURFACE_COPY = 1244, - SVGA_3D_CMD_MAX = 1245, + SVGA_3D_CMD_DX_DEFINE_UA_VIEW = 1245, + SVGA_3D_CMD_DX_DESTROY_UA_VIEW = 1246, + SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT = 1247, + SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT = 1248, + SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT = 1249, + SVGA_3D_CMD_DX_SET_UA_VIEWS = 1250, + + SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT = 1251, + SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT = 1252, + SVGA_3D_CMD_DX_DISPATCH = 1253, + SVGA_3D_CMD_DX_DISPATCH_INDIRECT = 1254, + + SVGA_3D_CMD_WRITE_ZERO_SURFACE = 1255, + SVGA_3D_CMD_HINT_ZERO_SURFACE = 1256, + SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER = 1257, + SVGA_3D_CMD_DX_SET_STRUCTURE_COUNT = 1258, + + SVGA_3D_CMD_LOGICOPS_BITBLT = 1259, + SVGA_3D_CMD_LOGICOPS_TRANSBLT = 1260, + SVGA_3D_CMD_LOGICOPS_STRETCHBLT = 1261, + SVGA_3D_CMD_LOGICOPS_COLORFILL = 1262, + SVGA_3D_CMD_LOGICOPS_ALPHABLEND = 1263, + SVGA_3D_CMD_LOGICOPS_CLEARTYPEBLEND = 1264, + + SVGA_3D_CMD_RESERVED2_1 = 1265, + + SVGA_3D_CMD_RESERVED2_2 = 1266, + SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 = 1267, + SVGA_3D_CMD_DX_SET_CS_UA_VIEWS = 1268, + SVGA_3D_CMD_DX_SET_MIN_LOD = 1269, + SVGA_3D_CMD_RESERVED2_3 = 1270, + SVGA_3D_CMD_RESERVED2_4 = 1271, + SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2 = 1272, + SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB = 1273, + SVGA_3D_CMD_DX_SET_SHADER_IFACE = 1274, + SVGA_3D_CMD_DX_BIND_STREAMOUTPUT = 1275, + SVGA_3D_CMD_SURFACE_STRETCHBLT_NON_MS_TO_MS = 1276, + SVGA_3D_CMD_DX_BIND_SHADER_IFACE = 1277, + + SVGA_3D_CMD_MAX = 1278, SVGA_3D_CMD_FUTURE_MAX = 3000 } SVGAFifo3dCmdId; @@ -334,6 +366,7 @@ struct { uint32 sid; SVGA3dSurface1Flags surfaceFlags; SVGA3dSurfaceFormat format; + /* * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace * structures must have the same value of numMipLevels field. @@ -341,6 +374,7 @@ struct { * numMipLevels set to 0. */ SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES]; + /* * Followed by an SVGA3dSize structure for each mip level in each face. * @@ -360,6 +394,7 @@ struct { uint32 sid; SVGA3dSurface1Flags surfaceFlags; SVGA3dSurfaceFormat format; + /* * If surfaceFlags has SVGA3D_SURFACE_CUBEMAP bit set, all SVGA3dSurfaceFace * structures must have the same value of numMipLevels field. @@ -369,6 +404,7 @@ struct { SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES]; uint32 multisampleCount; SVGA3dTextureFilter autogenFilter; + /* * Followed by an SVGA3dSize structure for each mip level in each face. * @@ -512,6 +548,18 @@ struct { #include "vmware_pack_end.h" SVGA3dCmdWholeSurfaceCopy; /* SVGA_3D_CMD_WHOLE_SURFACE_COPY */ +typedef +#include "vmware_pack_begin.h" +struct { + SVGA3dSurfaceImageId src; + SVGA3dSurfaceImageId dest; + SVGA3dBox boxSrc; + SVGA3dBox boxDest; +} +#include "vmware_pack_end.h" +SVGA3dCmdSurfaceStretchBltNonMSToMS; +/* SVGA_3D_CMD_SURFACE_STRETCHBLT_NON_MS_TO_MS */ + typedef #include "vmware_pack_begin.h" struct { @@ -555,6 +603,7 @@ struct { SVGAGuestImage guest; SVGA3dSurfaceImageId host; SVGA3dTransferType transfer; + /* * Followed by variable number of SVGA3dCopyBox structures. For consistency * in all clipping logic and coordinate translation, we define the @@ -789,7 +838,7 @@ struct { uint32 indexBufferSid; /* Valid index buffer sid. */ uint32 indexBufferOffset; /* Byte offset into the vertex buffer, almost */ - /* always 0 for DX9 guests, non-zero for OpenGL */ + /* always 0 for pre SM guests, non-zero for OpenGL */ /* guests. We can't represent non-multiple of */ /* stride offsets in D3D9Renderer... */ uint8 indexBufferStride; /* Allowable values = 1, 2, or 4 */ @@ -1228,6 +1277,7 @@ struct SVGA3dCmdLogicOpsBitBlt { SVGA3dSurfaceImageId src; SVGA3dSurfaceImageId dst; SVGA3dLogicOp logicOp; + SVGA3dLogicOpRop3 logicOpRop3; /* Followed by variable number of SVGA3dCopyBox structures */ } #include "vmware_pack_end.h" @@ -1247,7 +1297,8 @@ struct SVGA3dCmdLogicOpsTransBlt { uint32 color; uint32 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsTransBlt; /* SVGA_3D_CMD_LOGICOPS_TRANSBLT */ @@ -1266,7 +1317,8 @@ struct SVGA3dCmdLogicOpsStretchBlt { uint16 mode; uint16 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsStretchBlt; /* SVGA_3D_CMD_LOGICOPS_STRETCHBLT */ @@ -1283,6 +1335,7 @@ struct SVGA3dCmdLogicOpsColorFill { SVGA3dSurfaceImageId dst; uint32 color; SVGA3dLogicOp logicOp; + SVGA3dLogicOpRop3 logicOpRop3; /* Followed by variable number of SVGA3dRect structures. */ } #include "vmware_pack_end.h" @@ -1302,7 +1355,8 @@ struct SVGA3dCmdLogicOpsAlphaBlend { uint32 alphaVal; uint32 flags; SVGA3dBox srcBox; - SVGA3dBox dstBox; + SVGA3dSignedBox dstBox; + SVGA3dBox clipBox; } #include "vmware_pack_end.h" SVGA3dCmdLogicOpsAlphaBlend; /* SVGA_3D_CMD_LOGICOPS_ALPHABLEND */ @@ -1365,8 +1419,9 @@ struct { SVGA3dSurface2Flags surface2Flags; uint8 multisamplePattern; uint8 qualityLevel; - uint8 pad0[2]; - uint32 pad1[3]; + uint16 bufferByteStride; + float minLOD; + uint32 pad0[2]; } #include "vmware_pack_end.h" SVGAOTableSurfaceEntry; @@ -1543,7 +1598,7 @@ typedef #include "vmware_pack_begin.h" struct { SVGAOTableType type; - PPN baseAddress; + PPN32 baseAddress; uint32 sizeInBytes; uint32 validSizeInBytes; SVGAMobFormat ptDepth; @@ -1599,7 +1654,7 @@ typedef struct SVGA3dCmdDefineGBMob { SVGAMobId mobid; SVGAMobFormat ptDepth; - PPN base; + PPN32 base; uint32 sizeInBytes; } #include "vmware_pack_end.h" @@ -1618,7 +1673,6 @@ struct SVGA3dCmdDestroyGBMob { #include "vmware_pack_end.h" SVGA3dCmdDestroyGBMob; /* SVGA_3D_CMD_DESTROY_GB_MOB */ - /* * Define a memory object (Mob) in the OTable with a PPN64 base. */ @@ -1718,6 +1772,27 @@ struct SVGA3dCmdDefineGBSurface_v3 { #include "vmware_pack_end.h" SVGA3dCmdDefineGBSurface_v3; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V3 */ +/* + * Defines a guest-backed surface, adding buffer byte stride. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDefineGBSurface_v4 { + uint32 sid; + SVGA3dSurfaceAllFlags surfaceFlags; + SVGA3dSurfaceFormat format; + uint32 numMipLevels; + uint32 multisampleCount; + SVGA3dMSPattern multisamplePattern; + SVGA3dMSQualityLevel qualityLevel; + SVGA3dTextureFilter autogenFilter; + SVGA3dSize size; + uint32 arraySize; + uint32 bufferByteStride; +} +#include "vmware_pack_end.h" +SVGA3dCmdDefineGBSurface_v4; /* SVGA_3D_CMD_DEFINE_GB_SURFACE_V4 */ + /* * Destroy a guest-backed surface. */ @@ -2181,4 +2256,20 @@ SVGA3dCmdScreenCopy; /* SVGA_3D_CMD_SCREEN_COPY */ #define SVGA_SCREEN_COPY_STATUS_SUCCESS 0x01 #define SVGA_SCREEN_COPY_STATUS_INVALID 0xFFFFFFFF +typedef +#include "vmware_pack_begin.h" +struct { + uint32 sid; +} +#include "vmware_pack_end.h" +SVGA3dCmdWriteZeroSurface; /* SVGA_3D_CMD_WRITE_ZERO_SURFACE */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 sid; +} +#include "vmware_pack_end.h" +SVGA3dCmdHintZeroSurface; /* SVGA_3D_CMD_HINT_ZERO_SURFACE */ + #endif /* _SVGA3D_CMD_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h index 2de878b5ba16..617b468c626c 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_devcaps.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 1998-2015 VMware, Inc. + * Copyright 1998-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -39,6 +39,8 @@ #include "includeCheck.h" +#include "svga3d_types.h" + /* * 3D Hardware Version * @@ -69,386 +71,408 @@ typedef enum { * DevCap indexes. */ -typedef enum { - SVGA3D_DEVCAP_INVALID = ((uint32)-1), - SVGA3D_DEVCAP_3D = 0, - SVGA3D_DEVCAP_MAX_LIGHTS = 1, - - /* - * SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of - * fixed-function texture units available. Each of these units - * work in both FFP and Shader modes, and they support texture - * transforms and texture coordinates. The host may have additional - * texture image units that are only usable with shaders. - */ - SVGA3D_DEVCAP_MAX_TEXTURES = 2, - SVGA3D_DEVCAP_MAX_CLIP_PLANES = 3, - SVGA3D_DEVCAP_VERTEX_SHADER_VERSION = 4, - SVGA3D_DEVCAP_VERTEX_SHADER = 5, - SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION = 6, - SVGA3D_DEVCAP_FRAGMENT_SHADER = 7, - SVGA3D_DEVCAP_MAX_RENDER_TARGETS = 8, - SVGA3D_DEVCAP_S23E8_TEXTURES = 9, - SVGA3D_DEVCAP_S10E5_TEXTURES = 10, - SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND = 11, - SVGA3D_DEVCAP_D16_BUFFER_FORMAT = 12, - SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT = 13, - SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT = 14, - SVGA3D_DEVCAP_QUERY_TYPES = 15, - SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING = 16, - SVGA3D_DEVCAP_MAX_POINT_SIZE = 17, - SVGA3D_DEVCAP_MAX_SHADER_TEXTURES = 18, - SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH = 19, - SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT = 20, - SVGA3D_DEVCAP_MAX_VOLUME_EXTENT = 21, - SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT = 22, - SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO = 23, - SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY = 24, - SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT = 25, - SVGA3D_DEVCAP_MAX_VERTEX_INDEX = 26, - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS = 27, - SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS = 28, - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS = 29, - SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS = 30, - SVGA3D_DEVCAP_TEXTURE_OPS = 31, - SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 = 32, - SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 = 33, - SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 = 34, - SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 = 35, - SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 = 36, - SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 = 37, - SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 = 38, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 = 39, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 = 40, - SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 = 41, - SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 = 42, - SVGA3D_DEVCAP_SURFACEFMT_Z_D16 = 43, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 = 44, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 = 45, - SVGA3D_DEVCAP_SURFACEFMT_DXT1 = 46, - SVGA3D_DEVCAP_SURFACEFMT_DXT2 = 47, - SVGA3D_DEVCAP_SURFACEFMT_DXT3 = 48, - SVGA3D_DEVCAP_SURFACEFMT_DXT4 = 49, - SVGA3D_DEVCAP_SURFACEFMT_DXT5 = 50, - SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 = 51, - SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 = 52, - SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 = 53, - SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 = 54, - SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 = 55, - SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 = 56, - SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 = 57, - SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 = 58, - SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 = 59, - SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 = 60, - SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 = 61, - - /* - * There is a hole in our devcap definitions for - * historical reasons. - * - * Define a constant just for completeness. - */ - SVGA3D_DEVCAP_MISSING62 = 62, - - SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES = 63, - - /* - * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color - * render targets. This does not include the depth or stencil targets. - */ - SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS = 64, - - SVGA3D_DEVCAP_SURFACEFMT_V16U16 = 65, - SVGA3D_DEVCAP_SURFACEFMT_G16R16 = 66, - SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 = 67, - SVGA3D_DEVCAP_SURFACEFMT_UYVY = 68, - SVGA3D_DEVCAP_SURFACEFMT_YUY2 = 69, - - /* - * Deprecated. - */ - SVGA3D_DEVCAP_DEAD4 = 70, - SVGA3D_DEVCAP_DEAD5 = 71, - SVGA3D_DEVCAP_DEAD7 = 72, - SVGA3D_DEVCAP_DEAD6 = 73, - - SVGA3D_DEVCAP_AUTOGENMIPMAPS = 74, - SVGA3D_DEVCAP_SURFACEFMT_NV12 = 75, - SVGA3D_DEVCAP_SURFACEFMT_AYUV = 76, - - /* - * This is the maximum number of SVGA context IDs that the guest - * can define using SVGA_3D_CMD_CONTEXT_DEFINE. - */ - SVGA3D_DEVCAP_MAX_CONTEXT_IDS = 77, - - /* - * This is the maximum number of SVGA surface IDs that the guest - * can define using SVGA_3D_CMD_SURFACE_DEFINE*. - */ - SVGA3D_DEVCAP_MAX_SURFACE_IDS = 78, - - SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 = 79, - SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 = 80, - SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT = 81, - - SVGA3D_DEVCAP_SURFACEFMT_ATI1 = 82, - SVGA3D_DEVCAP_SURFACEFMT_ATI2 = 83, - - /* - * Deprecated. - */ - SVGA3D_DEVCAP_DEAD1 = 84, - - /* - * This contains several SVGA_3D_CAPS_VIDEO_DECODE elements - * ored together, one for every type of video decoding supported. - */ - SVGA3D_DEVCAP_VIDEO_DECODE = 85, - - /* - * This contains several SVGA_3D_CAPS_VIDEO_PROCESS elements - * ored together, one for every type of video processing supported. - */ - SVGA3D_DEVCAP_VIDEO_PROCESS = 86, - - SVGA3D_DEVCAP_LINE_AA = 87, /* boolean */ - SVGA3D_DEVCAP_LINE_STIPPLE = 88, /* boolean */ - SVGA3D_DEVCAP_MAX_LINE_WIDTH = 89, /* float */ - SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH = 90, /* float */ - - SVGA3D_DEVCAP_SURFACEFMT_YV12 = 91, - - /* - * Does the host support the SVGA logic ops commands? - */ - SVGA3D_DEVCAP_LOGICOPS = 92, - - /* - * Are TS_CONSTANT, TS_COLOR_KEY, and TS_COLOR_KEY_ENABLE supported? - */ - SVGA3D_DEVCAP_TS_COLOR_KEY = 93, /* boolean */ - - /* - * Deprecated. - */ - SVGA3D_DEVCAP_DEAD2 = 94, - - /* - * Does the device support DXContexts? - */ - SVGA3D_DEVCAP_DXCONTEXT = 95, - - /* - * What is the maximum size of a texture array? - * - * (Even if this cap is zero, cubemaps are still allowed.) - */ - SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE = 96, - - /* - * What is the maximum number of vertex buffers or vertex input registers - * that can be expected to work correctly with a DXContext? - * - * The guest is allowed to set up to SVGA3D_DX_MAX_VERTEXBUFFERS, but - * anything in excess of this cap is not guaranteed to render correctly. - * - * Similarly, the guest can set up to SVGA3D_DX_MAX_VERTEXINPUTREGISTERS - * input registers without the SVGA3D_DEVCAP_SM4_1 cap, or - * SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS with the SVGA3D_DEVCAP_SM4_1, - * but only the registers up to this cap value are guaranteed to render - * correctly. - * - * If guest-drivers are able to expose a lower-limit, it's recommended - * that they clamp to this value. Otherwise, the host will make a - * best-effort on case-by-case basis if guests exceed this. - */ - SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS = 97, - - /* - * What is the maximum number of constant buffers that can be expected to - * work correctly with a DX context? - * - * The guest is allowed to set up to SVGA3D_DX_MAX_CONSTBUFFERS, but - * anything in excess of this cap is not guaranteed to render correctly. - * - * If guest-drivers are able to expose a lower-limit, it's recommended - * that they clamp to this value. Otherwise, the host will make a - * best-effort on case-by-case basis if guests exceed this. - */ - SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS = 98, - - /* - * Does the device support provoking vertex control? - * - * If this cap is present, the provokingVertexLast field in the - * rasterizer state is enabled. (Guests can then set it to FALSE, - * meaning that the first vertex is the provoking vertex, or TRUE, - * meaning that the last verteix is the provoking vertex.) - * - * If this cap is FALSE, then guests should set the provokingVertexLast - * to FALSE, otherwise rendering behavior is undefined. - */ - SVGA3D_DEVCAP_DX_PROVOKING_VERTEX = 99, - - SVGA3D_DEVCAP_DXFMT_X8R8G8B8 = 100, - SVGA3D_DEVCAP_DXFMT_A8R8G8B8 = 101, - SVGA3D_DEVCAP_DXFMT_R5G6B5 = 102, - SVGA3D_DEVCAP_DXFMT_X1R5G5B5 = 103, - SVGA3D_DEVCAP_DXFMT_A1R5G5B5 = 104, - SVGA3D_DEVCAP_DXFMT_A4R4G4B4 = 105, - SVGA3D_DEVCAP_DXFMT_Z_D32 = 106, - SVGA3D_DEVCAP_DXFMT_Z_D16 = 107, - SVGA3D_DEVCAP_DXFMT_Z_D24S8 = 108, - SVGA3D_DEVCAP_DXFMT_Z_D15S1 = 109, - SVGA3D_DEVCAP_DXFMT_LUMINANCE8 = 110, - SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4 = 111, - SVGA3D_DEVCAP_DXFMT_LUMINANCE16 = 112, - SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8 = 113, - SVGA3D_DEVCAP_DXFMT_DXT1 = 114, - SVGA3D_DEVCAP_DXFMT_DXT2 = 115, - SVGA3D_DEVCAP_DXFMT_DXT3 = 116, - SVGA3D_DEVCAP_DXFMT_DXT4 = 117, - SVGA3D_DEVCAP_DXFMT_DXT5 = 118, - SVGA3D_DEVCAP_DXFMT_BUMPU8V8 = 119, - SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5 = 120, - SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8 = 121, - SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1 = 122, - SVGA3D_DEVCAP_DXFMT_ARGB_S10E5 = 123, - SVGA3D_DEVCAP_DXFMT_ARGB_S23E8 = 124, - SVGA3D_DEVCAP_DXFMT_A2R10G10B10 = 125, - SVGA3D_DEVCAP_DXFMT_V8U8 = 126, - SVGA3D_DEVCAP_DXFMT_Q8W8V8U8 = 127, - SVGA3D_DEVCAP_DXFMT_CxV8U8 = 128, - SVGA3D_DEVCAP_DXFMT_X8L8V8U8 = 129, - SVGA3D_DEVCAP_DXFMT_A2W10V10U10 = 130, - SVGA3D_DEVCAP_DXFMT_ALPHA8 = 131, - SVGA3D_DEVCAP_DXFMT_R_S10E5 = 132, - SVGA3D_DEVCAP_DXFMT_R_S23E8 = 133, - SVGA3D_DEVCAP_DXFMT_RG_S10E5 = 134, - SVGA3D_DEVCAP_DXFMT_RG_S23E8 = 135, - SVGA3D_DEVCAP_DXFMT_BUFFER = 136, - SVGA3D_DEVCAP_DXFMT_Z_D24X8 = 137, - SVGA3D_DEVCAP_DXFMT_V16U16 = 138, - SVGA3D_DEVCAP_DXFMT_G16R16 = 139, - SVGA3D_DEVCAP_DXFMT_A16B16G16R16 = 140, - SVGA3D_DEVCAP_DXFMT_UYVY = 141, - SVGA3D_DEVCAP_DXFMT_YUY2 = 142, - SVGA3D_DEVCAP_DXFMT_NV12 = 143, - SVGA3D_DEVCAP_DXFMT_AYUV = 144, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS = 145, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT = 146, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT = 147, - SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS = 148, - SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT = 149, - SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT = 150, - SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT = 151, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS = 152, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT = 153, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM = 154, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT = 155, - SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS = 156, - SVGA3D_DEVCAP_DXFMT_R32G32_UINT = 157, - SVGA3D_DEVCAP_DXFMT_R32G32_SINT = 158, - SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS = 159, - SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT = 160, - SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24 = 161, - SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT = 162, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS = 163, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT = 164, - SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT = 165, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS = 166, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM = 167, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB = 168, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT = 169, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT = 170, - SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS = 171, - SVGA3D_DEVCAP_DXFMT_R16G16_UINT = 172, - SVGA3D_DEVCAP_DXFMT_R16G16_SINT = 173, - SVGA3D_DEVCAP_DXFMT_R32_TYPELESS = 174, - SVGA3D_DEVCAP_DXFMT_D32_FLOAT = 175, - SVGA3D_DEVCAP_DXFMT_R32_UINT = 176, - SVGA3D_DEVCAP_DXFMT_R32_SINT = 177, - SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS = 178, - SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT = 179, - SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8 = 180, - SVGA3D_DEVCAP_DXFMT_X24_G8_UINT = 181, - SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS = 182, - SVGA3D_DEVCAP_DXFMT_R8G8_UNORM = 183, - SVGA3D_DEVCAP_DXFMT_R8G8_UINT = 184, - SVGA3D_DEVCAP_DXFMT_R8G8_SINT = 185, - SVGA3D_DEVCAP_DXFMT_R16_TYPELESS = 186, - SVGA3D_DEVCAP_DXFMT_R16_UNORM = 187, - SVGA3D_DEVCAP_DXFMT_R16_UINT = 188, - SVGA3D_DEVCAP_DXFMT_R16_SNORM = 189, - SVGA3D_DEVCAP_DXFMT_R16_SINT = 190, - SVGA3D_DEVCAP_DXFMT_R8_TYPELESS = 191, - SVGA3D_DEVCAP_DXFMT_R8_UNORM = 192, - SVGA3D_DEVCAP_DXFMT_R8_UINT = 193, - SVGA3D_DEVCAP_DXFMT_R8_SNORM = 194, - SVGA3D_DEVCAP_DXFMT_R8_SINT = 195, - SVGA3D_DEVCAP_DXFMT_P8 = 196, - SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP = 197, - SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM = 198, - SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM = 199, - SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS = 200, - SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB = 201, - SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS = 202, - SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB = 203, - SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS = 204, - SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB = 205, - SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS = 206, - SVGA3D_DEVCAP_DXFMT_ATI1 = 207, - SVGA3D_DEVCAP_DXFMT_BC4_SNORM = 208, - SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS = 209, - SVGA3D_DEVCAP_DXFMT_ATI2 = 210, - SVGA3D_DEVCAP_DXFMT_BC5_SNORM = 211, - SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM = 212, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS = 213, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB = 214, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS = 215, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB = 216, - SVGA3D_DEVCAP_DXFMT_Z_DF16 = 217, - SVGA3D_DEVCAP_DXFMT_Z_DF24 = 218, - SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT = 219, - SVGA3D_DEVCAP_DXFMT_YV12 = 220, - SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT = 221, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT = 222, - SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM = 223, - SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT = 224, - SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM = 225, - SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM = 226, - SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT = 227, - SVGA3D_DEVCAP_DXFMT_R16G16_UNORM = 228, - SVGA3D_DEVCAP_DXFMT_R16G16_SNORM = 229, - SVGA3D_DEVCAP_DXFMT_R32_FLOAT = 230, - SVGA3D_DEVCAP_DXFMT_R8G8_SNORM = 231, - SVGA3D_DEVCAP_DXFMT_R16_FLOAT = 232, - SVGA3D_DEVCAP_DXFMT_D16_UNORM = 233, - SVGA3D_DEVCAP_DXFMT_A8_UNORM = 234, - SVGA3D_DEVCAP_DXFMT_BC1_UNORM = 235, - SVGA3D_DEVCAP_DXFMT_BC2_UNORM = 236, - SVGA3D_DEVCAP_DXFMT_BC3_UNORM = 237, - SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM = 238, - SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM = 239, - SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM = 240, - SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM = 241, - SVGA3D_DEVCAP_DXFMT_BC4_UNORM = 242, - SVGA3D_DEVCAP_DXFMT_BC5_UNORM = 243, - - /* - * Advertises shaderModel 4.1 support, independent blend-states, - * cube-map arrays, and a higher vertex input registers limit. - * - * (See documentation on SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS.) - */ - SVGA3D_DEVCAP_SM41 = 244, - - SVGA3D_DEVCAP_MULTISAMPLE_2X = 245, - SVGA3D_DEVCAP_MULTISAMPLE_4X = 246, - - SVGA3D_DEVCAP_MAX /* This must be the last index. */ -} SVGA3dDevCapIndex; +typedef uint32 SVGA3dDevCapIndex; + +#define SVGA3D_DEVCAP_INVALID ((uint32)-1) +#define SVGA3D_DEVCAP_3D 0 +#define SVGA3D_DEVCAP_MAX_LIGHTS 1 + +/* + * SVGA3D_DEVCAP_MAX_TEXTURES reflects the maximum number of + * fixed-function texture units available. Each of these units + * work in both FFP and Shader modes, and they support texture + * transforms and texture coordinates. The host may have additional + * texture image units that are only usable with shaders. + */ +#define SVGA3D_DEVCAP_MAX_TEXTURES 2 +#define SVGA3D_DEVCAP_MAX_CLIP_PLANES 3 +#define SVGA3D_DEVCAP_VERTEX_SHADER_VERSION 4 +#define SVGA3D_DEVCAP_VERTEX_SHADER 5 +#define SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION 6 +#define SVGA3D_DEVCAP_FRAGMENT_SHADER 7 +#define SVGA3D_DEVCAP_MAX_RENDER_TARGETS 8 +#define SVGA3D_DEVCAP_S23E8_TEXTURES 9 +#define SVGA3D_DEVCAP_S10E5_TEXTURES 10 +#define SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND 11 +#define SVGA3D_DEVCAP_D16_BUFFER_FORMAT 12 +#define SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT 13 +#define SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT 14 +#define SVGA3D_DEVCAP_QUERY_TYPES 15 +#define SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING 16 +#define SVGA3D_DEVCAP_MAX_POINT_SIZE 17 +#define SVGA3D_DEVCAP_MAX_SHADER_TEXTURES 18 +#define SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH 19 +#define SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT 20 +#define SVGA3D_DEVCAP_MAX_VOLUME_EXTENT 21 +#define SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT 22 +#define SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO 23 +#define SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY 24 +#define SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT 25 +#define SVGA3D_DEVCAP_MAX_VERTEX_INDEX 26 +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS 27 +#define SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS 28 +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS 29 +#define SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS 30 +#define SVGA3D_DEVCAP_TEXTURE_OPS 31 +#define SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8 32 +#define SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8 33 +#define SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10 34 +#define SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5 35 +#define SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5 36 +#define SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4 37 +#define SVGA3D_DEVCAP_SURFACEFMT_R5G6B5 38 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16 39 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8 40 +#define SVGA3D_DEVCAP_SURFACEFMT_ALPHA8 41 +#define SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8 42 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D16 43 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8 44 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8 45 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT1 46 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT2 47 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT3 48 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT4 49 +#define SVGA3D_DEVCAP_SURFACEFMT_DXT5 50 +#define SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8 51 +#define SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10 52 +#define SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8 53 +#define SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8 54 +#define SVGA3D_DEVCAP_SURFACEFMT_CxV8U8 55 +#define SVGA3D_DEVCAP_SURFACEFMT_R_S10E5 56 +#define SVGA3D_DEVCAP_SURFACEFMT_R_S23E8 57 +#define SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5 58 +#define SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8 59 +#define SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5 60 +#define SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8 61 + +/* + * There is a hole in our devcap definitions for + * historical reasons. + * + * Define a constant just for completeness. + */ +#define SVGA3D_DEVCAP_MISSING62 62 + +#define SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES 63 + +/* + * Note that MAX_SIMULTANEOUS_RENDER_TARGETS is a maximum count of color + * render targets. This does not include the depth or stencil targets. + */ +#define SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS 64 + +#define SVGA3D_DEVCAP_SURFACEFMT_V16U16 65 +#define SVGA3D_DEVCAP_SURFACEFMT_G16R16 66 +#define SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16 67 +#define SVGA3D_DEVCAP_SURFACEFMT_UYVY 68 +#define SVGA3D_DEVCAP_SURFACEFMT_YUY2 69 + +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD4 70 +#define SVGA3D_DEVCAP_DEAD5 71 +#define SVGA3D_DEVCAP_DEAD7 72 +#define SVGA3D_DEVCAP_DEAD6 73 + +#define SVGA3D_DEVCAP_AUTOGENMIPMAPS 74 +#define SVGA3D_DEVCAP_SURFACEFMT_NV12 75 +#define SVGA3D_DEVCAP_DEAD10 76 + +/* + * This is the maximum number of SVGA context IDs that the guest + * can define using SVGA_3D_CMD_CONTEXT_DEFINE. + */ +#define SVGA3D_DEVCAP_MAX_CONTEXT_IDS 77 + +/* + * This is the maximum number of SVGA surface IDs that the guest + * can define using SVGA_3D_CMD_SURFACE_DEFINE*. + */ +#define SVGA3D_DEVCAP_MAX_SURFACE_IDS 78 + +#define SVGA3D_DEVCAP_SURFACEFMT_Z_DF16 79 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_DF24 80 +#define SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT 81 + +#define SVGA3D_DEVCAP_SURFACEFMT_ATI1 82 +#define SVGA3D_DEVCAP_SURFACEFMT_ATI2 83 + +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD1 84 +#define SVGA3D_DEVCAP_DEAD8 85 +#define SVGA3D_DEVCAP_DEAD9 86 + +#define SVGA3D_DEVCAP_LINE_AA 87 /* boolean */ +#define SVGA3D_DEVCAP_LINE_STIPPLE 88 /* boolean */ +#define SVGA3D_DEVCAP_MAX_LINE_WIDTH 89 /* float */ +#define SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH 90 /* float */ + +#define SVGA3D_DEVCAP_SURFACEFMT_YV12 91 + +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD3 92 + +/* + * Are TS_CONSTANT, TS_COLOR_KEY, and TS_COLOR_KEY_ENABLE supported? + */ +#define SVGA3D_DEVCAP_TS_COLOR_KEY 93 /* boolean */ + +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD2 94 + +/* + * Does the device support DXContexts? + */ +#define SVGA3D_DEVCAP_DXCONTEXT 95 + +/* + * Deprecated. + */ +#define SVGA3D_DEVCAP_DEAD11 96 + +/* + * What is the maximum number of vertex buffers or vertex input registers + * that can be expected to work correctly with a DXContext? + * + * The guest is allowed to set up to SVGA3D_DX_MAX_VERTEXBUFFERS, but + * anything in excess of this cap is not guaranteed to render correctly. + * + * Similarly, the guest can set up to SVGA3D_DX_MAX_VERTEXINPUTREGISTERS + * input registers without the SVGA3D_DEVCAP_SM4_1 cap, or + * SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS with the SVGA3D_DEVCAP_SM4_1, + * but only the registers up to this cap value are guaranteed to render + * correctly. + * + * If guest-drivers are able to expose a lower-limit, it's recommended + * that they clamp to this value. Otherwise, the host will make a + * best-effort on case-by-case basis if guests exceed this. + */ +#define SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS 97 + +/* + * What is the maximum number of constant buffers that can be expected to + * work correctly with a DX context? + * + * The guest is allowed to set up to SVGA3D_DX_MAX_CONSTBUFFERS, but + * anything in excess of this cap is not guaranteed to render correctly. + * + * If guest-drivers are able to expose a lower-limit, it's recommended + * that they clamp to this value. Otherwise, the host will make a + * best-effort on case-by-case basis if guests exceed this. + */ +#define SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS 98 + +/* + * Does the device support provoking vertex control? + * + * If this cap is present, the provokingVertexLast field in the + * rasterizer state is enabled. (Guests can then set it to FALSE, + * meaning that the first vertex is the provoking vertex, or TRUE, + * meaning that the last verteix is the provoking vertex.) + * + * If this cap is FALSE, then guests should set the provokingVertexLast + * to FALSE, otherwise rendering behavior is undefined. + */ +#define SVGA3D_DEVCAP_DX_PROVOKING_VERTEX 99 + +#define SVGA3D_DEVCAP_DXFMT_X8R8G8B8 100 +#define SVGA3D_DEVCAP_DXFMT_A8R8G8B8 101 +#define SVGA3D_DEVCAP_DXFMT_R5G6B5 102 +#define SVGA3D_DEVCAP_DXFMT_X1R5G5B5 103 +#define SVGA3D_DEVCAP_DXFMT_A1R5G5B5 104 +#define SVGA3D_DEVCAP_DXFMT_A4R4G4B4 105 +#define SVGA3D_DEVCAP_DXFMT_Z_D32 106 +#define SVGA3D_DEVCAP_DXFMT_Z_D16 107 +#define SVGA3D_DEVCAP_DXFMT_Z_D24S8 108 +#define SVGA3D_DEVCAP_DXFMT_Z_D15S1 109 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE8 110 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4 111 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE16 112 +#define SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8 113 +#define SVGA3D_DEVCAP_DXFMT_DXT1 114 +#define SVGA3D_DEVCAP_DXFMT_DXT2 115 +#define SVGA3D_DEVCAP_DXFMT_DXT3 116 +#define SVGA3D_DEVCAP_DXFMT_DXT4 117 +#define SVGA3D_DEVCAP_DXFMT_DXT5 118 +#define SVGA3D_DEVCAP_DXFMT_BUMPU8V8 119 +#define SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5 120 +#define SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8 121 +#define SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1 122 +#define SVGA3D_DEVCAP_DXFMT_ARGB_S10E5 123 +#define SVGA3D_DEVCAP_DXFMT_ARGB_S23E8 124 +#define SVGA3D_DEVCAP_DXFMT_A2R10G10B10 125 +#define SVGA3D_DEVCAP_DXFMT_V8U8 126 +#define SVGA3D_DEVCAP_DXFMT_Q8W8V8U8 127 +#define SVGA3D_DEVCAP_DXFMT_CxV8U8 128 +#define SVGA3D_DEVCAP_DXFMT_X8L8V8U8 129 +#define SVGA3D_DEVCAP_DXFMT_A2W10V10U10 130 +#define SVGA3D_DEVCAP_DXFMT_ALPHA8 131 +#define SVGA3D_DEVCAP_DXFMT_R_S10E5 132 +#define SVGA3D_DEVCAP_DXFMT_R_S23E8 133 +#define SVGA3D_DEVCAP_DXFMT_RG_S10E5 134 +#define SVGA3D_DEVCAP_DXFMT_RG_S23E8 135 +#define SVGA3D_DEVCAP_DXFMT_BUFFER 136 +#define SVGA3D_DEVCAP_DXFMT_Z_D24X8 137 +#define SVGA3D_DEVCAP_DXFMT_V16U16 138 +#define SVGA3D_DEVCAP_DXFMT_G16R16 139 +#define SVGA3D_DEVCAP_DXFMT_A16B16G16R16 140 +#define SVGA3D_DEVCAP_DXFMT_UYVY 141 +#define SVGA3D_DEVCAP_DXFMT_YUY2 142 +#define SVGA3D_DEVCAP_DXFMT_NV12 143 +#define SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2 144 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS 145 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT 146 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT 147 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS 148 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT 149 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT 150 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT 151 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS 152 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT 153 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM 154 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT 155 +#define SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS 156 +#define SVGA3D_DEVCAP_DXFMT_R32G32_UINT 157 +#define SVGA3D_DEVCAP_DXFMT_R32G32_SINT 158 +#define SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS 159 +#define SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT 160 +#define SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24 161 +#define SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT 162 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS 163 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT 164 +#define SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT 165 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS 166 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM 167 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB 168 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT 169 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT 170 +#define SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS 171 +#define SVGA3D_DEVCAP_DXFMT_R16G16_UINT 172 +#define SVGA3D_DEVCAP_DXFMT_R16G16_SINT 173 +#define SVGA3D_DEVCAP_DXFMT_R32_TYPELESS 174 +#define SVGA3D_DEVCAP_DXFMT_D32_FLOAT 175 +#define SVGA3D_DEVCAP_DXFMT_R32_UINT 176 +#define SVGA3D_DEVCAP_DXFMT_R32_SINT 177 +#define SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS 178 +#define SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT 179 +#define SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8 180 +#define SVGA3D_DEVCAP_DXFMT_X24_G8_UINT 181 +#define SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS 182 +#define SVGA3D_DEVCAP_DXFMT_R8G8_UNORM 183 +#define SVGA3D_DEVCAP_DXFMT_R8G8_UINT 184 +#define SVGA3D_DEVCAP_DXFMT_R8G8_SINT 185 +#define SVGA3D_DEVCAP_DXFMT_R16_TYPELESS 186 +#define SVGA3D_DEVCAP_DXFMT_R16_UNORM 187 +#define SVGA3D_DEVCAP_DXFMT_R16_UINT 188 +#define SVGA3D_DEVCAP_DXFMT_R16_SNORM 189 +#define SVGA3D_DEVCAP_DXFMT_R16_SINT 190 +#define SVGA3D_DEVCAP_DXFMT_R8_TYPELESS 191 +#define SVGA3D_DEVCAP_DXFMT_R8_UNORM 192 +#define SVGA3D_DEVCAP_DXFMT_R8_UINT 193 +#define SVGA3D_DEVCAP_DXFMT_R8_SNORM 194 +#define SVGA3D_DEVCAP_DXFMT_R8_SINT 195 +#define SVGA3D_DEVCAP_DXFMT_P8 196 +#define SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP 197 +#define SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM 198 +#define SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM 199 +#define SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS 200 +#define SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB 201 +#define SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS 202 +#define SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB 203 +#define SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS 204 +#define SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB 205 +#define SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS 206 +#define SVGA3D_DEVCAP_DXFMT_ATI1 207 +#define SVGA3D_DEVCAP_DXFMT_BC4_SNORM 208 +#define SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS 209 +#define SVGA3D_DEVCAP_DXFMT_ATI2 210 +#define SVGA3D_DEVCAP_DXFMT_BC5_SNORM 211 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM 212 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS 213 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB 214 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS 215 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB 216 +#define SVGA3D_DEVCAP_DXFMT_Z_DF16 217 +#define SVGA3D_DEVCAP_DXFMT_Z_DF24 218 +#define SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT 219 +#define SVGA3D_DEVCAP_DXFMT_YV12 220 +#define SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT 221 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT 222 +#define SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM 223 +#define SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT 224 +#define SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM 225 +#define SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM 226 +#define SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT 227 +#define SVGA3D_DEVCAP_DXFMT_R16G16_UNORM 228 +#define SVGA3D_DEVCAP_DXFMT_R16G16_SNORM 229 +#define SVGA3D_DEVCAP_DXFMT_R32_FLOAT 230 +#define SVGA3D_DEVCAP_DXFMT_R8G8_SNORM 231 +#define SVGA3D_DEVCAP_DXFMT_R16_FLOAT 232 +#define SVGA3D_DEVCAP_DXFMT_D16_UNORM 233 +#define SVGA3D_DEVCAP_DXFMT_A8_UNORM 234 +#define SVGA3D_DEVCAP_DXFMT_BC1_UNORM 235 +#define SVGA3D_DEVCAP_DXFMT_BC2_UNORM 236 +#define SVGA3D_DEVCAP_DXFMT_BC3_UNORM 237 +#define SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM 238 +#define SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM 239 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM 240 +#define SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM 241 +#define SVGA3D_DEVCAP_DXFMT_BC4_UNORM 242 +#define SVGA3D_DEVCAP_DXFMT_BC5_UNORM 243 + +/* + * Advertises shaderModel 4.1 support, independent blend-states, + * cube-map arrays, and a higher vertex input registers limit. + * + * (See documentation on SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS.) + */ +#define SVGA3D_DEVCAP_SM41 244 +#define SVGA3D_DEVCAP_MULTISAMPLE_2X 245 +#define SVGA3D_DEVCAP_MULTISAMPLE_4X 246 + +/* + * Indicates that the device has rendering support for + * the full multisample quality. If this cap is not present, + * the host may or may not support full quality rendering. + * + * See also SVGA_REG_MS_HINT_RESOLVED. + */ +#define SVGA3D_DEVCAP_MS_FULL_QUALITY 247 + +/* + * Advertises support for the SVGA3D LogicOps commands. + */ +#define SVGA3D_DEVCAP_LOGICOPS 248 + +/* + * Advertises support for using logicOps in the DXBlendStates. + */ +#define SVGA3D_DEVCAP_LOGIC_BLENDOPS 249 + +/* +* Note DXFMT range is now non-contiguous. +*/ +#define SVGA3D_DEVCAP_RESERVED_1 250 +#define SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS 251 +#define SVGA3D_DEVCAP_DXFMT_BC6H_UF16 252 +#define SVGA3D_DEVCAP_DXFMT_BC6H_SF16 253 +#define SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS 254 +#define SVGA3D_DEVCAP_DXFMT_BC7_UNORM 255 +#define SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB 256 +#define SVGA3D_DEVCAP_RESERVED_2 257 + +#define SVGA3D_DEVCAP_SM5 258 +#define SVGA3D_DEVCAP_MULTISAMPLE_8X 259 + +/* This must be the last index. */ +#define SVGA3D_DEVCAP_MAX 260 /* * Bit definitions for DXFMT devcaps @@ -477,10 +501,10 @@ typedef enum { #define SVGA3D_DXFMT_MAX (1 << 10) typedef union { - Bool b; + SVGA3dBool b; uint32 u; - int32 i; - float f; + int32 i; + float f; } SVGA3dDevCapResult; #endif /* _SVGA3D_DEVCAPS_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h index 7a49c94df221..f703ac2b1768 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_dx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 2012-2015 VMware, Inc. + * Copyright 2012-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -118,12 +118,14 @@ typedef uint8 SVGA3dMultisampleRastEnable; #define SVGA3D_DX_MAX_SRVIEWS 128 #define SVGA3D_DX_MAX_CONSTBUFFERS 16 #define SVGA3D_DX_MAX_SAMPLERS 16 +#define SVGA3D_DX_MAX_CLASS_INSTANCES 253 #define SVGA3D_DX_MAX_CONSTBUF_BINDING_SIZE (4096 * 4 * (uint32)sizeof(uint32)) typedef uint32 SVGA3dShaderResourceViewId; typedef uint32 SVGA3dRenderTargetViewId; typedef uint32 SVGA3dDepthStencilViewId; +typedef uint32 SVGA3dUAViewId; typedef uint32 SVGA3dShaderId; typedef uint32 SVGA3dElementLayoutId; @@ -145,6 +147,17 @@ typedef union { float value[4]; } SVGA3dRGBAFloat; +typedef union { + struct { + uint32 r; + uint32 g; + uint32 b; + uint32 a; + }; + + uint32 value[4]; +} SVGA3dRGBAUint32; + typedef #include "vmware_pack_begin.h" struct { @@ -249,6 +262,39 @@ struct SVGA3dCmdDXSetShader { #include "vmware_pack_end.h" SVGA3dCmdDXSetShader; /* SVGA_3D_CMD_DX_SET_SHADER */ +typedef union { + struct { + uint32 cbOffset : 12; + uint32 cbId : 4; + uint32 baseSamp : 4; + uint32 baseTex : 7; + uint32 reserved : 5; + }; + uint32 value; +} SVGA3dIfaceData; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetShaderIface { + SVGA3dShaderType type; + uint32 numClassInstances; + uint32 index; + uint32 iface; + SVGA3dIfaceData data; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetShaderIface; /* SVGA_3D_CMD_DX_SET_SHADER_IFACE */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXBindShaderIface { + uint32 cid; + SVGAMobId mobid; + uint32 offsetInBytes; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXBindShaderIface; /* SVGA_3D_CMD_DX_BIND_SHADER_IFACE */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXSetSamplers { @@ -304,6 +350,26 @@ struct SVGA3dCmdDXDrawIndexedInstanced { #include "vmware_pack_end.h" SVGA3dCmdDXDrawIndexedInstanced; /* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDrawIndexedInstancedIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDrawIndexedInstancedIndirect; +/* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDrawInstancedIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDrawInstancedIndirect; +/* SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDrawAuto { @@ -312,6 +378,27 @@ struct SVGA3dCmdDXDrawAuto { #include "vmware_pack_end.h" SVGA3dCmdDXDrawAuto; /* SVGA_3D_CMD_DX_DRAW_AUTO */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDispatch { + uint32 threadGroupCountX; + uint32 threadGroupCountY; + uint32 threadGroupCountZ; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDispatch; +/* SVGA_3D_CMD_DX_DISPATCH */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDispatchIndirect { + SVGA3dSurfaceId argsBufferSid; + uint32 byteOffsetForArgs; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDispatchIndirect; +/* SVGA_3D_CMD_DX_DISPATCH_INDIRECT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXSetInputLayout { @@ -525,7 +612,7 @@ struct MKS3dDXSOState { uint32 offset; /* Starting offset */ uint32 intOffset; /* Internal offset */ uint32 vertexCount; /* vertices written */ - uint32 sizeInBytes; /* max bytes to write */ + uint32 dead; } #include "vmware_pack_end.h" SVGA3dDXSOState; @@ -786,6 +873,31 @@ struct SVGA3dCmdDXTransferFromBuffer { SVGA3dCmdDXTransferFromBuffer; /* SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER */ +#define SVGA3D_TRANSFER_TO_BUFFER_READBACK (1 << 0) +#define SVGA3D_TRANSFER_TO_BUFFER_FLAGS_MASK (1 << 0) +typedef uint32 SVGA3dTransferToBufferFlags; + +/* + * Raw byte wise transfer to a buffer surface from another surface + * of the requested box. Supported if SVGA_CAP_DX2 is set. This + * command does not take a context. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXTransferToBuffer { + SVGA3dSurfaceId srcSid; + uint32 srcSubResource; + SVGA3dBox srcBox; + SVGA3dSurfaceId destSid; + uint32 destOffset; + uint32 destPitch; + uint32 destSlicePitch; + SVGA3dTransferToBufferFlags flags; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXTransferToBuffer; /* SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER */ + + /* * Raw byte wise transfer from a buffer surface into another surface * of the requested box. Supported if SVGA3D_DEVCAP_DXCONTEXT is set. @@ -905,6 +1017,20 @@ typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetPSConstantBufferOffset; typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetGSConstantBufferOffset; /* SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET */ +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetHSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET */ + +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetDSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET */ + +typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetCSConstantBufferOffset; +/* SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET */ + + +#define SVGA3D_BUFFEREX_SRV_RAW (1 << 0) +#define SVGA3D_BUFFEREX_SRV_FLAGS_MAX (1 << 1) +#define SVGA3D_BUFFEREX_SRV_FLAGS_MASK (SVGA3D_BUFFEREX_SRV_FLAGS_MAX - 1) +typedef uint32 SVGA3dBufferExFlags; typedef #include "vmware_pack_begin.h" @@ -925,7 +1051,7 @@ struct { struct { uint32 firstElement; uint32 numElements; - uint32 flags; + SVGA3dBufferExFlags flags; uint32 pad0; } bufferex; }; @@ -1072,6 +1198,32 @@ struct SVGA3dCmdDXDefineDepthStencilView { SVGA3dCmdDXDefineDepthStencilView; /* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW */ +/* + * Version 2 needed in order to start validating and using the flags + * field. Unfortunately the device wasn't validating or using the + * flags field and the driver wasn't initializing it in shipped code, + * so a new version of the command is needed to allow that code to + * continue to work. + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineDepthStencilView_v2 { + SVGA3dDepthStencilViewId depthStencilViewId; + + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + uint32 mipSlice; + uint32 firstArraySlice; + uint32 arraySize; + SVGA3DCreateDSViewFlags flags; + uint8 pad0; + uint16 pad1; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineDepthStencilView_v2; +/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2 */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDestroyDepthStencilView { @@ -1081,6 +1233,138 @@ struct SVGA3dCmdDXDestroyDepthStencilView { SVGA3dCmdDXDestroyDepthStencilView; /* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW */ + +#define SVGA3D_UABUFFER_RAW (1 << 0) +#define SVGA3D_UABUFFER_APPEND (1 << 1) +#define SVGA3D_UABUFFER_COUNTER (1 << 2) +typedef uint32 SVGA3dUABufferFlags; + +typedef +#include "vmware_pack_begin.h" +struct { + union { + struct { + uint32 firstElement; + uint32 numElements; + SVGA3dUABufferFlags flags; + uint32 padding0; + uint32 padding1; + } buffer; + struct { + uint32 mipSlice; + uint32 firstArraySlice; + uint32 arraySize; + uint32 padding0; + uint32 padding1; + } tex; /* 1d, 2d */ + struct { + uint32 mipSlice; + uint32 firstW; + uint32 wSize; + uint32 padding0; + uint32 padding1; + } tex3D; + }; +} +#include "vmware_pack_end.h" +SVGA3dUAViewDesc; + +typedef +#include "vmware_pack_begin.h" +struct { + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + SVGA3dUAViewDesc desc; + uint32 structureCount; + uint32 pad[7]; +} +#include "vmware_pack_end.h" +SVGACOTableDXUAViewEntry; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineUAView { + SVGA3dUAViewId uaViewId; + + SVGA3dSurfaceId sid; + SVGA3dSurfaceFormat format; + SVGA3dResourceType resourceDimension; + + SVGA3dUAViewDesc desc; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineUAView; +/* SVGA_3D_CMD_DX_DEFINE_UA_VIEW */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDestroyUAView { + SVGA3dUAViewId uaViewId; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDestroyUAView; +/* SVGA_3D_CMD_DX_DESTROY_UA_VIEW */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXClearUAViewUint { + SVGA3dUAViewId uaViewId; + SVGA3dRGBAUint32 value; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXClearUAViewUint; +/* SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXClearUAViewFloat { + SVGA3dUAViewId uaViewId; + SVGA3dRGBAFloat value; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXClearUAViewFloat; +/* SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXCopyStructureCount { + SVGA3dUAViewId srcUAViewId; + SVGA3dSurfaceId destSid; + uint32 destByteOffset; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXCopyStructureCount; +/* SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetStructureCount { + SVGA3dUAViewId uaViewId; + uint32 structureCount; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetStructureCount; +/* SVGA_3D_CMD_DX_SET_STRUCTURE_COUNT */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetUAViews { + uint32 uavSpliceIndex; + /* Followed by a variable number of SVGA3dUAViewId's. */ +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetUAViews; /* SVGA_3D_CMD_DX_SET_UA_VIEWS */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetCSUAViews { + uint32 startIndex; + /* Followed by a variable number of SVGA3dUAViewId's. */ +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetCSUAViews; /* SVGA_3D_CMD_DX_SET_CS_UA_VIEWS */ + typedef #include "vmware_pack_begin.h" struct SVGA3dInputElementDesc { @@ -1099,7 +1383,7 @@ typedef struct { uint32 elid; uint32 numDescs; - SVGA3dInputElementDesc desc[32]; + SVGA3dInputElementDesc descs[32]; uint32 pad[62]; } #include "vmware_pack_end.h" @@ -1261,7 +1545,8 @@ struct { uint8 lineStippleEnable; uint8 lineStippleFactor; uint16 lineStipplePattern; - uint32 forcedSampleCount; + uint8 forcedSampleCount; + uint8 mustBeZero[3]; } #include "vmware_pack_end.h" SVGACOTableDXRasterizerStateEntry; @@ -1352,6 +1637,71 @@ struct SVGA3dCmdDXDestroySamplerState { #include "vmware_pack_end.h" SVGA3dCmdDXDestroySamplerState; /* SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE */ + +#define SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION 1 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE 2 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE 3 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX 4 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX 5 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID 6 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID 7 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID 8 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE 9 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX 10 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR 11 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR 12 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR 13 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR 14 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR 15 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR 16 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR 17 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR 18 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR 19 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR 20 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR 21 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR 22 +#define SVGADX_SIGNATURE_SEMANTIC_NAME_MAX 23 +typedef uint32 SVGA3dDXSignatureSemanticName; + +#define SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN 0 +typedef uint32 SVGA3dDXSignatureRegisterComponentType; + +#define SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT 0 +typedef uint32 SVGA3dDXSignatureMinPrecision; + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dDXSignatureEntry { + uint32 registerIndex; + SVGA3dDXSignatureSemanticName semanticName; + uint32 mask; /* Lower 4 bits represent X, Y, Z, W channels */ + SVGA3dDXSignatureRegisterComponentType componentType; + SVGA3dDXSignatureMinPrecision minPrecision; +} +#include "vmware_pack_end.h" +SVGA3dDXShaderSignatureEntry; + +#define SVGADX_SIGNATURE_HEADER_VERSION_0 0x08a92d12 + +/* + * The SVGA3dDXSignatureHeader structure is added after the shader + * body in the mob that is bound to the shader. It is followed by the + * specified number of SVGA3dDXSignatureEntry structures for each of + * the three types of signatures in the order (input, output, patch + * constants). + */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dDXSignatureHeader { + uint32 headerVersion; + uint32 numInputSignatures; + uint32 numOutputSignatures; + uint32 numPatchConstantSignatures; +} +#include "vmware_pack_end.h" +SVGA3dDXShaderSignatureHeader; + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDefineShader { @@ -1415,7 +1765,8 @@ SVGA3dCmdDXCondBindAllShader; /* SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER */ /* * The maximum number of streamout decl's in each streamout entry. */ -#define SVGA3D_MAX_STREAMOUT_DECLS 64 +#define SVGA3D_MAX_DX10_STREAMOUT_DECLS 64 +#define SVGA3D_MAX_STREAMOUT_DECLS 512 typedef #include "vmware_pack_begin.h" @@ -1434,10 +1785,16 @@ typedef #include "vmware_pack_begin.h" struct SVGAOTableStreamOutputEntry { uint32 numOutputStreamEntries; - SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS]; + SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS]; uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; uint32 rasterizedStream; - uint32 pad[250]; + uint32 numOutputStreamStrides; + uint32 mobid; + uint32 offsetInBytes; + uint8 usesMob; + uint8 pad0; + uint16 pad1; + uint32 pad2[246]; } #include "vmware_pack_end.h" SVGACOTableDXStreamOutputEntry; @@ -1447,13 +1804,47 @@ typedef struct SVGA3dCmdDXDefineStreamOutput { SVGA3dStreamOutputId soid; uint32 numOutputStreamEntries; - SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_STREAMOUT_DECLS]; + SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS]; uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; uint32 rasterizedStream; } #include "vmware_pack_end.h" SVGA3dCmdDXDefineStreamOutput; /* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT */ +/* + * Version 2 needed in order to start validating and using the + * rasterizedStream field. Unfortunately the device wasn't validating + * or using this field and the driver wasn't initializing it in shipped + * code, so a new version of the command is needed to allow that code + * to continue to work. Also added new numOutputStreamStrides field. + */ + +#define SVGA3D_DX_SO_NO_RASTERIZED_STREAM 0xFFFFFFFF + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXDefineStreamOutputWithMob { + SVGA3dStreamOutputId soid; + uint32 numOutputStreamEntries; + uint32 numOutputStreamStrides; + uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS]; + uint32 rasterizedStream; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXDefineStreamOutputWithMob; +/* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB */ + +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXBindStreamOutput { + SVGA3dStreamOutputId soid; + uint32 mobid; + uint32 offsetInBytes; + uint32 sizeInBytes; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXBindStreamOutput; /* SVGA_3D_CMD_DX_BIND_STREAMOUTPUT */ + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXDestroyStreamOutput { @@ -1470,6 +1861,15 @@ struct SVGA3dCmdDXSetStreamOutput { #include "vmware_pack_end.h" SVGA3dCmdDXSetStreamOutput; /* SVGA_3D_CMD_DX_SET_STREAMOUTPUT */ +typedef +#include "vmware_pack_begin.h" +struct SVGA3dCmdDXSetMinLOD { + SVGA3dSurfaceId sid; + float minLOD; +} +#include "vmware_pack_end.h" +SVGA3dCmdDXSetMinLOD; /* SVGA_3D_CMD_DX_SET_MIN_LOD */ + typedef #include "vmware_pack_begin.h" struct { @@ -1581,33 +1981,38 @@ struct SVGADXContextMobFormat { uint32 rasterizerStateId; uint32 depthStencilViewId; uint32 renderTargetViewIds[SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS]; - uint32 unorderedAccessViewIds[SVGA3D_MAX_UAVIEWS]; } renderState; + uint32 pad0[8]; + struct { uint32 targets[SVGA3D_DX_MAX_SOTARGETS]; uint32 soid; } streamOut; - uint32 pad0[11]; + + uint32 pad1[10]; + + uint32 uavSpliceIndex; uint8 numViewports; uint8 numScissorRects; - uint16 pad1[1]; + uint16 pad2[1]; - uint32 pad2[3]; + uint32 pad3[3]; SVGA3dViewport viewports[SVGA3D_DX_MAX_VIEWPORTS]; - uint32 pad3[32]; + uint32 pad4[32]; SVGASignedRect scissorRects[SVGA3D_DX_MAX_SCISSORRECTS]; - uint32 pad4[64]; + uint32 pad5[64]; struct { uint32 queryID; uint32 value; } predication; - uint32 pad5[2]; + SVGAMobId shaderIfaceMobid; + uint32 shaderIfaceOffset; struct { uint32 shaderId; SVGA3dConstantBufferBinding constantBuffers[SVGA3D_DX_MAX_CONSTBUFFERS]; @@ -1619,11 +2024,38 @@ struct SVGADXContextMobFormat { SVGA3dQueryId queryID[SVGA3D_MAX_QUERY]; SVGA3dCOTableData cotables[SVGA_COTABLE_MAX]; - uint32 pad7[380]; + + uint32 pad7[64]; + + uint32 uaViewIds[SVGA3D_DX11_1_MAX_UAVIEWS]; + uint32 csuaViewIds[SVGA3D_DX11_1_MAX_UAVIEWS]; + + uint32 pad8[188]; } #include "vmware_pack_end.h" SVGADXContextMobFormat; +/* + * There is conflicting documentation on max class instances (253 vs 256). The + * lower value is the one used throughout the device, but since mob format is + * more involved to increase if needed, conservatively use the higher one here. + */ +#define SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED 256 + +typedef +#include "vmware_pack_begin.h" +struct SVGADXShaderIfaceMobFormat { + struct { + uint32 numClassInstances; + uint32 iface[SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED]; + SVGA3dIfaceData data[SVGA3D_DX_MAX_CLASS_INSTANCES_PADDED]; + } shaderIfaceState[SVGA3D_NUM_SHADERTYPE]; + + uint32 pad0[1018]; +} +#include "vmware_pack_end.h" +SVGADXShaderIfaceMobFormat; + typedef #include "vmware_pack_begin.h" struct SVGA3dCmdDXTempSetContext { diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h index b22a67f15660..f4375a41b3aa 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_limits.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 OR MIT */ /********************************************************** - * Copyright 2007-2015 VMware, Inc. + * Copyright 2007-2019 VMware, Inc. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -40,11 +40,25 @@ #include "includeCheck.h" #define SVGA3D_NUM_CLIPPLANES 6 +#define SVGA3D_MAX_CONTEXT_IDS 256 +#define SVGA3D_MAX_SURFACE_IDS (32 * 1024) + +/* + * While there are separate bind-points for RenderTargetViews and + * UnorderedAccessViews in a DXContext, there is in fact one shared + * semantic space that the guest-driver can use on any given draw call. + * So there are really only 8 slots that can be spilt up between them, with the + * spliceIndex controlling where the UAV's sit in the collapsed array. + */ #define SVGA3D_MAX_RENDER_TARGETS 8 #define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS (SVGA3D_MAX_RENDER_TARGETS) #define SVGA3D_MAX_UAVIEWS 8 -#define SVGA3D_MAX_CONTEXT_IDS 256 -#define SVGA3D_MAX_SURFACE_IDS (32 * 1024) +#define SVGA3D_DX11_1_MAX_UAVIEWS 64 + +/* + * Maximum canonical size of a surface in host-backed mode (pre-GBObjects). + */ +#define SVGA3D_HB_MAX_SURFACE_SIZE MBYTES_2_BYTES(128) /* * Maximum ID a shader can be assigned on a given context. @@ -59,6 +73,8 @@ #define SVGA3D_NUM_TEXTURE_UNITS 32 #define SVGA3D_NUM_LIGHTS 8 +#define SVGA3D_MAX_VIDEOPROCESSOR_SAMPLERS 32 + /* * Maximum size in dwords of shader text the SVGA device will allow. * Currently 8 MB. @@ -67,6 +83,11 @@ #define SVGA3D_MAX_SHADER_MEMORY (SVGA3D_MAX_SHADER_MEMORY_BYTES / \ sizeof(uint32)) +/* + * The maximum value of threadGroupCount in each dimension + */ +#define SVGA3D_MAX_SHADER_THREAD_GROUPS 65535 + #define SVGA3D_MAX_CLIP_PLANES 6 /* @@ -85,7 +106,9 @@ /* * Maximum number of array indexes in a GB surface (with DX enabled). */ -#define SVGA3D_MAX_SURFACE_ARRAYSIZE 512 +#define SVGA3D_SM4_MAX_SURFACE_ARRAYSIZE 512 +#define SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE 2048 +#define SVGA3D_MAX_SURFACE_ARRAYSIZE SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE /* * The maximum number of vertex arrays we're guaranteed to support in @@ -99,4 +122,9 @@ */ #define SVGA3D_MAX_DRAW_PRIMITIVE_RANGES 32 +/* + * The maximum number of samples that can be contained in a surface. + */ +#define SVGA3D_MAX_SAMPLES 8 + #endif /* _SVGA3D_LIMITS_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h index 61414f105c67..4db25bd9fa22 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h @@ -131,6 +131,8 @@ enum svga3d_block_desc { SVGA3DBLOCKDESC_BC3 = 1 << 26, SVGA3DBLOCKDESC_BC4 = 1 << 27, SVGA3DBLOCKDESC_BC5 = 1 << 28, + SVGA3DBLOCKDESC_BC6H = 1 << 29, + SVGA3DBLOCKDESC_BC7 = 1 << 30, SVGA3DBLOCKDESC_A_UINT = SVGA3DBLOCKDESC_ALPHA | SVGA3DBLOCKDESC_UINT | @@ -290,6 +292,18 @@ enum svga3d_block_desc { SVGA3DBLOCKDESC_COMP_UNORM, SVGA3DBLOCKDESC_BC5_COMP_SNORM = SVGA3DBLOCKDESC_BC5 | SVGA3DBLOCKDESC_COMP_SNORM, + SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMP_TYPELESS, + SVGA3DBLOCKDESC_BC6H_COMP_UF16 = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMPRESSED, + SVGA3DBLOCKDESC_BC6H_COMP_SF16 = SVGA3DBLOCKDESC_BC6H | + SVGA3DBLOCKDESC_COMPRESSED, + SVGA3DBLOCKDESC_BC7_COMP_TYPELESS = SVGA3DBLOCKDESC_BC7 | + SVGA3DBLOCKDESC_COMP_TYPELESS, + SVGA3DBLOCKDESC_BC7_COMP_UNORM = SVGA3DBLOCKDESC_BC7 | + SVGA3DBLOCKDESC_COMP_UNORM, + SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB = SVGA3DBLOCKDESC_BC7_COMP_UNORM | + SVGA3DBLOCKDESC_SRGB, SVGA3DBLOCKDESC_NV12 = SVGA3DBLOCKDESC_YUV_VIDEO | SVGA3DBLOCKDESC_PLANAR_YUV | @@ -494,7 +508,7 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {{8}, {8}, {8}, {0}}, {{16}, {8}, {0}, {0}}}, - {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_UVL, + {SVGA3D_FORMAT_DEAD1, SVGA3DBLOCKDESC_NONE, {1, 1, 1}, 3, 3, {{8}, {8}, {8}, {0}}, {{16}, {8}, {0}, {0}}}, @@ -604,7 +618,7 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {{0}, {0}, {48}, {0}}, {{0}, {0}, {0}, {0}}}, - {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, + {SVGA3D_FORMAT_DEAD2, SVGA3DBLOCKDESC_NONE, {1, 1, 1}, 4, 4, {{8}, {8}, {8}, {8}}, {{0}, {8}, {16}, {24}}}, @@ -1103,6 +1117,46 @@ static const struct svga3d_surface_desc svga3d_surface_descs[] = { {4, 4, 1}, 16, 16, {{0}, {0}, {128}, {0}}, {{0}, {0}, {0}, {0}}}, + + {SVGA3D_B4G4R4A4_UNORM, SVGA3DBLOCKDESC_RGBA_UNORM, + {1, 1, 1}, 2, 2, + {{4}, {4}, {4}, {4}}, + {{0}, {4}, {8}, {12}}}, + + {SVGA3D_BC6H_TYPELESS, SVGA3DBLOCKDESC_BC6H_COMP_TYPELESS, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC6H_UF16, SVGA3DBLOCKDESC_BC6H_COMP_UF16, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC6H_SF16, SVGA3DBLOCKDESC_BC6H_COMP_SF16, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_TYPELESS, SVGA3DBLOCKDESC_BC7_COMP_TYPELESS, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_UNORM, SVGA3DBLOCKDESC_BC7_COMP_UNORM, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_BC7_UNORM_SRGB, SVGA3DBLOCKDESC_BC7_COMP_UNORM_SRGB, + {4, 4, 1}, 16, 16, + {{0}, {0}, {128}, {0}}, + {{0}, {0}, {0}, {0}}}, + + {SVGA3D_AYUV, SVGA3DBLOCKDESC_AYUV, + {1, 1, 1}, 4, 4, + {{8}, {8}, {8}, {8}}, + {{0}, {8}, {16}, {24}}}, }; static inline u32 clamped_umul32(u32 a, u32 b) diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h index 308370665a8e..77e338a65791 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_types.h @@ -113,6 +113,19 @@ struct { #include "vmware_pack_end.h" SVGA3dBox; +typedef +#include "vmware_pack_begin.h" +struct { + int32 x; + int32 y; + int32 z; + int32 w; + int32 h; + int32 d; +} +#include "vmware_pack_end.h" +SVGA3dSignedBox; + typedef #include "vmware_pack_begin.h" struct { @@ -198,8 +211,7 @@ typedef enum SVGA3dSurfaceFormat { /* Planar video formats */ SVGA3D_NV12 = 44, - /* Video format with alpha */ - SVGA3D_AYUV = 45, + SVGA3D_FORMAT_DEAD2 = 45, SVGA3D_R32G32B32A32_TYPELESS = 46, SVGA3D_R32G32B32A32_UINT = 47, @@ -305,6 +317,18 @@ typedef enum SVGA3dSurfaceFormat { SVGA3D_B8G8R8X8_UNORM = 142, SVGA3D_BC4_UNORM = 143, SVGA3D_BC5_UNORM = 144, + SVGA3D_B4G4R4A4_UNORM = 145, + + /* DX11 compressed formats */ + SVGA3D_BC6H_TYPELESS = 146, + SVGA3D_BC6H_UF16 = 147, + SVGA3D_BC6H_SF16 = 148, + SVGA3D_BC7_TYPELESS = 149, + SVGA3D_BC7_UNORM = 150, + SVGA3D_BC7_UNORM_SRGB = 151, + + /* Video format with alpha */ + SVGA3D_AYUV = 152, SVGA3D_FORMAT_MAX } SVGA3dSurfaceFormat; @@ -326,10 +350,10 @@ typedef enum SVGA3dSurfaceFormat { #define SVGA3D_SURFACE_HINT_RENDERTARGET (CONST64U(1) << 6) #define SVGA3D_SURFACE_HINT_DEPTHSTENCIL (CONST64U(1) << 7) #define SVGA3D_SURFACE_HINT_WRITEONLY (CONST64U(1) << 8) -#define SVGA3D_SURFACE_MASKABLE_ANTIALIAS (CONST64U(1) << 9) +#define SVGA3D_SURFACE_DEAD2 (CONST64U(1) << 9) #define SVGA3D_SURFACE_AUTOGENMIPMAPS (CONST64U(1) << 10) -#define SVGA3D_SURFACE_DECODE_RENDERTARGET (CONST64U(1) << 11) +#define SVGA3D_SURFACE_DEAD1 (CONST64U(1) << 11) /* * Is this surface using a base-level pitch for it's mob backing? @@ -387,7 +411,7 @@ typedef enum SVGA3dSurfaceFormat { * Setting this flag allow this surface to be used with the * SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command. It is only valid for * buffer surfaces, and no bind flags are allowed to be set on surfaces - * with this flag. + * with this flag except SVGA3D_SURFACE_TRANSFER_TO_BUFFER. */ #define SVGA3D_SURFACE_TRANSFER_FROM_BUFFER (CONST64U(1) << 30) @@ -402,7 +426,31 @@ typedef enum SVGA3dSurfaceFormat { */ #define SVGA3D_SURFACE_MULTISAMPLE (CONST64U(1) << 32) -#define SVGA3D_SURFACE_FLAG_MAX (CONST64U(1) << 33) +/* + * Specified that the surface is allowed to be bound to a UAView. + */ +#define SVGA3D_SURFACE_BIND_UAVIEW (CONST64U(1) << 33) + +/* + * Setting this flag allow this surface to be used with the + * SVGA_3D_CMD_DX_TRANSFER_TO_BUFFER command. It is only valid for + * buffer surfaces, and no bind flags are allowed to be set on surfaces + * with this flag except SVGA3D_SURFACE_TRANSFER_FROM_BUFFER. + */ +#define SVGA3D_SURFACE_TRANSFER_TO_BUFFER (CONST64U(1) << 34) + +#define SVGA3D_SURFACE_BIND_LOGICOPS (CONST64U(1) << 35) + +/* + * Optional flags for use with SVGA3D_SURFACE_BIND_UAVIEW + */ +#define SVGA3D_SURFACE_BIND_RAW_VIEWS (CONST64U(1) << 36) +#define SVGA3D_SURFACE_BUFFER_STRUCTURED (CONST64U(1) << 37) + +#define SVGA3D_SURFACE_DRAWINDIRECT_ARGS (CONST64U(1) << 38) +#define SVGA3D_SURFACE_RESOURCE_CLAMP (CONST64U(1) << 39) + +#define SVGA3D_SURFACE_FLAG_MAX (CONST64U(1) << 40) /* * Surface flags types: @@ -428,17 +476,25 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_STAGING_DOWNLOAD | \ SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_HB_PRESENT_DISALLOWED_MASK \ ( SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_RESERVED1 | \ SVGA3D_SURFACE_MULTISAMPLE \ ) #define SVGA3D_SURFACE_2D_DISALLOWED_MASK \ ( SVGA3D_SURFACE_CUBEMAP | \ - SVGA3D_SURFACE_MASKABLE_ANTIALIAS | \ SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ @@ -448,7 +504,14 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_BASICOPS_DISALLOWED_MASK \ @@ -456,6 +519,7 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_RESERVED1 | \ SVGA3D_SURFACE_MULTISAMPLE \ ) @@ -474,7 +538,14 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_STAGING_DOWNLOAD | \ SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ - SVGA3D_SURFACE_MULTISAMPLE \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_BUFFER_DISALLOWED_MASK \ @@ -482,10 +553,11 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_AUTOGENMIPMAPS | \ SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ - SVGA3D_SURFACE_MASKABLE_ANTIALIAS | \ + SVGA3D_SURFACE_DEAD2 | \ SVGA3D_SURFACE_ARRAY | \ SVGA3D_SURFACE_MULTISAMPLE | \ - SVGA3D_SURFACE_MOB_PITCH \ + SVGA3D_SURFACE_MOB_PITCH | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) #define SVGA3D_SURFACE_MULTISAMPLE_DISALLOWED_MASK \ @@ -494,14 +566,23 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_VOLUME | \ SVGA3D_SURFACE_1D | \ SVGA3D_SURFACE_SCREENTARGET | \ - SVGA3D_SURFACE_MOB_PITCH \ + SVGA3D_SURFACE_MOB_PITCH | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_RESERVED1 | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS \ ) -#define SVGA3D_SURFACE_DX_ONLY_MASK \ - ( SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ - SVGA3D_SURFACE_STAGING_UPLOAD | \ - SVGA3D_SURFACE_STAGING_DOWNLOAD | \ - SVGA3D_SURFACE_TRANSFER_FROM_BUFFER \ +#define SVGA3D_SURFACE_DX_ONLY_MASK \ + ( SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER \ ) #define SVGA3D_SURFACE_STAGING_MASK \ @@ -516,9 +597,135 @@ typedef uint64 SVGA3dSurfaceAllFlags; SVGA3D_SURFACE_BIND_SHADER_RESOURCE | \ SVGA3D_SURFACE_BIND_RENDER_TARGET | \ SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ - SVGA3D_SURFACE_BIND_STREAM_OUTPUT \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS \ + ) + +#define SVGA3D_SURFACE_VADECODE_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_HINT_STATIC | \ + SVGA3D_SURFACE_HINT_DYNAMIC | \ + SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_TEXTURE | \ + SVGA3D_SURFACE_HINT_RENDERTARGET | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_HINT_WRITEONLY | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_AUTOGENMIPMAPS | \ + SVGA3D_SURFACE_HINT_RT_LOCKABLE | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_SCREENTARGET | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_RENDER_TARGET | \ + SVGA3D_SURFACE_BIND_SHADER_RESOURCE | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_INACTIVE | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_HINT_INDIRECT_UPDATE | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_VAPROCESSFRAME_OUTPUT_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_INACTIVE | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_VADECODE | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_VAPROCESSFRAME_INPUT_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_HINT_INDEXBUFFER | \ + SVGA3D_SURFACE_HINT_VERTEXBUFFER | \ + SVGA3D_SURFACE_HINT_DEPTHSTENCIL | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_SCREENTARGET | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_STAGING_UPLOAD | \ + SVGA3D_SURFACE_STAGING_DOWNLOAD | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_LOGICOPS | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ + ) + +#define SVGA3D_SURFACE_LOGICOPS_DISALLOWED_MASK \ + ( SVGA3D_SURFACE_CUBEMAP | \ + SVGA3D_SURFACE_DEAD2 | \ + SVGA3D_SURFACE_AUTOGENMIPMAPS | \ + SVGA3D_SURFACE_VOLUME | \ + SVGA3D_SURFACE_1D | \ + SVGA3D_SURFACE_BIND_VERTEX_BUFFER | \ + SVGA3D_SURFACE_BIND_INDEX_BUFFER | \ + SVGA3D_SURFACE_BIND_CONSTANT_BUFFER | \ + SVGA3D_SURFACE_BIND_DEPTH_STENCIL | \ + SVGA3D_SURFACE_BIND_STREAM_OUTPUT | \ + SVGA3D_SURFACE_TRANSFER_FROM_BUFFER | \ + SVGA3D_SURFACE_VADECODE | \ + SVGA3D_SURFACE_MULTISAMPLE | \ + SVGA3D_SURFACE_BIND_UAVIEW | \ + SVGA3D_SURFACE_TRANSFER_TO_BUFFER | \ + SVGA3D_SURFACE_BIND_RAW_VIEWS | \ + SVGA3D_SURFACE_BUFFER_STRUCTURED | \ + SVGA3D_SURFACE_DRAWINDIRECT_ARGS | \ + SVGA3D_SURFACE_RESOURCE_CLAMP \ ) +#define SVGA3D_BUFFER_STRUCTURED_STRIDE_MAX 2048 + + +/* + * These are really the D3DFORMAT_OP defines from the wdk. We need + * them so that we can query the host for what the supported surface + * operations are (when we're using the D3D backend, in particular), + * and so we can send those operations to the guest. + */ typedef enum { SVGA3DFORMAT_OP_TEXTURE = 0x00000001, SVGA3DFORMAT_OP_VOLUMETEXTURE = 0x00000002, @@ -1338,7 +1545,40 @@ typedef enum { SVGA3D_PRIMITIVE_LINESTRIP_ADJ = 8, SVGA3D_PRIMITIVE_TRIANGLELIST_ADJ = 9, SVGA3D_PRIMITIVE_TRIANGLESTRIP_ADJ = 10, - SVGA3D_PRIMITIVE_MAX + SVGA3D_PRIMITIVE_DX10_MAX = 11, + SVGA3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 11, + SVGA3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 12, + SVGA3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 13, + SVGA3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 14, + SVGA3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 15, + SVGA3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 16, + SVGA3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 17, + SVGA3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 18, + SVGA3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 19, + SVGA3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 20, + SVGA3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 21, + SVGA3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 22, + SVGA3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 23, + SVGA3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 24, + SVGA3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 25, + SVGA3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 26, + SVGA3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 27, + SVGA3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 28, + SVGA3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 29, + SVGA3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 30, + SVGA3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 31, + SVGA3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 32, + SVGA3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 33, + SVGA3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 34, + SVGA3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 35, + SVGA3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 36, + SVGA3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 37, + SVGA3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 38, + SVGA3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 39, + SVGA3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 40, + SVGA3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 41, + SVGA3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 42, + SVGA3D_PRIMITIVE_MAX = 43 } SVGA3dPrimitiveType; typedef enum { @@ -1442,16 +1682,15 @@ typedef enum { SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS = 5, SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE = 6, SVGA3D_QUERYTYPE_OCCLUSION64 = 7, - SVGA3D_QUERYTYPE_EVENT = 8, - SVGA3D_QUERYTYPE_DX10_MAX = 9, - SVGA3D_QUERYTYPE_SOSTATS_STREAM0 = 9, - SVGA3D_QUERYTYPE_SOSTATS_STREAM1 = 10, - SVGA3D_QUERYTYPE_SOSTATS_STREAM2 = 11, - SVGA3D_QUERYTYPE_SOSTATS_STREAM3 = 12, - SVGA3D_QUERYTYPE_SOP_STREAM0 = 13, - SVGA3D_QUERYTYPE_SOP_STREAM1 = 14, - SVGA3D_QUERYTYPE_SOP_STREAM2 = 15, - SVGA3D_QUERYTYPE_SOP_STREAM3 = 16, + SVGA3D_QUERYTYPE_DX10_MAX = 8, + SVGA3D_QUERYTYPE_SOSTATS_STREAM0 = 8, + SVGA3D_QUERYTYPE_SOSTATS_STREAM1 = 9, + SVGA3D_QUERYTYPE_SOSTATS_STREAM2 = 10, + SVGA3D_QUERYTYPE_SOSTATS_STREAM3 = 11, + SVGA3D_QUERYTYPE_SOP_STREAM0 = 12, + SVGA3D_QUERYTYPE_SOP_STREAM1 = 13, + SVGA3D_QUERYTYPE_SOP_STREAM2 = 14, + SVGA3D_QUERYTYPE_SOP_STREAM3 = 15, SVGA3D_QUERYTYPE_MAX } SVGA3dQueryType; @@ -1584,28 +1823,33 @@ typedef enum { SVGA3D_READ_HOST_VRAM = 2, } SVGA3dTransferType; -typedef enum { - SVGA3D_LOGICOP_INVALID = 0, - SVGA3D_LOGICOP_MIN = 1, - SVGA3D_LOGICOP_COPY = 1, - SVGA3D_LOGICOP_NOT = 2, - SVGA3D_LOGICOP_AND = 3, - SVGA3D_LOGICOP_OR = 4, - SVGA3D_LOGICOP_XOR = 5, - SVGA3D_LOGICOP_NXOR = 6, - SVGA3D_LOGICOP_ROP3MIN = 30, /* 7-29 are reserved for future logic ops. */ - SVGA3D_LOGICOP_ROP3MAX = (SVGA3D_LOGICOP_ROP3MIN + 255), - SVGA3D_LOGICOP_MAX = (SVGA3D_LOGICOP_ROP3MAX + 1), -} SVGA3dLogicOp; +#define SVGA3D_LOGICOP_INVALID 0 +#define SVGA3D_LOGICOP_MIN 1 +#define SVGA3D_LOGICOP_COPY 1 +#define SVGA3D_LOGICOP_NOT 2 +#define SVGA3D_LOGICOP_AND 3 +#define SVGA3D_LOGICOP_OR 4 +#define SVGA3D_LOGICOP_XOR 5 +#define SVGA3D_LOGICOP_NXOR 6 +#define SVGA3D_LOGICOP_ROP3 7 +#define SVGA3D_LOGICOP_MAX 8 + +typedef uint16 SVGA3dLogicOp; + +#define SVGA3D_LOGICOP_ROP3_INVALID ((uint16) -1) +#define SVGA3D_LOGICOP_ROP3_MIN 0 +#define SVGA3D_LOGICOP_ROP3_MAX 256 + +typedef uint16 SVGA3dLogicOpRop3; typedef #include "vmware_pack_begin.h" struct { union { struct { - uint16 function; /* SVGA3dFogFunction */ - uint8 type; /* SVGA3dFogType */ - uint8 base; /* SVGA3dFogBase */ + uint16 function; // SVGA3dFogFunction + uint8 type; // SVGA3dFogType + uint8 base; // SVGA3dFogBase }; uint32 uintValue; }; @@ -1742,4 +1986,15 @@ typedef enum SVGA3dMSQualityLevel { SVGA3D_MS_QUALITY_MAX = 2, } SVGA3dMSQualityLevel; +/* + * Screen Target Update Flags + */ + +typedef enum SVGA3dFrameUpdateType { + SVGA3D_FRAME_END = 0, + SVGA3D_FRAME_PARTIAL = 1, + SVGA3D_FRAME_UNKNOWN = 2, + SVGA3D_FRAME_MAX = 3, +} SVGA3dFrameUpdateType; + #endif /* _SVGA3D_TYPES_H_ */ diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h index 056f54b35d73..19fb9e3299e7 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga_reg.h @@ -70,8 +70,7 @@ typedef uint32 SVGAMobId; /* * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned - * cursor bypass mode. This is still supported, but no new guest - * drivers should use it. + * cursor bypass mode. */ #define SVGA_CURSOR_ON_HIDE 0x0 #define SVGA_CURSOR_ON_SHOW 0x1 @@ -136,6 +135,17 @@ typedef uint32 SVGAMobId; #define SVGA_IRQFLAG_COMMAND_BUFFER 0x8 /* Command buffer completed */ #define SVGA_IRQFLAG_ERROR 0x10 /* Error while processing commands */ +/* + * The byte-size is the size of the actual cursor data, + * possibly after expanding it to the current bit depth. + * + * 40K is sufficient memory for two 32-bit planes for a 64 x 64 cursor. + * + * The dimension limit is a bound on the maximum width or height. + */ +#define SVGA_MAX_CURSOR_CMD_BYTES (40 * 1024) +#define SVGA_MAX_CURSOR_CMD_DIMENSION 1024 + /* * Registers */ @@ -169,7 +179,7 @@ enum { SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */ SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */ SVGA_REG_GUEST_ID = 23, /* (Deprecated) */ - SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */ + SVGA_REG_DEAD = 24, /* Drivers should never write this. */ SVGA_REG_CURSOR_X = 25, /* (Deprecated) */ SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */ SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */ @@ -208,7 +218,13 @@ enum { SVGA_REG_MAX_PRIMARY_MEM = 50, SVGA_REG_MAX_PRIMARY_BOUNDING_BOX_MEM = 50, - SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, /* Sugested limit on mob mem */ + /* + * Legacy version of SVGA_REG_GBOBJECT_MEM_SIZE_KB for drivers that + * don't know how to convert to a 64-bit byte value without overflowing. + * (See SVGA_REG_GBOBJECT_MEM_SIZE_KB). + */ + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB = 51, + SVGA_REG_DEV_CAP = 52, /* Write dev cap index, read value */ SVGA_REG_CMD_PREPEND_LOW = 53, SVGA_REG_CMD_PREPEND_HIGH = 54, @@ -218,7 +234,59 @@ enum { SVGA_REG_BLANK_SCREEN_TARGETS = 58, SVGA_REG_CAP2 = 59, SVGA_REG_DEVEL_CAP = 60, - SVGA_REG_TOP = 61, /* Must be 1 more than the last register */ + + /* + * Allow the guest to hint to the device which driver is running. + * + * This should not generally change device behavior, but might be + * convenient to work-around specific bugs in guest drivers. + * + * Drivers should first write their id value into SVGA_REG_GUEST_DRIVER_ID, + * and then fill out all of the version registers that they have defined. + * + * After the driver has written all of the registers, they should + * then write the value SVGA_REG_GUEST_DRIVER_ID_SUBMIT to the + * SVGA_REG_GUEST_DRIVER_ID register, to signal that they have finished. + * + * The SVGA_REG_GUEST_DRIVER_ID values are defined below by the + * SVGARegGuestDriverId enum. + * + * The SVGA_REG_GUEST_DRIVER_VERSION fields are driver-specific, + * but ideally should encode a monotonically increasing number that allows + * the device to perform inequality checks against ranges of driver versions. + */ + SVGA_REG_GUEST_DRIVER_ID = 61, + SVGA_REG_GUEST_DRIVER_VERSION1 = 62, + SVGA_REG_GUEST_DRIVER_VERSION2 = 63, + SVGA_REG_GUEST_DRIVER_VERSION3 = 64, + SVGA_REG_CURSOR_MOBID = 65, + SVGA_REG_CURSOR_MAX_BYTE_SIZE = 66, + SVGA_REG_CURSOR_MAX_DIMENSION = 67, + + SVGA_REG_FIFO_CAPS = 68, + SVGA_REG_FENCE = 69, + + SVGA_REG_RESERVED1 = 70, + SVGA_REG_RESERVED2 = 71, + SVGA_REG_RESERVED3 = 72, + SVGA_REG_RESERVED4 = 73, + SVGA_REG_RESERVED5 = 74, + SVGA_REG_SCREENDMA = 75, + + /* + * The maximum amount of guest-backed objects that the device can have + * resident at a time. Guest-drivers should keep their working set size + * below this limit for best performance. + * + * Note that this value is in kilobytes, and not bytes, because the actual + * number of bytes might be larger than can fit in a 32-bit register. + * + * PLEASE USE A 64-BIT VALUE WHEN CONVERTING THIS INTO BYTES. + * (See SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB). + */ + SVGA_REG_GBOBJECT_MEM_SIZE_KB = 76, + + SVGA_REG_TOP = 77, /* Must be 1 more than the last register */ SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ /* Next 768 (== 256*3) registers exist for colormap */ @@ -229,6 +297,20 @@ enum { the use of the current SVGA driver. */ }; + +/* + * Values for SVGA_REG_GUEST_DRIVER_ID. + */ +typedef enum SVGARegGuestDriverId { + SVGA_REG_GUEST_DRIVER_ID_UNKNOWN = 0, + SVGA_REG_GUEST_DRIVER_ID_WDDM = 1, + SVGA_REG_GUEST_DRIVER_ID_LINUX = 2, + SVGA_REG_GUEST_DRIVER_ID_MAX, + + SVGA_REG_GUEST_DRIVER_ID_SUBMIT = MAX_UINT32, +} SVGARegGuestDriverId; + + /* * Guest memory regions (GMRs): * @@ -416,7 +498,6 @@ typedef enum { SVGA_CB_CONTEXT_0 = 0x0, SVGA_CB_CONTEXT_1 = 0x1, /* Supported with SVGA_CAP_HP_CMD_QUEUE */ SVGA_CB_CONTEXT_MAX = 0x2, - SVGA_CB_CONTEXT_HP_MAX = 0x2, } SVGACBContext; @@ -733,9 +814,6 @@ SVGASignedPoint; * and must not be reused. Those capabilities will never be reported * by new versions of the SVGA device. * - * XXX: Add longer descriptions for each capability, including a list - * of the new features that each capability provides. - * * SVGA_CAP_IRQMASK -- * Provides device interrupts. Adds device register SVGA_REG_IRQMASK * to set interrupt mask and direct I/O port SVGA_IRQSTATUS_PORT to @@ -842,17 +920,51 @@ SVGASignedPoint; * Allow the IntraSurfaceCopy command. * * SVGA_CAP2_DX2 -- - * Allow the DefineGBSurface_v3, WholeSurfaceCopy. + * Allow the DefineGBSurface_v3, WholeSurfaceCopy, WriteZeroSurface, and + * HintZeroSurface commands, and the SVGA_REG_GUEST_DRIVER_ID register. + * + * SVGA_CAP2_GB_MEMSIZE_2 -- + * Allow the SVGA_REG_GBOBJECT_MEM_SIZE_KB register. + * + * SVGA_CAP2_SCREENDMA_REG -- + * Allow the SVGA_REG_SCREENDMA register. + * + * SVGA_CAP2_OTABLE_PTDEPTH_2 -- + * Allow 2 level page tables for OTable commands. + * + * SVGA_CAP2_NON_MS_TO_MS_STRETCHBLT -- + * Allow a stretch blt from a non-multisampled surface to a multisampled + * surface. + * + * SVGA_CAP2_CURSOR_MOB -- + * Allow the SVGA_REG_CURSOR_MOBID register. + * + * SVGA_CAP2_MSHINT -- + * Allow the SVGA_REG_MSHINT register. + * + * SVGA_CAP2_DX3 -- + * Allows the DefineGBSurface_v4 command. + * Allows the DXDefineDepthStencilView_v2, DXDefineStreamOutputWithMob, + * and DXBindStreamOutput commands if 3D is also available. + * Allows the DXPredStagingCopy and DXStagingCopy commands if SM41 + * is also available. * * SVGA_CAP2_RESERVED -- * Reserve the last bit for extending the SVGA capabilities to some * future mechanisms. */ -#define SVGA_CAP2_NONE 0x00000000 -#define SVGA_CAP2_GROW_OTABLE 0x00000001 -#define SVGA_CAP2_INTRA_SURFACE_COPY 0x00000002 -#define SVGA_CAP2_DX2 0x00000004 -#define SVGA_CAP2_RESERVED 0x80000000 +#define SVGA_CAP2_NONE 0x00000000 +#define SVGA_CAP2_GROW_OTABLE 0x00000001 +#define SVGA_CAP2_INTRA_SURFACE_COPY 0x00000002 +#define SVGA_CAP2_DX2 0x00000004 +#define SVGA_CAP2_GB_MEMSIZE_2 0x00000008 +#define SVGA_CAP2_SCREENDMA_REG 0x00000010 +#define SVGA_CAP2_OTABLE_PTDEPTH_2 0x00000020 +#define SVGA_CAP2_NON_MS_TO_MS_STRETCHBLT 0x00000040 +#define SVGA_CAP2_CURSOR_MOB 0x00000080 +#define SVGA_CAP2_MSHINT 0x00000100 +#define SVGA_CAP2_DX3 0x00000400 +#define SVGA_CAP2_RESERVED 0x80000000 /* @@ -875,7 +987,9 @@ typedef enum { SVGABackdoorCapFifoCaps = 1, SVGABackdoorCap3dHWVersion = 2, SVGABackdoorCapDeviceCaps2 = 3, - SVGABackdoorCapMax = 4, + SVGABackdoorCapDevelCaps = 4, + SVGABackdoorDevelRenderer = 5, + SVGABackdoorCapMax = 6, } SVGABackdoorCapType; @@ -1055,103 +1169,80 @@ enum { /* * FIFO Synchronization Registers * - * This explains the relationship between the various FIFO - * sync-related registers in IOSpace and in FIFO space. - * * SVGA_REG_SYNC -- * - * The SYNC register can be used in two different ways by the guest: - * - * 1. If the guest wishes to fully sync (drain) the FIFO, - * it will write once to SYNC then poll on the BUSY - * register. The FIFO is sync'ed once BUSY is zero. - * - * 2. If the guest wants to asynchronously wake up the host, - * it will write once to SYNC without polling on BUSY. - * Ideally it will do this after some new commands have - * been placed in the FIFO, and after reading a zero - * from SVGA_FIFO_BUSY. - * - * (1) is the original behaviour that SYNC was designed to - * support. Originally, a write to SYNC would implicitly - * trigger a read from BUSY. This causes us to synchronously - * process the FIFO. - * - * This behaviour has since been changed so that writing SYNC - * will *not* implicitly cause a read from BUSY. Instead, it - * makes a channel call which asynchronously wakes up the MKS - * thread. - * - * New guests can use this new behaviour to implement (2) - * efficiently. This lets guests get the host's attention - * without waiting for the MKS to poll, which gives us much - * better CPU utilization on SMP hosts and on UP hosts while - * we're blocked on the host GPU. - * - * Old guests shouldn't notice the behaviour change. SYNC was - * never guaranteed to process the entire FIFO, since it was - * bounded to a particular number of CPU cycles. Old guests will - * still loop on the BUSY register until the FIFO is empty. - * - * Writing to SYNC currently has the following side-effects: - * - * - Sets SVGA_REG_BUSY to TRUE (in the monitor) - * - Asynchronously wakes up the MKS thread for FIFO processing - * - The value written to SYNC is recorded as a "reason", for - * stats purposes. - * - * If SVGA_FIFO_BUSY is available, drivers are advised to only - * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set - * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will - * eventually set SVGA_FIFO_BUSY on its own, but this approach - * lets the driver avoid sending multiple asynchronous wakeup - * messages to the MKS thread. + * The SYNC register can be used by the guest driver to signal to the + * device that the guest driver is waiting for previously submitted + * commands to complete. + * + * When the guest driver writes to the SYNC register, the device sets + * the BUSY register to TRUE, and starts processing the submitted commands + * (if it was not already doing so). When all previously submitted + * commands are finished and the device is idle again, it sets the BUSY + * register back to FALSE. (If the guest driver submits new commands + * after writing the SYNC register, the new commands are not guaranteed + * to have been procesesd.) + * + * When guest drivers are submitting commands using the FIFO, the device + * periodically polls to check for new FIFO commands when idle, which may + * introduce a delay in command processing. If the guest-driver wants + * the commands to be processed quickly (which it typically does), it + * should write SYNC after each batch of commands is committed to the + * FIFO to immediately wake up the device. For even better performance, + * the guest can use the SVGA_FIFO_BUSY register to avoid these extra + * SYNC writes if the device is already active, using the technique known + * as "Ringing the Doorbell" (described below). (Note that command + * buffer submission implicitly wakes up the device, and so doesn't + * suffer from this problem.) + * + * The SYNC register can also be used in combination with BUSY to + * synchronously ensure that all SVGA commands are processed (with both + * the FIFO and command-buffers). To do this, the guest driver should + * write to SYNC, and then loop reading BUSY until BUSY returns FALSE. + * This technique is known as a "Legacy Sync". * * SVGA_REG_BUSY -- * * This register is set to TRUE when SVGA_REG_SYNC is written, - * and it reads as FALSE when the FIFO has been completely - * drained. - * - * Every read from this register causes us to synchronously - * process FIFO commands. There is no guarantee as to how many - * commands each read will process. + * and is set back to FALSE when the device has finished processing + * all commands and is idle again. * - * CPU time spent processing FIFO commands will be billed to - * the guest. + * Every read from the BUSY reigster will block for an undefined + * amount of time (normally until the device finishes some interesting + * work unit), or the device is idle. * - * New drivers should avoid using this register unless they - * need to guarantee that the FIFO is completely drained. It - * is overkill for performing a sync-to-fence. Older drivers - * will use this register for any type of synchronization. + * Guest drivers can also do a partial Legacy Sync to check for some + * particular condition, for instance by stopping early when a fence + * passes before BUSY has been set back to FALSE. This is particularly + * useful if the guest-driver knows that it is blocked waiting on the + * device, because it will yield CPU time back to the host. * * SVGA_FIFO_BUSY -- * - * This register is a fast way for the guest driver to check - * whether the FIFO is already being processed. It reads and - * writes at normal RAM speeds, with no monitor intervention. - * - * If this register reads as TRUE, the host is guaranteeing that - * any new commands written into the FIFO will be noticed before - * the MKS goes back to sleep. + * The SVGA_FIFO_BUSY register is a fast way for the guest driver to check + * whether the device is actively processing FIFO commands before writing + * the more expensive SYNC register. * - * If this register reads as FALSE, no such guarantee can be - * made. + * If this register reads as TRUE, the device is actively processing + * FIFO commands. * - * The guest should use this register to quickly determine - * whether or not it needs to wake up the host. If the guest - * just wrote a command or group of commands that it would like - * the host to begin processing, it should: + * If this register reads as FALSE, the device may not be actively + * processing commands, and the guest driver should try + * "Ringing the Doorbell". * - * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further - * action is necessary. + * To Ring the Doorbell, the guest should: * - * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest - * code that we've already sent a SYNC to the host and we - * don't need to send a duplicate. + * 1. Have already written their batch of commands into the FIFO. + * 2. Check if the SVGA_FIFO_BUSY register is available by reading + * SVGA_FIFO_MIN. + * 3. Read SVGA_FIFO_BUSY. If it reads as TRUE, the device is actively + * processing FIFO commands, and no further action is necessary. + * 4. If SVGA_FIFO_BUSY was FALSE, write TRUE to SVGA_REG_SYNC. * - * 3. Write a reason to SVGA_REG_SYNC. This will send an - * asynchronous wakeup to the MKS thread. + * For maximum performance, this procedure should be followed after + * every meaningful batch of commands has been written into the FIFO. + * (Normally when the underlying application signals it's finished a + * meaningful work unit by calling Flush.) */ @@ -1164,9 +1255,6 @@ enum { * Video -- SVGA Video overlay units are supported * Escape -- Escape command is supported * - * XXX: Add longer descriptions for each capability, including a list - * of the new features that each capability provides. - * * SVGA_FIFO_CAP_SCREEN_OBJECT -- * * Provides dynamic multi-screen rendering, for improved Unity and @@ -1278,6 +1366,15 @@ enum { #define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff +/* + * ScreenDMA Register Values + */ + +#define SVGA_SCREENDMA_REG_UNDEFINED 0 +#define SVGA_SCREENDMA_REG_NOT_PRESENT 1 +#define SVGA_SCREENDMA_REG_PRESENT 2 +#define SVGA_SCREENDMA_REG_MAX 3 + /* * Video overlay support */ @@ -1664,6 +1761,80 @@ struct { SVGAFifoCmdDefineAlphaCursor; +/* + * Provide a new large cursor image, as an AND/XOR mask. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + uint32 andMaskDepth; + uint32 xorMaskDepth; + /* + * Followed by scanline data for AND mask, then XOR mask. + * Each scanline is padded to a 32-bit boundary. + */ +} +#include "vmware_pack_end.h" +SVGAGBColorCursorHeader; + + +/* + * Provide a new large cursor image, in 32-bit BGRA format. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + uint32 hotspotX; + uint32 hotspotY; + uint32 width; + uint32 height; + /* Followed by scanline data */ +} +#include "vmware_pack_end.h" +SVGAGBAlphaCursorHeader; + + /* + * Define the SVGA guest backed cursor types + */ + +typedef enum { + SVGA_COLOR_CURSOR = 0, + SVGA_ALPHA_CURSOR = 1, +} SVGAGBCursorType; + +/* + * Provide a new large cursor image. + * + * Should only be used for CursorMob functionality + */ + +typedef +#include "vmware_pack_begin.h" +struct { + SVGAGBCursorType type; + union { + SVGAGBColorCursorHeader colorHeader; + SVGAGBAlphaCursorHeader alphaHeader; + } header; + uint32 sizeInBytes; + /* + * Followed by the cursor data + */ +} +#include "vmware_pack_end.h" +SVGAGBCursorHeader; + + /* * SVGA_CMD_UPDATE_VERBOSE -- * @@ -2061,9 +2232,12 @@ SVGAFifoCmdRemapGMR2; #define SVGA_VRAM_MAX_SIZE (128 * 1024 * 1024) #define SVGA_MEMORY_SIZE_MAX (1024 * 1024 * 1024) #define SVGA_FIFO_SIZE_MAX (2 * 1024 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_MIN (32 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_MAX (2 * 1024 * 1024) -#define SVGA_GRAPHICS_MEMORY_KB_DEFAULT (256 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MIN (32 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_2GB (2 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_3GB (3 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_4GB (4 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_MAX_8GB (8 * 1024 * 1024) +#define SVGA_GRAPHICS_MEMORY_KB_DEFAULT (256 * 1024) #define SVGA_VRAM_SIZE_W2K (64 * 1024 * 1024) /* 64 MB */ @@ -2086,4 +2260,6 @@ SVGAFifoCmdRemapGMR2; #define SVGA_FIFO_SIZE_GBOBJECTS (256 * 1024) #define SVGA_VRAM_SIZE_GBOBJECTS (4 * 1024 * 1024) +#define SVGA_PCI_REGS_PAGES (1) + #endif diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga_types.h b/drivers/gpu/drm/vmwgfx/device_include/svga_types.h index 350bbc6fab02..beddccee40f6 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga_types.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga_types.h @@ -37,6 +37,7 @@ typedef s8 int8; typedef uint64 PA; typedef uint32 PPN; +typedef uint32 PPN32; typedef uint64 PPN64; typedef bool Bool; -- cgit 1.4.1 From 4dec28053ba0a10294297ad8aa70ab1f0884c41b Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 11:48:09 -0800 Subject: drm/vmwgfx: Add a new enum for SM5 graphics context capability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new enum to represent new SM5 graphics context capability in vmwgfx. v2: use new correct cap bits (merged several later commits into it). Signed-off-by: Deepak Rawat Signed-off-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 11 +++++++++++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 5277b9832d58..b55bd3b5f5cd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -290,6 +290,8 @@ static void vmw_print_capabilities2(uint32_t capabilities2) DRM_INFO(" Grow oTable.\n"); if (capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY) DRM_INFO(" IntraSurface copy.\n"); + if (capabilities2 & SVGA_CAP2_DX3) + DRM_INFO(" DX3.\n"); } static void vmw_print_capabilities(uint32_t capabilities) @@ -900,6 +902,13 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) dev_priv->sm_type = VMW_SM_4_1; + + if (has_sm4_1_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX3)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM5); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_5; + } } ret = vmw_kms_init(dev_priv); @@ -913,6 +922,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) ? "yes." : "no."); + if (dev_priv->sm_type == VMW_SM_5) + DRM_INFO("SM5 support available.\n"); if (dev_priv->sm_type == VMW_SM_4_1) DRM_INFO("SM4_1 support available.\n"); if (dev_priv->sm_type == VMW_SM_4) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 243731813887..262e57623df4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -446,12 +446,14 @@ enum { * @VMW_SM_LEGACY: Pre DX context. * @VMW_SM_4: Context support upto SM4. * @VMW_SM_4_1: Context support upto SM4_1. + * @VMW_SM_5: Context support up to SM5. * @VMW_SM_MAX: Should be the last. */ enum vmw_sm_type { VMW_SM_LEGACY = 0, VMW_SM_4, VMW_SM_4_1, + VMW_SM_5, VMW_SM_MAX }; @@ -684,6 +686,17 @@ static inline bool has_sm4_1_context(const struct vmw_private *dev_priv) return (dev_priv->sm_type >= VMW_SM_4_1); } +/** + * has_sm5_context - Does the device support SM5 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM5 context or not. + */ +static inline bool has_sm5_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_5); +} + extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); -- cgit 1.4.1 From 7ebb47c9f9abf4950f1ab3f952194cb67f9caba7 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Fri, 3 May 2019 13:13:06 -0700 Subject: drm/vmwgfx: Read new register for GB memory when available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Virtual device added new register for suggested GB memory, read the new register when available. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index b55bd3b5f5cd..71e45b568511 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -720,9 +720,15 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->max_mob_pages = 0; dev_priv->max_mob_size = 0; if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) { - uint64_t mem_size = - vmw_read(dev_priv, - SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); + uint64_t mem_size; + + if (dev_priv->capabilities2 & SVGA_CAP2_GB_MEMSIZE_2) + mem_size = vmw_read(dev_priv, + SVGA_REG_GBOBJECT_MEM_SIZE_KB); + else + mem_size = + vmw_read(dev_priv, + SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB); /* * Workaround for low memory 2D VMs to compensate for the -- cgit 1.4.1 From d2e90ab3744f911c45823b3390fda25b102e76ee Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 13:43:20 -0800 Subject: drm/vmwgfx: Support SM5 shader type in command buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Virtual device now supports new shader types, allow them as valid shader type in command buffer. Also add per shader bind info in binding manager state for new shader type. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 11 ++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 14 +++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index 66e14e38d5e8..5a7e8db3e826 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -98,7 +98,7 @@ struct vmw_ctx_binding_state { struct vmw_ctx_bindinfo_so so_targets[SVGA3D_DX_MAX_SOTARGETS]; 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_DX10]; + struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE]; unsigned long dirty; DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS); @@ -151,6 +151,9 @@ static const size_t vmw_binding_shader_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].shader), offsetof(struct vmw_ctx_binding_state, per_shader[1].shader), offsetof(struct vmw_ctx_binding_state, per_shader[2].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[3].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[4].shader), + offsetof(struct vmw_ctx_binding_state, per_shader[5].shader), }; static const size_t vmw_binding_rt_offsets[] = { offsetof(struct vmw_ctx_binding_state, render_targets), @@ -162,6 +165,9 @@ static const size_t vmw_binding_cb_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].const_buffers), offsetof(struct vmw_ctx_binding_state, per_shader[1].const_buffers), offsetof(struct vmw_ctx_binding_state, per_shader[2].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[3].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[4].const_buffers), + offsetof(struct vmw_ctx_binding_state, per_shader[5].const_buffers), }; static const size_t vmw_binding_dx_ds_offsets[] = { offsetof(struct vmw_ctx_binding_state, ds_view), @@ -170,6 +176,9 @@ static const size_t vmw_binding_sr_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[0].shader_res), offsetof(struct vmw_ctx_binding_state, per_shader[1].shader_res), offsetof(struct vmw_ctx_binding_state, per_shader[2].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[3].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[4].shader_res), + offsetof(struct vmw_ctx_binding_state, per_shader[5].shader_res), }; static const size_t vmw_binding_so_offsets[] = { offsetof(struct vmw_ctx_binding_state, so_targets), diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 73f19f0fec88..4abed135c013 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2118,6 +2118,9 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer); + SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ? + SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10; + struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_cb binding; @@ -2141,7 +2144,7 @@ vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv, binding.size = cmd->body.sizeInBytes; binding.slot = cmd->body.slot; - if (binding.shader_slot >= SVGA3D_NUM_SHADERTYPE_DX10 || + if (binding.shader_slot >= max_shader_num || binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", (unsigned int) cmd->body.type, @@ -2169,12 +2172,15 @@ static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = container_of(header, typeof(*cmd), header); + SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? + SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; + u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || - cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { + cmd->body.type >= max_allowed) { VMW_DEBUG_USER("Invalid shader binding.\n"); return -EINVAL; } @@ -2198,6 +2204,8 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader); + SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ? + SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX; struct vmw_resource *res = NULL; struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); struct vmw_ctx_bindinfo_shader binding; @@ -2208,7 +2216,7 @@ static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv, cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || + if (cmd->body.type >= max_allowed || cmd->body.type < SVGA3D_SHADERTYPE_MIN) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); -- cgit 1.4.1 From 5e8ec0d919a4911f7cde01affa2bfd78a74b9b0f Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 13:51:08 -0800 Subject: drm/vmwgfx: Add support for UA view commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Neha Bhende Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 129 +++++++++++++++++++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 16 ++++ drivers/gpu/drm/vmwgfx/vmwgfx_context.c | 26 ++++-- drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 4 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 144 +++++++++++++++++++++++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_so.c | 12 ++- 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}, }; /** @@ -320,6 +341,18 @@ void vmw_binding_add(struct vmw_ctx_binding_state *cbs, INIT_LIST_HEAD(&loc->res_list); } +/** + * 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. * @@ -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; -- cgit 1.4.1 From b6fad7397521cb032b3222d750147fb111555a59 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 14:00:18 -0800 Subject: drm/vmwgfx: Add support for indirect and dispatch commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validate indirect and dispatch commands in command buffer. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 70 +++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index ed56d9918c6a..ecab6cbbc8d3 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2816,6 +2816,16 @@ static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv, &cmd->body.surface.sid, NULL); } +static int vmw_cmd_sm5(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return 0; +} + static int vmw_cmd_sm5_view_define(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) @@ -2938,6 +2948,57 @@ static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv, return ret; } +static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_draw_indexed_instanced_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDrawIndexedInstancedIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + +static int vmw_cmd_instanced_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_draw_instanced_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDrawInstancedIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + +static int vmw_cmd_dispatch_indirect(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_dispatch_indirect_cmd { + SVGA3dCmdHeader header; + SVGA3dCmdDXDispatchIndirect body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, + VMW_RES_DIRTY_NONE, user_surface_converter, + &cmd->body.argsBufferSid, NULL); +} + static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, void *buf, uint32_t *size) @@ -3303,8 +3364,17 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { 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_DRAW_INDEXED_INSTANCED_INDIRECT, + &vmw_cmd_indexed_instanced_indirect, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT, + &vmw_cmd_instanced_indirect, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH, &vmw_cmd_sm5, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH_INDIRECT, + &vmw_cmd_dispatch_indirect, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_CS_UA_VIEWS, &vmw_cmd_set_cs_uav, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2, + &vmw_cmd_sm5_view_define, true, false, true), }; bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) -- cgit 1.4.1 From 403fef50e32bf179d56215391f669aa51e7c4c73 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Tue, 18 Dec 2018 10:13:13 -0800 Subject: drm/vmwgfx: Rename stream output target binding tracker struct MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous name vmw_ctx_bindinfo_so is misleading because it actually represent so target and stream output is a new resource type that needs tracking for SM5 capable device. Also rename binding type enum and internal functions to reflect these belongs to so targets. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 36 ++++++++++++++++----------------- drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 6 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 4 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index f0a576698266..f923b3c7c152 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -57,7 +57,7 @@ #define VMW_BINDING_RT_BIT 0 #define VMW_BINDING_PS_BIT 1 -#define VMW_BINDING_SO_BIT 2 +#define VMW_BINDING_SO_T_BIT 2 #define VMW_BINDING_VB_BIT 3 #define VMW_BINDING_UAV_BIT 4 #define VMW_BINDING_CS_UAV_BIT 5 @@ -98,7 +98,7 @@ struct vmw_ctx_binding_state { struct vmw_ctx_bindinfo_view render_targets[SVGA3D_RT_MAX]; struct vmw_ctx_bindinfo_tex texture_units[SVGA3D_NUM_TEXTURE_UNITS]; struct vmw_ctx_bindinfo_view ds_view; - struct vmw_ctx_bindinfo_so so_targets[SVGA3D_DX_MAX_SOTARGETS]; + struct vmw_ctx_bindinfo_so_target so_targets[SVGA3D_DX_MAX_SOTARGETS]; 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]; @@ -119,7 +119,7 @@ static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_scrub_sr(struct vmw_ctx_bindinfo *bi, bool rebind); -static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind); +static int vmw_binding_scrub_so_target(struct vmw_ctx_bindinfo *bi, bool rebind); static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs); static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind); @@ -187,7 +187,7 @@ static const size_t vmw_binding_sr_offsets[] = { offsetof(struct vmw_ctx_binding_state, per_shader[4].shader_res), offsetof(struct vmw_ctx_binding_state, per_shader[5].shader_res), }; -static const size_t vmw_binding_so_offsets[] = { +static const size_t vmw_binding_so_target_offsets[] = { offsetof(struct vmw_ctx_binding_state, so_targets), }; static const size_t vmw_binding_vb_offsets[] = { @@ -236,10 +236,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = { .size = sizeof(struct vmw_ctx_bindinfo_view), .offsets = vmw_binding_dx_ds_offsets, .scrub_func = vmw_binding_scrub_dx_rt}, - [vmw_ctx_binding_so] = { - .size = sizeof(struct vmw_ctx_bindinfo_so), - .offsets = vmw_binding_so_offsets, - .scrub_func = vmw_binding_scrub_so}, + [vmw_ctx_binding_so_target] = { + .size = sizeof(struct vmw_ctx_bindinfo_so_target), + .offsets = vmw_binding_so_target_offsets, + .scrub_func = vmw_binding_scrub_so_target}, [vmw_ctx_binding_vb] = { .size = sizeof(struct vmw_ctx_bindinfo_vb), .offsets = vmw_binding_vb_offsets, @@ -874,8 +874,8 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, const struct vmw_ctx_bindinfo *bi, u32 max_num) { - const struct vmw_ctx_bindinfo_so *biso = - container_of(bi, struct vmw_ctx_bindinfo_so, bi); + const struct vmw_ctx_bindinfo_so_target *biso = + container_of(bi, struct vmw_ctx_bindinfo_so_target, bi); unsigned long i; SVGA3dSoTarget *so_buffer = (SVGA3dSoTarget *) cbs->bind_cmd_buffer; @@ -900,11 +900,11 @@ static void vmw_collect_so_targets(struct vmw_ctx_binding_state *cbs, } /** - * vmw_binding_emit_set_so - Issue delayed streamout binding commands + * vmw_emit_set_so_target - Issue delayed streamout binding commands * * @cbs: Pointer to the context's struct vmw_ctx_binding_state */ -static int vmw_emit_set_so(struct vmw_ctx_binding_state *cbs) +static int vmw_emit_set_so_target(struct vmw_ctx_binding_state *cbs) { const struct vmw_ctx_bindinfo *loc = &cbs->so_targets[0].bi; struct { @@ -1136,8 +1136,8 @@ static int vmw_binding_emit_dirty(struct vmw_ctx_binding_state *cbs) case VMW_BINDING_PS_BIT: ret = vmw_binding_emit_dirty_ps(cbs); break; - case VMW_BINDING_SO_BIT: - ret = vmw_emit_set_so(cbs); + case VMW_BINDING_SO_T_BIT: + ret = vmw_emit_set_so_target(cbs); break; case VMW_BINDING_VB_BIT: ret = vmw_emit_set_vb(cbs); @@ -1201,18 +1201,18 @@ static int vmw_binding_scrub_dx_rt(struct vmw_ctx_bindinfo *bi, bool rebind) } /** - * vmw_binding_scrub_so - Schedule a dx streamoutput buffer binding + * vmw_binding_scrub_so_target - Schedule a dx streamoutput buffer binding * scrub from a context * * @bi: single binding information. * @rebind: Whether to issue a bind instead of scrub command. */ -static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind) +static int vmw_binding_scrub_so_target(struct vmw_ctx_bindinfo *bi, bool rebind) { struct vmw_ctx_binding_state *cbs = vmw_context_binding_state(bi->ctx); - __set_bit(VMW_BINDING_SO_BIT, &cbs->dirty); + __set_bit(VMW_BINDING_SO_T_BIT, &cbs->dirty); return 0; } @@ -1387,7 +1387,7 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type) [vmw_ctx_binding_rt] = VMW_RES_DIRTY_SET, [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_so_target] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_uav] = VMW_RES_DIRTY_SET, [vmw_ctx_binding_cs_uav] = VMW_RES_DIRTY_SET, }; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h index da67cbc9cd73..8d5f87aad490 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h @@ -50,7 +50,7 @@ enum vmw_ctx_binding_type { vmw_ctx_binding_dx_rt, vmw_ctx_binding_sr, vmw_ctx_binding_ds, - vmw_ctx_binding_so, + vmw_ctx_binding_so_target, vmw_ctx_binding_vb, vmw_ctx_binding_ib, vmw_ctx_binding_uav, @@ -132,14 +132,14 @@ struct vmw_ctx_bindinfo_view { }; /** - * struct vmw_ctx_bindinfo_so - StreamOutput binding metadata + * struct vmw_ctx_bindinfo_so_target - StreamOutput binding metadata * * @bi: struct vmw_ctx_bindinfo we derive from. * @offset: Device data used to reconstruct binding command. * @size: Device data used to reconstruct binding command. * @slot: Device data used to reconstruct binding command. */ -struct vmw_ctx_bindinfo_so { +struct vmw_ctx_bindinfo_so_target { struct vmw_ctx_bindinfo bi; uint32 offset; uint32 size; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index ecab6cbbc8d3..d49169c68fba 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2479,7 +2479,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, SVGA3dCmdHeader *header) { struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context); - struct vmw_ctx_bindinfo_so binding; + struct vmw_ctx_bindinfo_so_target binding; struct vmw_resource *res; struct { SVGA3dCmdHeader header; @@ -2509,7 +2509,7 @@ static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv, binding.bi.ctx = ctx_node->ctx; binding.bi.res = res; - binding.bi.bt = vmw_ctx_binding_so, + binding.bi.bt = vmw_ctx_binding_so_target, binding.offset = cmd->targets[i].offset; binding.size = cmd->targets[i].sizeInBytes; binding.slot = i; -- cgit 1.4.1 From e8bead9c5c07497ce42d684729738f042896a237 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 14:04:31 -0800 Subject: drm/vmwgfx: Add support for streamoutput with mob commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Neha Bhende Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/Makefile | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_binding.c | 39 ++- drivers/gpu/drm/vmwgfx/vmwgfx_binding.h | 11 + drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c | 2 +- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 22 +- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 173 +++++++++++- drivers/gpu/drm/vmwgfx/vmwgfx_so.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c | 387 +++++++++++++++++++++++++++ 8 files changed, 630 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile index c877a21a0739..5c3515e8cce1 100644 --- a/drivers/gpu/drm/vmwgfx/Makefile +++ b/drivers/gpu/drm/vmwgfx/Makefile @@ -8,7 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \ vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \ vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \ - vmwgfx_validation.o vmwgfx_page_dirty.o \ + vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \ ttm_object.o ttm_lock.o obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c index f923b3c7c152..f41550797970 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c @@ -78,6 +78,7 @@ * @index_buffer: Index buffer binding. * @per_shader: Per shader-type bindings. * @ua_views: UAV bindings. + * @so_state: StreamOutput 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 @@ -103,6 +104,7 @@ struct vmw_ctx_binding_state { 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]; + struct vmw_ctx_bindinfo_so so_state; unsigned long dirty; 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); 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 int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind); static void vmw_binding_build_asserts(void) __attribute__ ((unused)); @@ -202,6 +205,9 @@ static const size_t vmw_binding_uav_offsets[] = { static const size_t vmw_binding_cs_uav_offsets[] = { offsetof(struct vmw_ctx_binding_state, ua_views[1].views), }; +static const size_t vmw_binding_so_offsets[] = { + offsetof(struct vmw_ctx_binding_state, so_state), +}; static const struct vmw_binding_info vmw_binding_infos[] = { [vmw_ctx_binding_shader] = { @@ -256,6 +262,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = { .size = sizeof(struct vmw_ctx_bindinfo_view), .offsets = vmw_binding_cs_uav_offsets, .scrub_func = vmw_binding_scrub_cs_uav}, + [vmw_ctx_binding_so] = { + .size = sizeof(struct vmw_ctx_bindinfo_so), + .offsets = vmw_binding_so_offsets, + .scrub_func = vmw_binding_scrub_so}, }; /** @@ -1290,6 +1300,33 @@ static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind) return 0; } +/** + * vmw_binding_scrub_so - Scrub a streamoutput binding from context. + * @bi: Single binding information. + * @rebind: Whether to issue a bind instead of scrub command. + */ +static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind) +{ + struct vmw_ctx_bindinfo_so *binding = + container_of(bi, typeof(*binding), bi); + struct vmw_private *dev_priv = bi->ctx->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetStreamOutput body; + } *cmd; + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_SET_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = rebind ? bi->res->id : SVGA3D_INVALID_ID; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + return 0; +} + /** * vmw_binding_state_alloc - Allocate a struct vmw_ctx_binding_state with * memory accounting. @@ -1393,7 +1430,7 @@ u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type) }; /* Review this function as new bindings are added. */ - BUILD_BUG_ON(vmw_ctx_binding_max != 13); + BUILD_BUG_ON(vmw_ctx_binding_max != 14); 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 8d5f87aad490..dcb71fd0bb3b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.h @@ -55,6 +55,7 @@ enum vmw_ctx_binding_type { vmw_ctx_binding_ib, vmw_ctx_binding_uav, vmw_ctx_binding_cs_uav, + vmw_ctx_binding_so, vmw_ctx_binding_max }; @@ -203,6 +204,16 @@ struct vmw_ctx_bindinfo_uav { uint32 index; }; +/** + * struct vmw_ctx_bindinfo_so - Stream output binding metadata. + * @bi: struct vmw_ctx_bindinfo we derive from. + * @slot: Device data used to reconstruct binding command. + */ +struct vmw_ctx_bindinfo_so { + struct vmw_ctx_bindinfo bi; + uint32 slot; +}; + extern void vmw_binding_add(struct vmw_ctx_binding_state *cbs, const struct vmw_ctx_bindinfo *ci, u32 shader_slot, u32 slot); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 08c5b2ccca98..65e8e7a97724 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -80,7 +80,7 @@ static const struct vmw_cotable_info co_info[] = { {1, sizeof(SVGACOTableDXDepthStencilEntry), NULL}, {1, sizeof(SVGACOTableDXRasterizerStateEntry), NULL}, {1, sizeof(SVGACOTableDXSamplerEntry), NULL}, - {1, sizeof(SVGACOTableDXStreamOutputEntry), NULL}, + {1, sizeof(SVGACOTableDXStreamOutputEntry), &vmw_dx_streamoutput_cotable_list_scrub}, {1, sizeof(SVGACOTableDXQueryEntry), NULL}, {1, sizeof(SVGACOTableDXShaderEntry), &vmw_dx_shader_cotable_list_scrub}, {1, sizeof(SVGACOTableDXUAViewEntry), &vmw_view_cotable_list_destroy} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 262e57623df4..cfd8eaf7973e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -202,6 +202,7 @@ enum vmw_res_type { vmw_res_dx_context, vmw_res_cotable, vmw_res_view, + vmw_res_streamoutput, vmw_res_max }; @@ -210,7 +211,8 @@ enum vmw_res_type { */ enum vmw_cmdbuf_res_type { vmw_cmdbuf_res_shader, - vmw_cmdbuf_res_view + vmw_cmdbuf_res_view, + vmw_cmdbuf_res_streamoutput }; struct vmw_cmdbuf_res_manager; @@ -1307,6 +1309,24 @@ extern struct vmw_resource * vmw_shader_lookup(struct vmw_cmdbuf_res_manager *man, u32 user_key, SVGA3dShaderType shader_type); +/* + * Streamoutput management + */ +struct vmw_resource * +vmw_dx_streamoutput_lookup(struct vmw_cmdbuf_res_manager *man, + u32 user_key); +int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man, + struct vmw_resource *ctx, + SVGA3dStreamOutputId user_key, + struct list_head *list); +void vmw_dx_streamoutput_set_size(struct vmw_resource *res, u32 size); +int vmw_dx_streamoutput_remove(struct vmw_cmdbuf_res_manager *man, + SVGA3dStreamOutputId user_key, + struct list_head *list); +void vmw_dx_streamoutput_cotable_list_scrub(struct vmw_private *dev_priv, + struct list_head *list, + bool readback); + /* * Command buffer managed resources - vmwgfx_cmdbuf_res.c */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index d49169c68fba..367d5b87ee6a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2948,6 +2948,169 @@ static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv, return ret; } +static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXDefineStreamOutputWithMob body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT); + ret = vmw_cotable_notify(res, cmd->body.soid); + if (ret) + return ret; + + return vmw_dx_streamoutput_add(sw_context->man, ctx_node->ctx, + cmd->body.soid, + &sw_context->staged_cmd_res); +} + +static int vmw_cmd_dx_destroy_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXDestroyStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + /* + * When device does not support SM5 then streamoutput with mob command is + * not available to user-space. Simply return in this case. + */ + if (!has_sm5_context(dev_priv)) + return 0; + + /* + * With SM5 capable device if lookup fails then user-space probably used + * old streamoutput define command. Return without an error. + */ + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) + return 0; + + return vmw_dx_streamoutput_remove(sw_context->man, cmd->body.soid, + &sw_context->staged_cmd_res); +} + +static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!has_sm5_context(dev_priv)) + return -EINVAL; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) { + DRM_ERROR("Cound not find streamoutput to bind.\n"); + return PTR_ERR(res); + } + + vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes); + + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; + } + + return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, + &cmd->body.mobid, + cmd->body.offsetInBytes); +} + +static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv, + struct vmw_sw_context *sw_context, + SVGA3dCmdHeader *header) +{ + struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node; + struct vmw_resource *res; + struct vmw_ctx_bindinfo_so binding; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXSetStreamOutput body; + } *cmd = container_of(header, typeof(*cmd), header); + int ret; + + if (!ctx_node) { + DRM_ERROR("DX Context not set.\n"); + return -EINVAL; + } + + if (cmd->body.soid == SVGA3D_INVALID_ID) + return 0; + + /* + * When device does not support SM5 then streamoutput with mob command is + * not available to user-space. Simply return in this case. + */ + if (!has_sm5_context(dev_priv)) + return 0; + + /* + * With SM5 capable device if lookup fails then user-space probably used + * old streamoutput define command. Return without an error. + */ + res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx), + cmd->body.soid); + if (IS_ERR(res)) { + return 0; + } + + ret = vmw_execbuf_res_noctx_val_add(sw_context, res, + VMW_RES_DIRTY_NONE); + if (ret) { + DRM_ERROR("Error creating resource validation node.\n"); + return ret; + } + + binding.bi.ctx = ctx_node->ctx; + binding.bi.res = res; + binding.bi.bt = vmw_ctx_binding_so; + binding.slot = 0; /* Only one SO set to context at a time. */ + + vmw_binding_add(sw_context->dx_ctx_node->staged, &binding.bi, 0, + binding.slot); + + return ret; +} + static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv, struct vmw_sw_context *sw_context, SVGA3dCmdHeader *header) @@ -3330,9 +3493,9 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = { VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT, &vmw_cmd_dx_so_define, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT, - &vmw_cmd_dx_cid_check, true, false, true), - VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, &vmw_cmd_dx_cid_check, - true, false, true), + &vmw_cmd_dx_destroy_streamoutput, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, + &vmw_cmd_dx_set_streamoutput, true, false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SOTARGETS, &vmw_cmd_dx_set_so_targets, true, false, true), 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] = { false, true), VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2, &vmw_cmd_sm5_view_define, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB, + &vmw_cmd_dx_define_streamoutput, true, false, true), + VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_STREAMOUTPUT, + &vmw_cmd_dx_bind_streamoutput, true, false, true), }; bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h index 22b4f5720908..f48b84bfeeac 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_so.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_so.h @@ -129,6 +129,7 @@ static inline enum vmw_so_type vmw_so_cmd_to_type(u32 id) case SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE: return vmw_so_ss; case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT: + case SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB: case SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT: return vmw_so_so; default: diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c new file mode 100644 index 000000000000..193192456663 --- /dev/null +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/************************************************************************** + * + * Copyright © 2018-2019 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "vmwgfx_drv.h" +#include "vmwgfx_resource_priv.h" +#include "vmwgfx_binding.h" + +/** + * struct vmw_dx_streamoutput - Streamoutput resource metadata. + * @res: Base resource struct. + * @ctx: Non-refcounted context to which @res belong. + * @cotable: Refcounted cotable holding this Streamoutput. + * @cotable_head: List head for cotable-so_res list. + * @id: User-space provided identifier. + * @size: User-space provided mob size. + * @committed: Whether streamoutput is actually created or pending creation. + */ +struct vmw_dx_streamoutput { + struct vmw_resource res; + struct vmw_resource *ctx; + struct vmw_resource *cotable; + struct list_head cotable_head; + u32 id; + u32 size; + bool committed; +}; + +static int vmw_dx_streamoutput_create(struct vmw_resource *res); +static int vmw_dx_streamoutput_bind(struct vmw_resource *res, + struct ttm_validate_buffer *val_buf); +static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback, + struct ttm_validate_buffer *val_buf); +static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res, + enum vmw_cmdbuf_res_state state); + +static size_t vmw_streamoutput_size; + +static const struct vmw_res_func vmw_dx_streamoutput_func = { + .res_type = vmw_res_streamoutput, + .needs_backup = true, + .may_evict = false, + .type_name = "DX streamoutput", + .backup_placement = &vmw_mob_placement, + .create = vmw_dx_streamoutput_create, + .destroy = NULL, /* Command buffer managed resource. */ + .bind = vmw_dx_streamoutput_bind, + .unbind = vmw_dx_streamoutput_unbind, + .commit_notify = vmw_dx_streamoutput_commit_notify, +}; + +static inline struct vmw_dx_streamoutput * +vmw_res_to_dx_streamoutput(struct vmw_resource *res) +{ + return container_of(res, struct vmw_dx_streamoutput, res); +} + +/** + * vmw_dx_streamoutput_unscrub - Reattach the MOB to streamoutput. + * @res: The streamoutput resource. + * + * Return: 0 on success, negative error code on failure. + */ +static int vmw_dx_streamoutput_unscrub(struct vmw_resource *res) +{ + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + struct vmw_private *dev_priv = res->dev_priv; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd; + + if (!list_empty(&so->cotable_head) || !so->committed ) + return 0; + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), so->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = so->id; + cmd->body.mobid = res->backup->base.mem.start; + cmd->body.offsetInBytes = res->backup_offset; + cmd->body.sizeInBytes = so->size; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + vmw_cotable_add_resource(so->cotable, &so->cotable_head); + + return 0; +} + +static int vmw_dx_streamoutput_create(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + int ret = 0; + + WARN_ON_ONCE(!so->committed); + + if (vmw_resource_mob_attached(res)) { + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_unscrub(res); + mutex_unlock(&dev_priv->binding_mutex); + } + + res->id = so->id; + + return ret; +} + +static int vmw_dx_streamoutput_bind(struct vmw_resource *res, + struct ttm_validate_buffer *val_buf) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct ttm_buffer_object *bo = val_buf->bo; + int ret; + + if (WARN_ON(bo->mem.mem_type != VMW_PL_MOB)) + return -EINVAL; + + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_unscrub(res); + mutex_unlock(&dev_priv->binding_mutex); + + return ret; +} + +/** + * vmw_dx_streamoutput_scrub - Unbind the MOB from streamoutput. + * @res: The streamoutput resource. + * + * Return: 0 on success, negative error code on failure. + */ +static int vmw_dx_streamoutput_scrub(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDXBindStreamOutput body; + } *cmd; + + if (list_empty(&so->cotable_head)) + return 0; + + WARN_ON_ONCE(!so->committed); + + cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), so->ctx->id); + if (!cmd) + return -ENOMEM; + + cmd->header.id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT; + cmd->header.size = sizeof(cmd->body); + cmd->body.soid = res->id; + cmd->body.mobid = SVGA3D_INVALID_ID; + cmd->body.offsetInBytes = 0; + cmd->body.sizeInBytes = so->size; + vmw_fifo_commit(dev_priv, sizeof(*cmd)); + + res->id = -1; + list_del_init(&so->cotable_head); + + return 0; +} + +static int vmw_dx_streamoutput_unbind(struct vmw_resource *res, bool readback, + struct ttm_validate_buffer *val_buf) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_fence_obj *fence; + int ret; + + if (WARN_ON(res->backup->base.mem.mem_type != VMW_PL_MOB)) + return -EINVAL; + + mutex_lock(&dev_priv->binding_mutex); + ret = vmw_dx_streamoutput_scrub(res); + mutex_unlock(&dev_priv->binding_mutex); + + if (ret) + return ret; + + (void) vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL); + vmw_bo_fence_single(val_buf->bo, fence); + + if (fence != NULL) + vmw_fence_obj_unreference(&fence); + + return 0; +} + +static void vmw_dx_streamoutput_commit_notify(struct vmw_resource *res, + enum vmw_cmdbuf_res_state state) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + if (state == VMW_CMDBUF_RES_ADD) { + mutex_lock(&dev_priv->binding_mutex); + vmw_cotable_add_resource(so->cotable, &so->cotable_head); + so->committed = true; + res->id = so->id; + mutex_unlock(&dev_priv->binding_mutex); + } else { + mutex_lock(&dev_priv->binding_mutex); + list_del_init(&so->cotable_head); + so->committed = false; + res->id = -1; + mutex_unlock(&dev_priv->binding_mutex); + } +} + +/** + * vmw_dx_streamoutput_lookup - Do a streamoutput resource lookup by user key. + * @man: Command buffer managed resource manager for current context. + * @user_key: User-space identifier for lookup. + * + * Return: Valid refcounted vmw_resource on success, error pointer on failure. + */ +struct vmw_resource * +vmw_dx_streamoutput_lookup(struct vmw_cmdbuf_res_manager *man, + u32 user_key) +{ + return vmw_cmdbuf_res_lookup(man, vmw_cmdbuf_res_streamoutput, + user_key); +} + +static void vmw_dx_streamoutput_res_free(struct vmw_resource *res) +{ + struct vmw_private *dev_priv = res->dev_priv; + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + vmw_resource_unreference(&so->cotable); + kfree(so); + ttm_mem_global_free(vmw_mem_glob(dev_priv), vmw_streamoutput_size); +} + +static void vmw_dx_streamoutput_hw_destroy(struct vmw_resource *res) +{ + /* Destroyed by user-space cmd buf or as part of context takedown. */ + res->id = -1; +} + +/** + * vmw_dx_streamoutput_add - Add a streamoutput as a cmd buf managed resource. + * @man: Command buffer managed resource manager for current context. + * @ctx: Pointer to context resource. + * @user_key: The identifier for this streamoutput. + * @list: The list of staged command buffer managed resources. + * + * Return: 0 on success, negative error code on failure. + */ +int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man, + struct vmw_resource *ctx, u32 user_key, + struct list_head *list) +{ + struct vmw_dx_streamoutput *so; + struct vmw_resource *res; + struct vmw_private *dev_priv = ctx->dev_priv; + struct ttm_operation_ctx ttm_opt_ctx = { + .interruptible = true, + .no_wait_gpu = false + }; + int ret; + + if (!vmw_streamoutput_size) + vmw_streamoutput_size = ttm_round_pot(sizeof(*so)); + + ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), + vmw_streamoutput_size, &ttm_opt_ctx); + if (ret) { + if (ret != -ERESTARTSYS) + DRM_ERROR("Out of graphics memory for streamout.\n"); + return ret; + } + + so = kmalloc(sizeof(*so), GFP_KERNEL); + if (!so) { + ttm_mem_global_free(vmw_mem_glob(dev_priv), + vmw_streamoutput_size); + return -ENOMEM; + } + + res = &so->res; + so->ctx = ctx; + so->cotable = vmw_resource_reference + (vmw_context_cotable(ctx, SVGA_COTABLE_STREAMOUTPUT)); + so->id = user_key; + so->committed = false; + INIT_LIST_HEAD(&so->cotable_head); + ret = vmw_resource_init(dev_priv, res, true, + vmw_dx_streamoutput_res_free, + &vmw_dx_streamoutput_func); + if (ret) + goto out_resource_init; + + ret = vmw_cmdbuf_res_add(man, vmw_cmdbuf_res_streamoutput, user_key, + res, list); + if (ret) + goto out_resource_init; + + res->id = so->id; + res->hw_destroy = vmw_dx_streamoutput_hw_destroy; + +out_resource_init: + vmw_resource_unreference(&res); + + return ret; +} + +/** + * vmw_dx_streamoutput_set_size - Sets streamoutput mob size in res struct. + * @res: The streamoutput res for which need to set size. + * @size: The size provided by user-space to set. + */ +void vmw_dx_streamoutput_set_size(struct vmw_resource *res, u32 size) +{ + struct vmw_dx_streamoutput *so = vmw_res_to_dx_streamoutput(res); + + so->size = size; +} + +/** + * vmw_dx_streamoutput_remove - Stage streamoutput for removal. + * @man: Command buffer managed resource manager for current context. + * @user_key: The identifier for this streamoutput. + * @list: The list of staged command buffer managed resources. + * + * Return: 0 on success, negative error code on failure. + */ +int vmw_dx_streamoutput_remove(struct vmw_cmdbuf_res_manager *man, + u32 user_key, + struct list_head *list) +{ + struct vmw_resource *r; + + return vmw_cmdbuf_res_remove(man, vmw_cmdbuf_res_streamoutput, + (u32)user_key, list, &r); +} + +/** + * vmw_dx_streamoutput_cotable_list_scrub - cotable unbind_func callback. + * @dev_priv: Device private. + * @list: The list of cotable resources. + * @readback: Whether the call was part of a readback unbind. + */ +void vmw_dx_streamoutput_cotable_list_scrub(struct vmw_private *dev_priv, + struct list_head *list, + bool readback) +{ + struct vmw_dx_streamoutput *entry, *next; + + lockdep_assert_held_once(&dev_priv->binding_mutex); + + list_for_each_entry_safe(entry, next, list, cotable_head) { + WARN_ON(vmw_dx_streamoutput_scrub(&entry->res)); + if (!readback) + entry->committed =false; + } +} -- cgit 1.4.1 From 26b82873a4a41cd699001ea634e2fc789789e5bd Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 29 Apr 2019 11:42:45 -0700 Subject: drm/vmwgfx: Split surface metadata from struct vmw_surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a new structure vmw_surface_metadata representing the metadata used for creating surface. With this can make the surface_define_priv a bit cleaner. Signed-off-by: Deepak Rawat Reviewed-by: Brian Paul Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 56 ++++++-- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 16 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 44 +++--- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 240 +++++++++++++++++--------------- 4 files changed, 202 insertions(+), 154 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index cfd8eaf7973e..c87bb854267b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -225,24 +225,56 @@ struct vmw_cursor_snooper { struct vmw_framebuffer; struct vmw_surface_offset; -struct vmw_surface { - struct vmw_resource res; - SVGA3dSurfaceAllFlags flags; - uint32_t format; - uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES]; +/** + * struct vmw_surface_metadata - Metadata describing a surface. + * + * @flags: Device flags. + * @format: Surface SVGA3D_x format. + * @mip_levels: Mip level for each face. For GB first index is used only. + * @multisample_count: Sample count. + * @multisample_pattern: Sample patterns. + * @quality_level: Quality level. + * @autogen_filter: Filter for automatically generated mipmaps. + * @array_size: Number of array elements for a 1D/2D texture. For cubemap + texture number of faces * array_size. This should be 0 for pre + SM4 device. + * @num_sizes: Size of @sizes. For GB surface this should always be 1. + * @base_size: Surface dimension. + * @sizes: Array representing mip sizes. Legacy only. + * @scanout: Whether this surface will be used for scanout. + * + * This tracks metadata for both legacy and guest backed surface. + */ +struct vmw_surface_metadata { + u64 flags; + u32 format; + u32 mip_levels[DRM_VMW_MAX_SURFACE_FACES]; + u32 multisample_count; + u32 multisample_pattern; + u32 quality_level; + u32 autogen_filter; + u32 array_size; + u32 num_sizes; struct drm_vmw_size base_size; struct drm_vmw_size *sizes; - uint32_t num_sizes; bool scanout; - uint32_t array_size; - /* TODO so far just a extra pointer */ +}; + +/** + * struct vmw_surface: Resource structure for a surface. + * + * @res: The base resource for this surface. + * @metadata: Metadata for this surface resource. + * @snooper: Cursor data. Legacy surface only. + * @offsets: Legacy surface only. + * @view_list: List of views bound to this surface. + */ +struct vmw_surface { + struct vmw_resource res; + struct vmw_surface_metadata metadata; struct vmw_cursor_snooper snooper; struct vmw_surface_offset *offsets; - SVGA3dTextureFilter autogen_filter; - uint32_t multisample_count; struct list_head view_list; - SVGA3dMSPattern multisample_pattern; - SVGA3dMSQualityLevel quality_level; }; struct vmw_marker_queue { diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 04b79e8975ce..4d2aaca15fd2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -905,14 +905,14 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, */ /* Surface must be marked as a scanout. */ - if (unlikely(!surface->scanout)) + if (unlikely(!surface->metadata.scanout)) return -EINVAL; - if (unlikely(surface->mip_levels[0] != 1 || - surface->num_sizes != 1 || - surface->base_size.width < mode_cmd->width || - surface->base_size.height < mode_cmd->height || - surface->base_size.depth != 1)) { + if (unlikely(surface->metadata.mip_levels[0] != 1 || + surface->metadata.num_sizes != 1 || + surface->metadata.base_size.width < mode_cmd->width || + surface->metadata.base_size.height < mode_cmd->height || + surface->metadata.base_size.depth != 1)) { DRM_ERROR("Incompatible surface dimensions " "for requested mode.\n"); return -EINVAL; @@ -941,7 +941,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, * For DX, surface format validation is done when surface->scanout * is set. */ - if (!has_sm4_context(dev_priv) && format != surface->format) { + if (!has_sm4_context(dev_priv) && format != surface->metadata.format) { DRM_ERROR("Invalid surface format for requested mode.\n"); return -EINVAL; } @@ -2516,7 +2516,7 @@ int vmw_kms_update_proxy(struct vmw_resource *res, int increment) { struct vmw_private *dev_priv = res->dev_priv; - struct drm_vmw_size *size = &vmw_res_to_srf(res)->base_size; + struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size; struct { SVGA3dCmdHeader header; SVGA3dCmdUpdateGBImage body; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 68aecb6d9f87..60275fe0db94 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -590,7 +590,7 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty) return; /* Assume we are blitting from Guest (bo) to Host (display_srf) */ - dst_pitch = stdu->display_srf->base_size.width * stdu->cpp; + dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; dst_bo = &stdu->display_srf->res.backup->base; dst_offset = ddirty->top * dst_pitch + ddirty->left * stdu->cpp; @@ -1058,8 +1058,9 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, vfb = vmw_framebuffer_to_vfb(new_fb); new_vfbs = (vfb->bo) ? NULL : vmw_framebuffer_to_vfbs(new_fb); - if (new_vfbs && new_vfbs->surface->base_size.width == hdisplay && - new_vfbs->surface->base_size.height == vdisplay) + if (new_vfbs && + new_vfbs->surface->metadata.base_size.width == hdisplay && + new_vfbs->surface->metadata.base_size.height == vdisplay) new_content_type = SAME_AS_DISPLAY; else if (vfb->bo) new_content_type = SEPARATE_BO; @@ -1082,15 +1083,15 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, switch (new_fb->format->cpp[0]*8) { case 32: - content_srf.format = SVGA3D_X8R8G8B8; + content_srf.metadata.format = SVGA3D_X8R8G8B8; break; case 16: - content_srf.format = SVGA3D_R5G6B5; + content_srf.metadata.format = SVGA3D_R5G6B5; break; case 8: - content_srf.format = SVGA3D_P8; + content_srf.metadata.format = SVGA3D_P8; break; default: @@ -1098,22 +1099,25 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, return -EINVAL; } - content_srf.flags = 0; - content_srf.mip_levels[0] = 1; - content_srf.multisample_count = 0; - content_srf.multisample_pattern = + content_srf.metadata.flags = 0; + content_srf.metadata.mip_levels[0] = 1; + content_srf.metadata.multisample_count = 0; + content_srf.metadata.multisample_pattern = SVGA3D_MS_PATTERN_NONE; - content_srf.quality_level = SVGA3D_MS_QUALITY_NONE; + content_srf.metadata.quality_level = + SVGA3D_MS_QUALITY_NONE; } else { content_srf = *new_vfbs->surface; } if (vps->surf) { - struct drm_vmw_size cur_base_size = vps->surf->base_size; + struct drm_vmw_size cur_base_size = + vps->surf->metadata.base_size; if (cur_base_size.width != display_base_size.width || cur_base_size.height != display_base_size.height || - vps->surf->format != content_srf.format) { + vps->surf->metadata.format != + content_srf.metadata.format) { WARN_ON(vps->pinned != 0); vmw_surface_unreference(&vps->surf); } @@ -1125,15 +1129,15 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, (crtc->dev, /* Kernel visible only */ 0, - content_srf.flags, - content_srf.format, + content_srf.metadata.flags, + content_srf.metadata.format, true, /* a scanout buffer */ - content_srf.mip_levels[0], - content_srf.multisample_count, + content_srf.metadata.mip_levels[0], + content_srf.metadata.multisample_count, 0, display_base_size, - content_srf.multisample_pattern, - content_srf.quality_level, + content_srf.metadata.multisample_pattern, + content_srf.metadata.quality_level, &vps->surf); if (ret != 0) { DRM_ERROR("Couldn't allocate STDU surface.\n"); @@ -1311,7 +1315,7 @@ vmw_stdu_bo_populate_update_cpu(struct vmw_du_update_plane *update, void *cmd, diff.cpp = stdu->cpp; dst_bo = &stdu->display_srf->res.backup->base; - dst_pitch = stdu->display_srf->base_size.width * stdu->cpp; + dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp; dst_offset = bb->y1 * dst_pitch + bb->x1 * stdu->cpp; src_bo = &vfbbo->buffer->base; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 4bad6e2a700d..d9b677a0491a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -199,7 +199,7 @@ struct vmw_surface_destroy { */ static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf) { - return srf->num_sizes * sizeof(struct vmw_surface_dma); + return srf->metadata.num_sizes * sizeof(struct vmw_surface_dma); } @@ -213,7 +213,7 @@ static inline uint32_t vmw_surface_dma_size(const struct vmw_surface *srf) */ static inline uint32_t vmw_surface_define_size(const struct vmw_surface *srf) { - return sizeof(struct vmw_surface_define) + srf->num_sizes * + return sizeof(struct vmw_surface_define) + srf->metadata.num_sizes * sizeof(SVGA3dSize); } @@ -262,7 +262,8 @@ static void vmw_surface_define_encode(const struct vmw_surface *srf, uint32_t cmd_len; int i; - cmd_len = sizeof(cmd->body) + srf->num_sizes * sizeof(SVGA3dSize); + cmd_len = sizeof(cmd->body) + srf->metadata.num_sizes * + sizeof(SVGA3dSize); cmd->header.id = SVGA_3D_CMD_SURFACE_DEFINE; cmd->header.size = cmd_len; @@ -272,16 +273,16 @@ static void vmw_surface_define_encode(const struct vmw_surface *srf, * since driver internally stores as 64 bit. * For legacy surface define only 32 bit flag is supported. */ - cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->flags; - cmd->body.format = srf->format; + cmd->body.surfaceFlags = (SVGA3dSurface1Flags)srf->metadata.flags; + cmd->body.format = srf->metadata.format; for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) - cmd->body.face[i].numMipLevels = srf->mip_levels[i]; + cmd->body.face[i].numMipLevels = srf->metadata.mip_levels[i]; cmd += 1; cmd_size = (SVGA3dSize *) cmd; - src_size = srf->sizes; + src_size = srf->metadata.sizes; - for (i = 0; i < srf->num_sizes; ++i, cmd_size++, src_size++) { + for (i = 0; i < srf->metadata.num_sizes; ++i, cmd_size++, src_size++) { cmd_size->width = src_size->width; cmd_size->height = src_size->height; cmd_size->depth = src_size->depth; @@ -305,15 +306,15 @@ static void vmw_surface_dma_encode(struct vmw_surface *srf, uint32_t i; struct vmw_surface_dma *cmd = (struct vmw_surface_dma *)cmd_space; const struct svga3d_surface_desc *desc = - svga3dsurface_get_desc(srf->format); + svga3dsurface_get_desc(srf->metadata.format); - for (i = 0; i < srf->num_sizes; ++i) { + for (i = 0; i < srf->metadata.num_sizes; ++i) { SVGA3dCmdHeader *header = &cmd->header; SVGA3dCmdSurfaceDMA *body = &cmd->body; SVGA3dCopyBox *cb = &cmd->cb; SVGA3dCmdSurfaceDMASuffix *suffix = &cmd->suffix; const struct vmw_surface_offset *cur_offset = &srf->offsets[i]; - const struct drm_vmw_size *cur_size = &srf->sizes[i]; + const struct drm_vmw_size *cur_size = &srf->metadata.sizes[i]; header->id = SVGA_3D_CMD_SURFACE_DMA; header->size = sizeof(*body) + sizeof(*cb) + sizeof(*suffix); @@ -669,7 +670,7 @@ static void vmw_user_surface_free(struct vmw_resource *res) if (user_srf->master) drm_master_put(&user_srf->master); kfree(srf->offsets); - kfree(srf->sizes); + kfree(srf->metadata.sizes); kfree(srf->snooper.image); ttm_prime_object_kfree(user_srf, prime); ttm_mem_global_free(vmw_mem_glob(dev_priv), size); @@ -728,6 +729,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_user_surface *user_srf; struct vmw_surface *srf; + struct vmw_surface_metadata *metadata; struct vmw_resource *res; struct vmw_resource *tmp; union drm_vmw_surface_create_arg *arg = @@ -793,43 +795,45 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } srf = &user_srf->srf; + metadata = &srf->metadata; res = &srf->res; /* Driver internally stores as 64-bit flags */ - srf->flags = (SVGA3dSurfaceAllFlags)req->flags; - srf->format = req->format; - srf->scanout = req->scanout; + metadata->flags = (SVGA3dSurfaceAllFlags)req->flags; + metadata->format = req->format; + metadata->scanout = req->scanout; - memcpy(srf->mip_levels, req->mip_levels, sizeof(srf->mip_levels)); - srf->num_sizes = num_sizes; + memcpy(metadata->mip_levels, req->mip_levels, + sizeof(metadata->mip_levels)); + metadata->num_sizes = num_sizes; user_srf->size = size; - srf->sizes = memdup_user((struct drm_vmw_size __user *)(unsigned long) - req->size_addr, - sizeof(*srf->sizes) * srf->num_sizes); - if (IS_ERR(srf->sizes)) { - ret = PTR_ERR(srf->sizes); + metadata->sizes = + memdup_user((struct drm_vmw_size __user *)(unsigned long) + req->size_addr, + sizeof(*metadata->sizes) * metadata->num_sizes); + if (IS_ERR(metadata->sizes)) { + ret = PTR_ERR(metadata->sizes); goto out_no_sizes; } - srf->offsets = kmalloc_array(srf->num_sizes, - sizeof(*srf->offsets), + srf->offsets = kmalloc_array(metadata->num_sizes, sizeof(*srf->offsets), GFP_KERNEL); if (unlikely(!srf->offsets)) { ret = -ENOMEM; goto out_no_offsets; } - srf->base_size = *srf->sizes; - srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; - srf->multisample_count = 0; - srf->multisample_pattern = SVGA3D_MS_PATTERN_NONE; - srf->quality_level = SVGA3D_MS_QUALITY_NONE; + metadata->base_size = *srf->metadata.sizes; + metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE; + metadata->multisample_count = 0; + metadata->multisample_pattern = SVGA3D_MS_PATTERN_NONE; + metadata->quality_level = SVGA3D_MS_QUALITY_NONE; cur_bo_offset = 0; cur_offset = srf->offsets; - cur_size = srf->sizes; + cur_size = metadata->sizes; for (i = 0; i < DRM_VMW_MAX_SURFACE_FACES; ++i) { - for (j = 0; j < srf->mip_levels[i]; ++j) { + for (j = 0; j < metadata->mip_levels[i]; ++j) { uint32_t stride = svga3dsurface_calculate_pitch (desc, cur_size); @@ -843,11 +847,11 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, } } res->backup_size = cur_bo_offset; - if (srf->scanout && - srf->num_sizes == 1 && - srf->sizes[0].width == 64 && - srf->sizes[0].height == 64 && - srf->format == SVGA3D_A8R8G8B8) { + if (metadata->scanout && + metadata->num_sizes == 1 && + metadata->sizes[0].width == 64 && + metadata->sizes[0].height == 64 && + metadata->format == SVGA3D_A8R8G8B8) { srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL); if (!srf->snooper.image) { @@ -911,7 +915,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, out_no_copy: kfree(srf->offsets); out_no_offsets: - kfree(srf->sizes); + kfree(metadata->sizes); out_no_sizes: ttm_prime_object_kfree(user_srf, prime); out_no_user_srf: @@ -1031,18 +1035,19 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data, srf = &user_srf->srf; /* Downcast of flags when sending back to user space */ - rep->flags = (uint32_t)srf->flags; - rep->format = srf->format; - memcpy(rep->mip_levels, srf->mip_levels, sizeof(srf->mip_levels)); + rep->flags = (uint32_t)srf->metadata.flags; + rep->format = srf->metadata.format; + memcpy(rep->mip_levels, srf->metadata.mip_levels, + sizeof(srf->metadata.mip_levels)); user_sizes = (struct drm_vmw_size __user *)(unsigned long) rep->size_addr; if (user_sizes) - ret = copy_to_user(user_sizes, &srf->base_size, - sizeof(srf->base_size)); + ret = copy_to_user(user_sizes, &srf->metadata.base_size, + sizeof(srf->metadata.base_size)); if (unlikely(ret != 0)) { VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes, - srf->num_sizes); + srf->metadata.num_sizes); ttm_ref_object_base_unref(tfile, base->handle, TTM_REF_USAGE); ret = -EFAULT; } @@ -1062,6 +1067,7 @@ static int vmw_gb_surface_create(struct vmw_resource *res) { struct vmw_private *dev_priv = res->dev_priv; struct vmw_surface *srf = vmw_res_to_srf(res); + struct vmw_surface_metadata *metadata = &srf->metadata; uint32_t cmd_len, cmd_id, submit_len; int ret; struct { @@ -1092,11 +1098,11 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); - } else if (srf->array_size > 0) { + } else if (metadata->array_size > 0) { /* VMW_SM_4 support verified at creation time. */ cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2; cmd_len = sizeof(cmd2->body); @@ -1115,46 +1121,46 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; - cmd3->body.surfaceFlags = srf->flags; - cmd3->body.format = srf->format; - cmd3->body.numMipLevels = srf->mip_levels[0]; - cmd3->body.multisampleCount = srf->multisample_count; - cmd3->body.multisamplePattern = srf->multisample_pattern; - cmd3->body.qualityLevel = srf->quality_level; - cmd3->body.autogenFilter = srf->autogen_filter; - cmd3->body.size.width = srf->base_size.width; - cmd3->body.size.height = srf->base_size.height; - cmd3->body.size.depth = srf->base_size.depth; - cmd3->body.arraySize = srf->array_size; - } else if (srf->array_size > 0) { + cmd3->body.surfaceFlags = metadata->flags; + cmd3->body.format = metadata->format; + cmd3->body.numMipLevels = metadata->mip_levels[0]; + cmd3->body.multisampleCount = metadata->multisample_count; + cmd3->body.multisamplePattern = metadata->multisample_pattern; + cmd3->body.qualityLevel = metadata->quality_level; + cmd3->body.autogenFilter = metadata->autogen_filter; + cmd3->body.size.width = metadata->base_size.width; + cmd3->body.size.height = metadata->base_size.height; + cmd3->body.size.depth = metadata->base_size.depth; + cmd3->body.arraySize = metadata->array_size; + } else if (metadata->array_size > 0) { cmd2->header.id = cmd_id; cmd2->header.size = cmd_len; cmd2->body.sid = srf->res.id; - cmd2->body.surfaceFlags = srf->flags; - cmd2->body.format = srf->format; - cmd2->body.numMipLevels = srf->mip_levels[0]; - cmd2->body.multisampleCount = srf->multisample_count; - cmd2->body.autogenFilter = srf->autogen_filter; - cmd2->body.size.width = srf->base_size.width; - cmd2->body.size.height = srf->base_size.height; - cmd2->body.size.depth = srf->base_size.depth; - cmd2->body.arraySize = srf->array_size; + cmd2->body.surfaceFlags = metadata->flags; + cmd2->body.format = metadata->format; + cmd2->body.numMipLevels = metadata->mip_levels[0]; + cmd2->body.multisampleCount = metadata->multisample_count; + cmd2->body.autogenFilter = metadata->autogen_filter; + cmd2->body.size.width = metadata->base_size.width; + cmd2->body.size.height = metadata->base_size.height; + cmd2->body.size.depth = metadata->base_size.depth; + cmd2->body.arraySize = metadata->array_size; } else { cmd->header.id = cmd_id; cmd->header.size = cmd_len; cmd->body.sid = srf->res.id; - cmd->body.surfaceFlags = srf->flags; - cmd->body.format = srf->format; - cmd->body.numMipLevels = srf->mip_levels[0]; - cmd->body.multisampleCount = srf->multisample_count; - cmd->body.autogenFilter = srf->autogen_filter; - cmd->body.size.width = srf->base_size.width; - cmd->body.size.height = srf->base_size.height; - cmd->body.size.depth = srf->base_size.depth; + cmd->body.surfaceFlags = metadata->flags; + cmd->body.format = metadata->format; + cmd->body.numMipLevels = metadata->mip_levels[0]; + cmd->body.multisampleCount = metadata->multisample_count; + cmd->body.autogenFilter = metadata->autogen_filter; + cmd->body.size.width = metadata->base_size.width; + cmd->body.size.height = metadata->base_size.height; + cmd->body.size.depth = metadata->base_size.depth; } vmw_fifo_commit(dev_priv, submit_len); @@ -1412,6 +1418,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, .no_wait_gpu = false }; struct vmw_surface *srf; + struct vmw_surface_metadata *metadata; int ret; u32 num_layers = 1; u32 sample_count = 1; @@ -1473,36 +1480,37 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, user_srf->prime.base.tfile = NULL; srf = &user_srf->srf; - srf->flags = svga3d_flags; - srf->format = format; - srf->scanout = for_scanout; - srf->mip_levels[0] = num_mip_levels; - srf->num_sizes = 1; - srf->sizes = NULL; - srf->offsets = NULL; - srf->base_size = size; - srf->autogen_filter = SVGA3D_TEX_FILTER_NONE; - srf->array_size = array_size; - srf->multisample_count = multisample_count; - srf->multisample_pattern = multisample_pattern; - srf->quality_level = quality_level; + metadata = &srf->metadata; + metadata->flags = svga3d_flags; + metadata->format = format; + metadata->scanout = for_scanout; + metadata->mip_levels[0] = num_mip_levels; + metadata->num_sizes = 1; + metadata->sizes = NULL; + srf->offsets = NULL; + metadata->base_size = size; + metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE; + metadata->array_size = array_size; + metadata->multisample_count = multisample_count; + metadata->multisample_pattern = multisample_pattern; + metadata->quality_level = quality_level; if (array_size) num_layers = array_size; else if (svga3d_flags & SVGA3D_SURFACE_CUBEMAP) num_layers = SVGA3D_MAX_SURFACE_FACES; - if (srf->flags & SVGA3D_SURFACE_MULTISAMPLE) - sample_count = srf->multisample_count; + if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE) + sample_count = metadata->multisample_count; - srf->res.backup_size = - svga3dsurface_get_serialized_size_extended(srf->format, - srf->base_size, - srf->mip_levels[0], + srf->res.backup_size = + svga3dsurface_get_serialized_size_extended(metadata->format, + metadata->base_size, + metadata->mip_levels[0], num_layers, sample_count); - if (srf->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) + if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) srf->res.backup_size += sizeof(SVGA3dDXSOState); /* @@ -1516,7 +1524,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev, if (dev_priv->active_display_unit == vmw_du_screen_target && for_scanout && size.width <= dev_priv->stdu_max_width && size.height <= dev_priv->stdu_max_height) - srf->flags |= SVGA3D_SURFACE_SCREENTARGET; + metadata->flags |= SVGA3D_SURFACE_SCREENTARGET; /* * From this point, the generic resource management functions @@ -1762,6 +1770,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_surface *srf; struct vmw_user_surface *user_srf; + struct vmw_surface_metadata *metadata; struct ttm_base_object *base; uint32_t backup_handle; int ret = -EINVAL; @@ -1777,6 +1786,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, DRM_ERROR("Shared GB surface is missing a backup buffer.\n"); goto out_bad_resource; } + metadata = &srf->metadata; mutex_lock(&dev_priv->cmdbuf_mutex); /* Protect res->backup */ ret = vmw_user_bo_reference(tfile, srf->res.backup, &backup_handle); @@ -1790,15 +1800,15 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, goto out_bad_resource; } - rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(srf->flags); - rep->creq.base.format = srf->format; - rep->creq.base.mip_levels = srf->mip_levels[0]; + rep->creq.base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(metadata->flags); + rep->creq.base.format = metadata->format; + rep->creq.base.mip_levels = metadata->mip_levels[0]; rep->creq.base.drm_surface_flags = 0; - rep->creq.base.multisample_count = srf->multisample_count; - rep->creq.base.autogen_filter = srf->autogen_filter; - rep->creq.base.array_size = srf->array_size; + rep->creq.base.multisample_count = metadata->multisample_count; + rep->creq.base.autogen_filter = metadata->autogen_filter; + rep->creq.base.array_size = metadata->array_size; rep->creq.base.buffer_handle = backup_handle; - rep->creq.base.base_size = srf->base_size; + rep->creq.base.base_size = metadata->base_size; rep->crep.handle = user_srf->prime.base.handle; rep->crep.backup_size = srf->res.backup_size; rep->crep.buffer_handle = backup_handle; @@ -1808,9 +1818,9 @@ vmw_gb_surface_reference_internal(struct drm_device *dev, rep->creq.version = drm_vmw_gb_surface_v1; rep->creq.svga3d_flags_upper_32_bits = - SVGA3D_FLAGS_UPPER_32(srf->flags); - rep->creq.multisample_pattern = srf->multisample_pattern; - rep->creq.quality_level = srf->quality_level; + SVGA3D_FLAGS_UPPER_32(metadata->flags); + rep->creq.multisample_pattern = metadata->multisample_pattern; + rep->creq.quality_level = metadata->quality_level; rep->creq.must_be_zero = 0; out_bad_resource: @@ -1968,7 +1978,7 @@ static void vmw_surface_dirty_range_add(struct vmw_resource *res, size_t start, start >= res->backup_offset + res->backup_size)) return; - if (srf->format == SVGA3D_BUFFER) + if (srf->metadata.format == SVGA3D_BUFFER) vmw_surface_buf_dirty_range_add(res, start, end); else vmw_surface_tex_dirty_range_add(res, start, end); @@ -2058,6 +2068,7 @@ static int vmw_surface_dirty_sync(struct vmw_resource *res) static int vmw_surface_dirty_alloc(struct vmw_resource *res) { struct vmw_surface *srf = vmw_res_to_srf(res); + const struct vmw_surface_metadata *metadata = &srf->metadata; struct vmw_surface_dirty *dirty; u32 num_layers = 1; u32 num_mip; @@ -2070,12 +2081,12 @@ static int vmw_surface_dirty_alloc(struct vmw_resource *res) }; int ret; - if (srf->array_size) - num_layers = srf->array_size; - else if (srf->flags & SVGA3D_SURFACE_CUBEMAP) + if (metadata->array_size) + num_layers = metadata->array_size; + else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP) num_layers *= SVGA3D_MAX_SURFACE_FACES; - num_mip = srf->mip_levels[0]; + num_mip = metadata->mip_levels[0]; if (!num_mip) num_mip = 1; @@ -2096,9 +2107,10 @@ static int vmw_surface_dirty_alloc(struct vmw_resource *res) goto out_no_dirty; } - num_samples = max_t(u32, 1, srf->multisample_count); - ret = svga3dsurface_setup_cache(&srf->base_size, srf->format, num_mip, - num_layers, num_samples, &dirty->cache); + num_samples = max_t(u32, 1, metadata->multisample_count); + ret = svga3dsurface_setup_cache(&metadata->base_size, metadata->format, + num_mip, num_layers, num_samples, + &dirty->cache); if (ret) goto out_no_cache; -- cgit 1.4.1 From 504901dbb0b565fcbe466b0c56f3131586df5afd Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Mon, 29 Apr 2019 14:55:44 -0700 Subject: drm/vmwgfx: Refactor surface_define to use vmw_surface_metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes surface_define cleaner by sending vmw_surface_metadata instead of all the arguments individually. v2: fix uninitialized return value, error message Signed-off-by: Deepak Rawat Reviewed-by: Brian Paul Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 27 +-- drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 51 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 378 ++++++++++++++++---------------- 4 files changed, 215 insertions(+), 246 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index c87bb854267b..326d1dd58bc5 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -1309,6 +1309,11 @@ extern int vmw_gb_surface_reference_ext_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int vmw_gb_surface_define(struct vmw_private *dev_priv, + uint32_t user_accounting_size, + const struct vmw_surface_metadata *req, + struct vmw_surface **srf_out); + /* * Shader management - vmwgfx_shader.c */ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 4d2aaca15fd2..04d66592f605 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -1144,8 +1144,8 @@ static int vmw_create_bo_proxy(struct drm_device *dev, struct vmw_buffer_object *bo_mob, struct vmw_surface **srf_out) { + struct vmw_surface_metadata metadata = {0}; uint32_t format; - struct drm_vmw_size content_base_size = {0}; struct vmw_resource *res; unsigned int bytes_pp; struct drm_format_name_buf format_name; @@ -1175,22 +1175,15 @@ static int vmw_create_bo_proxy(struct drm_device *dev, return -EINVAL; } - content_base_size.width = mode_cmd->pitches[0] / bytes_pp; - content_base_size.height = mode_cmd->height; - content_base_size.depth = 1; - - ret = vmw_surface_gb_priv_define(dev, - 0, /* kernel visible only */ - 0, /* flags */ - format, - true, /* can be a scanout buffer */ - 1, /* num of mip levels */ - 0, - 0, - content_base_size, - SVGA3D_MS_PATTERN_NONE, - SVGA3D_MS_QUALITY_NONE, - srf_out); + metadata.format = format; + metadata.mip_levels[0] = 1; + metadata.num_sizes = 1; + metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp; + metadata.base_size.height = mode_cmd->height; + metadata.base_size.depth = 1; + metadata.scanout = true; + + ret = vmw_gb_surface_define(vmw_priv(dev), 0, &metadata, srf_out); if (ret) { DRM_ERROR("Failed to allocate proxy content buffer\n"); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 60275fe0db94..9ffa9c75a5da 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -1041,7 +1041,6 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state); enum stdu_content_type new_content_type; struct vmw_framebuffer_surface *new_vfbs; - struct drm_crtc *crtc = new_state->crtc; uint32_t hdisplay = new_state->crtc_w, vdisplay = new_state->crtc_h; int ret; @@ -1068,12 +1067,11 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, new_content_type = SEPARATE_SURFACE; if (new_content_type != SAME_AS_DISPLAY) { - struct vmw_surface content_srf; - struct drm_vmw_size display_base_size = {0}; + struct vmw_surface_metadata metadata = {0}; - display_base_size.width = hdisplay; - display_base_size.height = vdisplay; - display_base_size.depth = 1; + metadata.base_size.width = hdisplay; + metadata.base_size.height = vdisplay; + metadata.base_size.depth = 1; /* * If content buffer is a buffer object, then we have to @@ -1083,15 +1081,15 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, switch (new_fb->format->cpp[0]*8) { case 32: - content_srf.metadata.format = SVGA3D_X8R8G8B8; + metadata.format = SVGA3D_X8R8G8B8; break; case 16: - content_srf.metadata.format = SVGA3D_R5G6B5; + metadata.format = SVGA3D_R5G6B5; break; case 8: - content_srf.metadata.format = SVGA3D_P8; + metadata.format = SVGA3D_P8; break; default: @@ -1099,25 +1097,20 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, return -EINVAL; } - content_srf.metadata.flags = 0; - content_srf.metadata.mip_levels[0] = 1; - content_srf.metadata.multisample_count = 0; - content_srf.metadata.multisample_pattern = - SVGA3D_MS_PATTERN_NONE; - content_srf.metadata.quality_level = - SVGA3D_MS_QUALITY_NONE; + metadata.mip_levels[0] = 1; + metadata.num_sizes = 1; + metadata.scanout = true; } else { - content_srf = *new_vfbs->surface; + metadata = new_vfbs->surface->metadata; } if (vps->surf) { struct drm_vmw_size cur_base_size = vps->surf->metadata.base_size; - if (cur_base_size.width != display_base_size.width || - cur_base_size.height != display_base_size.height || - vps->surf->metadata.format != - content_srf.metadata.format) { + if (cur_base_size.width != metadata.base_size.width || + cur_base_size.height != metadata.base_size.height || + vps->surf->metadata.format != metadata.format) { WARN_ON(vps->pinned != 0); vmw_surface_unreference(&vps->surf); } @@ -1125,20 +1118,8 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane, } if (!vps->surf) { - ret = vmw_surface_gb_priv_define - (crtc->dev, - /* Kernel visible only */ - 0, - content_srf.metadata.flags, - content_srf.metadata.format, - true, /* a scanout buffer */ - content_srf.metadata.mip_levels[0], - content_srf.metadata.multisample_count, - 0, - display_base_size, - content_srf.metadata.multisample_pattern, - content_srf.metadata.quality_level, - &vps->surf); + ret = vmw_gb_surface_define(dev_priv, 0, &metadata, + &vps->surf); if (ret != 0) { DRM_ERROR("Couldn't allocate STDU surface.\n"); return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index d9b677a0491a..6c907b147e97 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1320,7 +1320,6 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res) return 0; } - /** * vmw_gb_surface_define_ioctl - Ioctl function implementing * the user surface define functionality. @@ -1376,173 +1375,6 @@ int vmw_gb_surface_reference_ioctl(struct drm_device *dev, void *data, return ret; } -/** - * vmw_surface_gb_priv_define - Define a private GB surface - * - * @dev: Pointer to a struct drm_device - * @user_accounting_size: Used to track user-space memory usage, set - * to 0 for kernel mode only memory - * @svga3d_flags: SVGA3d surface flags for the device - * @format: requested surface format - * @for_scanout: true if inteded to be used for scanout buffer - * @num_mip_levels: number of MIP levels - * @multisample_count: - * @array_size: Surface array size. - * @size: width, heigh, depth of the surface requested - * @multisample_pattern: Multisampling pattern when msaa is supported - * @quality_level: Precision settings - * @user_srf_out: allocated user_srf. Set to NULL on failure. - * - * GB surfaces allocated by this function will not have a user mode handle, and - * thus will only be visible to vmwgfx. For optimization reasons the - * surface may later be given a user mode handle by another function to make - * it available to user mode drivers. - */ -int vmw_surface_gb_priv_define(struct drm_device *dev, - uint32_t user_accounting_size, - SVGA3dSurfaceAllFlags svga3d_flags, - SVGA3dSurfaceFormat format, - bool for_scanout, - uint32_t num_mip_levels, - uint32_t multisample_count, - uint32_t array_size, - struct drm_vmw_size size, - SVGA3dMSPattern multisample_pattern, - SVGA3dMSQualityLevel quality_level, - struct vmw_surface **srf_out) -{ - struct vmw_private *dev_priv = vmw_priv(dev); - struct vmw_user_surface *user_srf; - struct ttm_operation_ctx ctx = { - .interruptible = true, - .no_wait_gpu = false - }; - struct vmw_surface *srf; - struct vmw_surface_metadata *metadata; - int ret; - u32 num_layers = 1; - u32 sample_count = 1; - - *srf_out = NULL; - - if (for_scanout) { - if (!svga3dsurface_is_screen_target_format(format)) { - VMW_DEBUG_USER("Invalid Screen Target surface format."); - return -EINVAL; - } - - if (size.width > dev_priv->texture_max_width || - size.height > dev_priv->texture_max_height) { - VMW_DEBUG_USER("%ux%u\n, exceeds max surface size %ux%u", - size.width, size.height, - dev_priv->texture_max_width, - dev_priv->texture_max_height); - return -EINVAL; - } - } else { - const struct svga3d_surface_desc *desc; - - desc = svga3dsurface_get_desc(format); - if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) { - VMW_DEBUG_USER("Invalid surface format.\n"); - return -EINVAL; - } - } - - /* array_size must be null for non-GL3 host. */ - if (array_size > 0 && !has_sm4_context(dev_priv)) { - VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); - return -EINVAL; - } - - ret = ttm_read_lock(&dev_priv->reservation_sem, true); - if (unlikely(ret != 0)) - return ret; - - ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), - user_accounting_size, &ctx); - if (unlikely(ret != 0)) { - if (ret != -ERESTARTSYS) - DRM_ERROR("Out of graphics memory for surface" - " creation.\n"); - goto out_unlock; - } - - user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); - if (unlikely(!user_srf)) { - ret = -ENOMEM; - goto out_no_user_srf; - } - - *srf_out = &user_srf->srf; - user_srf->size = user_accounting_size; - user_srf->prime.base.shareable = false; - user_srf->prime.base.tfile = NULL; - - srf = &user_srf->srf; - metadata = &srf->metadata; - metadata->flags = svga3d_flags; - metadata->format = format; - metadata->scanout = for_scanout; - metadata->mip_levels[0] = num_mip_levels; - metadata->num_sizes = 1; - metadata->sizes = NULL; - srf->offsets = NULL; - metadata->base_size = size; - metadata->autogen_filter = SVGA3D_TEX_FILTER_NONE; - metadata->array_size = array_size; - metadata->multisample_count = multisample_count; - metadata->multisample_pattern = multisample_pattern; - metadata->quality_level = quality_level; - - if (array_size) - num_layers = array_size; - else if (svga3d_flags & SVGA3D_SURFACE_CUBEMAP) - num_layers = SVGA3D_MAX_SURFACE_FACES; - - if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE) - sample_count = metadata->multisample_count; - - srf->res.backup_size = - svga3dsurface_get_serialized_size_extended(metadata->format, - metadata->base_size, - metadata->mip_levels[0], - num_layers, - sample_count); - - if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) - srf->res.backup_size += sizeof(SVGA3dDXSOState); - - /* - * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with - * size greater than STDU max width/height. This is really a workaround - * to support creation of big framebuffer requested by some user-space - * for whole topology. That big framebuffer won't really be used for - * binding with screen target as during prepare_fb a separate surface is - * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag. - */ - if (dev_priv->active_display_unit == vmw_du_screen_target && - for_scanout && size.width <= dev_priv->stdu_max_width && - size.height <= dev_priv->stdu_max_height) - metadata->flags |= SVGA3D_SURFACE_SCREENTARGET; - - /* - * From this point, the generic resource management functions - * destroy the object on failure. - */ - ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); - - ttm_read_unlock(&dev_priv->reservation_sem); - return ret; - -out_no_user_srf: - ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size); - -out_unlock: - ttm_read_unlock(&dev_priv->reservation_sem); - return ret; -} - /** * vmw_gb_surface_define_ext_ioctl - Ioctl function implementing * the user surface define functionality. @@ -1596,43 +1428,55 @@ vmw_gb_surface_define_internal(struct drm_device *dev, struct drm_vmw_gb_surface_create_rep *rep, struct drm_file *file_priv) { + struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; struct vmw_private *dev_priv = vmw_priv(dev); struct vmw_user_surface *user_srf; + struct vmw_surface_metadata metadata = {0}; struct vmw_surface *srf; struct vmw_resource *res; struct vmw_resource *tmp; - struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; - int ret; + int ret = 0; uint32_t size; uint32_t backup_handle = 0; SVGA3dSurfaceAllFlags svga3d_flags_64 = SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits, req->base.svga3d_flags); + /* array_size must be null for non-GL3 host. */ + if (req->base.array_size > 0 && !has_sm4_context(dev_priv)) { + VMW_DEBUG_USER("SM4 surface not supported.\n"); + return -EINVAL; + } + if (!has_sm4_1_context(dev_priv)) { - /* - * If SM4_1 is not support then cannot send 64-bit flag to - * device. - */ if (req->svga3d_flags_upper_32_bits != 0) - return -EINVAL; + ret = -EINVAL; if (req->base.multisample_count != 0) - return -EINVAL; + ret = -EINVAL; if (req->multisample_pattern != SVGA3D_MS_PATTERN_NONE) - return -EINVAL; + ret = -EINVAL; if (req->quality_level != SVGA3D_MS_QUALITY_NONE) - return -EINVAL; + ret = -EINVAL; + + if (ret) { + VMW_DEBUG_USER("SM4.1 surface not supported.\n"); + return ret; + } } if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) && - req->base.multisample_count == 0) + req->base.multisample_count == 0) { + VMW_DEBUG_USER("Invalid sample count.\n"); return -EINVAL; + } - if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) + if (req->base.mip_levels > DRM_VMW_MAX_MIP_LEVELS) { + VMW_DEBUG_USER("Invalid mip level.\n"); return -EINVAL; + } if (unlikely(vmw_user_surface_size == 0)) vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) + @@ -1640,22 +1484,24 @@ vmw_gb_surface_define_internal(struct drm_device *dev, size = vmw_user_surface_size; + metadata.flags = svga3d_flags_64; + metadata.format = req->base.format; + metadata.mip_levels[0] = req->base.mip_levels; + metadata.multisample_count = req->base.multisample_count; + metadata.multisample_pattern = req->multisample_pattern; + metadata.quality_level = req->quality_level; + metadata.array_size = req->base.array_size; + metadata.num_sizes = 1; + metadata.base_size = req->base.base_size; + metadata.scanout = req->base.drm_surface_flags & + drm_vmw_surface_flag_scanout; + /* Define a surface based on the parameters. */ - ret = vmw_surface_gb_priv_define(dev, - size, - svga3d_flags_64, - req->base.format, - req->base.drm_surface_flags & - drm_vmw_surface_flag_scanout, - req->base.mip_levels, - req->base.multisample_count, - req->base.array_size, - req->base.base_size, - req->multisample_pattern, - req->quality_level, - &srf); - if (unlikely(ret != 0)) + ret = vmw_gb_surface_define(dev_priv, size, &metadata, &srf); + if (ret != 0) { + VMW_DEBUG_USER("Failed to define surface.\n"); return ret; + } user_srf = container_of(srf, struct vmw_user_surface, srf); if (drm_is_primary_client(file_priv)) @@ -2165,3 +2011,147 @@ static int vmw_surface_clean(struct vmw_resource *res) return 0; } + +/* + * vmw_gb_surface_define - Define a private GB surface + * + * @dev_priv: Pointer to a device private. + * @user_accounting_size: Used to track user-space memory usage, set + * to 0 for kernel mode only memory + * @metadata: Metadata representing the surface to create. + * @user_srf_out: allocated user_srf. Set to NULL on failure. + * + * GB surfaces allocated by this function will not have a user mode handle, and + * thus will only be visible to vmwgfx. For optimization reasons the + * surface may later be given a user mode handle by another function to make + * it available to user mode drivers. + */ +int vmw_gb_surface_define(struct vmw_private *dev_priv, + uint32_t user_accounting_size, + const struct vmw_surface_metadata *req, + struct vmw_surface **srf_out) +{ + struct vmw_surface_metadata *metadata; + struct vmw_user_surface *user_srf; + struct vmw_surface *srf; + struct ttm_operation_ctx ctx = { + .interruptible = true, + .no_wait_gpu = false + }; + u32 sample_count = 1; + u32 num_layers = 1; + int ret; + + *srf_out = NULL; + + if (req->scanout) { + if (!svga3dsurface_is_screen_target_format(req->format)) { + VMW_DEBUG_USER("Invalid Screen Target surface format."); + return -EINVAL; + } + + if (req->base_size.width > dev_priv->texture_max_width || + req->base_size.height > dev_priv->texture_max_height) { + VMW_DEBUG_USER("%ux%u\n, exceed max surface size %ux%u", + req->base_size.width, + req->base_size.height, + dev_priv->texture_max_width, + dev_priv->texture_max_height); + return -EINVAL; + } + } else { + const struct svga3d_surface_desc *desc = + svga3dsurface_get_desc(req->format); + + if (desc->block_desc == SVGA3DBLOCKDESC_NONE) { + VMW_DEBUG_USER("Invalid surface format.\n"); + return -EINVAL; + } + } + + if (req->autogen_filter != SVGA3D_TEX_FILTER_NONE) + return -EINVAL; + + if (req->num_sizes != 1) + return -EINVAL; + + if (req->sizes != NULL) + return -EINVAL; + + ret = ttm_read_lock(&dev_priv->reservation_sem, true); + if (unlikely(ret != 0)) + return ret; + + ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), + user_accounting_size, &ctx); + if (ret != 0) { + if (ret != -ERESTARTSYS) + DRM_ERROR("Out of graphics memory for surface.\n"); + goto out_unlock; + } + + user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); + if (unlikely(!user_srf)) { + ret = -ENOMEM; + goto out_no_user_srf; + } + + *srf_out = &user_srf->srf; + user_srf->size = user_accounting_size; + user_srf->prime.base.shareable = false; + user_srf->prime.base.tfile = NULL; + + srf = &user_srf->srf; + srf->metadata = *req; + srf->offsets = NULL; + + metadata = &srf->metadata; + + if (metadata->array_size) + num_layers = req->array_size; + else if (metadata->flags & SVGA3D_SURFACE_CUBEMAP) + num_layers = SVGA3D_MAX_SURFACE_FACES; + + if (metadata->flags & SVGA3D_SURFACE_MULTISAMPLE) + sample_count = metadata->multisample_count; + + srf->res.backup_size = + svga3dsurface_get_serialized_size_extended(metadata->format, + metadata->base_size, + metadata->mip_levels[0], + num_layers, + sample_count); + + if (metadata->flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) + srf->res.backup_size += sizeof(SVGA3dDXSOState); + + /* + * Don't set SVGA3D_SURFACE_SCREENTARGET flag for a scanout surface with + * size greater than STDU max width/height. This is really a workaround + * to support creation of big framebuffer requested by some user-space + * for whole topology. That big framebuffer won't really be used for + * binding with screen target as during prepare_fb a separate surface is + * created so it's safe to ignore SVGA3D_SURFACE_SCREENTARGET flag. + */ + if (dev_priv->active_display_unit == vmw_du_screen_target && + metadata->scanout && + metadata->base_size.width <= dev_priv->stdu_max_width && + metadata->base_size.height <= dev_priv->stdu_max_height) + metadata->flags |= SVGA3D_SURFACE_SCREENTARGET; + + /* + * From this point, the generic resource management functions + * destroy the object on failure. + */ + ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free); + + ttm_read_unlock(&dev_priv->reservation_sem); + return ret; + +out_no_user_srf: + ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size); + +out_unlock: + ttm_read_unlock(&dev_priv->reservation_sem); + return ret; +} -- cgit 1.4.1 From 2a50f06d639bc6d21e855296c2fa511b080f9a79 Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Tue, 30 Apr 2019 13:04:55 -0700 Subject: drm/vmwgfx: Add surface define v4 command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface define v4 added new member buffer_byte_stride. With this patch add buffer_byte_stride in surface metadata and create surface using new command if support is available. Also with this patch replace device specific data types with kernel types. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 ++ drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 36 +++++++++++++++++++++++++++++++-- include/uapi/drm/vmwgfx_drm.h | 12 ++++++----- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 326d1dd58bc5..0447be87697e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -238,6 +238,7 @@ struct vmw_surface_offset; * @array_size: Number of array elements for a 1D/2D texture. For cubemap texture number of faces * array_size. This should be 0 for pre SM4 device. + * @buffer_byte_stride: Buffer byte stride. * @num_sizes: Size of @sizes. For GB surface this should always be 1. * @base_size: Surface dimension. * @sizes: Array representing mip sizes. Legacy only. @@ -255,6 +256,7 @@ struct vmw_surface_metadata { u32 autogen_filter; u32 array_size; u32 num_sizes; + u32 buffer_byte_stride; struct drm_vmw_size base_size; struct drm_vmw_size *sizes; bool scanout; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 6c907b147e97..7ef51fa84b01 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1082,6 +1082,10 @@ static int vmw_gb_surface_create(struct vmw_resource *res) SVGA3dCmdHeader header; SVGA3dCmdDefineGBSurface_v3 body; } *cmd3; + struct { + SVGA3dCmdHeader header; + SVGA3dCmdDefineGBSurface_v4 body; + } *cmd4; if (likely(res->id != -1)) return 0; @@ -1098,7 +1102,11 @@ static int vmw_gb_surface_create(struct vmw_resource *res) goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V4; + cmd_len = sizeof(cmd4->body); + submit_len = sizeof(*cmd4); + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); @@ -1116,12 +1124,29 @@ static int vmw_gb_surface_create(struct vmw_resource *res) cmd = VMW_FIFO_RESERVE(dev_priv, submit_len); cmd2 = (typeof(cmd2))cmd; cmd3 = (typeof(cmd3))cmd; + cmd4 = (typeof(cmd4))cmd; if (unlikely(!cmd)) { ret = -ENOMEM; goto out_no_fifo; } - if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { + if (has_sm5_context(dev_priv) && metadata->array_size > 0) { + cmd4->header.id = cmd_id; + cmd4->header.size = cmd_len; + cmd4->body.sid = srf->res.id; + cmd4->body.surfaceFlags = metadata->flags; + cmd4->body.format = metadata->format; + cmd4->body.numMipLevels = metadata->mip_levels[0]; + cmd4->body.multisampleCount = metadata->multisample_count; + cmd4->body.multisamplePattern = metadata->multisample_pattern; + cmd4->body.qualityLevel = metadata->quality_level; + cmd4->body.autogenFilter = metadata->autogen_filter; + cmd4->body.size.width = metadata->base_size.width; + cmd4->body.size.height = metadata->base_size.height; + cmd4->body.size.depth = metadata->base_size.depth; + cmd4->body.arraySize = metadata->array_size; + cmd4->body.bufferByteStride = metadata->buffer_byte_stride; + } else if (has_sm4_1_context(dev_priv) && metadata->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; @@ -1341,6 +1366,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data, req_ext.svga3d_flags_upper_32_bits = 0; req_ext.multisample_pattern = SVGA3D_MS_PATTERN_NONE; req_ext.quality_level = SVGA3D_MS_QUALITY_NONE; + req_ext.buffer_byte_stride = 0; req_ext.must_be_zero = 0; return vmw_gb_surface_define_internal(dev, &req_ext, rep, file_priv); @@ -1467,6 +1493,11 @@ vmw_gb_surface_define_internal(struct drm_device *dev, } } + if (req->buffer_byte_stride > 0 && !has_sm5_context(dev_priv)) { + VMW_DEBUG_USER("SM5 surface not supported.\n"); + return -EINVAL; + } + if ((svga3d_flags_64 & SVGA3D_SURFACE_MULTISAMPLE) && req->base.multisample_count == 0) { VMW_DEBUG_USER("Invalid sample count.\n"); @@ -1491,6 +1522,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev, metadata.multisample_pattern = req->multisample_pattern; metadata.quality_level = req->quality_level; metadata.array_size = req->base.array_size; + metadata.buffer_byte_stride = req->buffer_byte_stride; metadata.num_sizes = 1; metadata.base_size = req->base.base_size; metadata.scanout = req->base.drm_surface_flags & diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index fcb741e3068f..8cd4b321597c 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -1133,7 +1133,7 @@ struct drm_vmw_handle_close_arg { * svga3d surface flags split into 2, upper half and lower half. */ enum drm_vmw_surface_version { - drm_vmw_gb_surface_v1 + drm_vmw_gb_surface_v1, }; /** @@ -1144,6 +1144,7 @@ enum drm_vmw_surface_version { * @svga3d_flags_upper_32_bits: Upper 32 bits of svga3d flags. * @multisample_pattern: Multisampling pattern when msaa is supported. * @quality_level: Precision settings for each sample. + * @buffer_byte_stride: Buffer byte stride. * @must_be_zero: Reserved for future usage. * * Input argument to the DRM_VMW_GB_SURFACE_CREATE_EXT Ioctl. @@ -1152,10 +1153,11 @@ enum drm_vmw_surface_version { struct drm_vmw_gb_surface_create_ext_req { struct drm_vmw_gb_surface_create_req base; enum drm_vmw_surface_version version; - uint32_t svga3d_flags_upper_32_bits; - SVGA3dMSPattern multisample_pattern; - SVGA3dMSQualityLevel quality_level; - uint64_t must_be_zero; + __u32 svga3d_flags_upper_32_bits; + __u32 multisample_pattern; + __u32 quality_level; + __u32 buffer_byte_stride; + __u32 must_be_zero; }; /** -- cgit 1.4.1 From f0fce23384dad01ae65ba30552f91f6cb76ee56f Mon Sep 17 00:00:00 2001 From: Deepak Rawat Date: Thu, 13 Dec 2018 14:23:46 -0800 Subject: drm/vmwgfx: Add SM5 param for userspace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new param for user-space to determine if kernel module is SM5 capable. Signed-off-by: Deepak Rawat Reviewed-by: Thomas Hellström (VMware) Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger --- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 3 +++ include/uapi/drm/vmwgfx_drm.h | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 0af42875ba4e..f681b7b4df1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -119,6 +119,9 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, case DRM_VMW_PARAM_SM4_1: param->value = has_sm4_1_context(dev_priv); break; + case DRM_VMW_PARAM_SM5: + param->value = has_sm5_context(dev_priv); + break; default: return -EINVAL; } diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h index 8cd4b321597c..02e917507479 100644 --- a/include/uapi/drm/vmwgfx_drm.h +++ b/include/uapi/drm/vmwgfx_drm.h @@ -86,6 +86,9 @@ extern "C" { * * DRM_VMW_PARAM_SM4_1 * SM4_1 support is enabled. + * + * DRM_VMW_PARAM_SM5 + * SM5 support is enabled. */ #define DRM_VMW_PARAM_NUM_STREAMS 0 @@ -103,6 +106,7 @@ extern "C" { #define DRM_VMW_PARAM_DX 12 #define DRM_VMW_PARAM_HW_CAPS2 13 #define DRM_VMW_PARAM_SM4_1 14 +#define DRM_VMW_PARAM_SM5 15 /** * enum drm_vmw_handle_type - handle type for ref ioctls -- cgit 1.4.1 From f59e61acececc5f25313252da178a5c5eba568bd Mon Sep 17 00:00:00 2001 From: "Thomas Hellström (VMware)" Date: Wed, 23 Oct 2019 08:27:18 +0200 Subject: drm/vmwgfx: Use vmwgfx version 2.18 to signal SM5 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thomas Hellström (VMware) Reviewed-by: Charmaine Lee Reviewed-by: Brian Paul Reviewed-by: Roland Scheidegger Signed-off-by: Roland Scheidegger ___ v2: Use 2.18 instead of 2.17 --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 0447be87697e..5ddbcb9f6df4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -58,7 +58,7 @@ #define VMWGFX_DRIVER_NAME "vmwgfx" #define VMWGFX_DRIVER_DATE "20200114" #define VMWGFX_DRIVER_MAJOR 2 -#define VMWGFX_DRIVER_MINOR 17 +#define VMWGFX_DRIVER_MINOR 18 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_MAX_RELOCATIONS 2048 -- cgit 1.4.1