Commit c2556238 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'feature/staging_sm5' of git://people.freedesktop.org/~sroland/linux into drm-next

vmwgfx pull for for 5.7. Needed for GL4 functionality.
Sync up device headers, add support for new commands, code
refactoring around surface definition.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: "Roland Scheidegger (VMware)" <rscheidegger.oss@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200323235434.11780-1-rscheidegger.oss@gmail.com
parents de487e43 f59e61ac
......@@ -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
/* 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_ */
......@@ -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)
......
......@@ -37,6 +37,7 @@ typedef s8 int8;
typedef uint64 PA;
typedef uint32 PPN;
typedef uint32 PPN32;
typedef uint64 PPN64;
typedef bool Bool;
......
This diff is collapsed.
......@@ -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;
......@@ -48,9 +50,12 @@ 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,
vmw_ctx_binding_cs_uav,
vmw_ctx_binding_so,
vmw_ctx_binding_max
};
......@@ -128,14 +133,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;
......@@ -189,9 +194,31 @@ 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;
};
/**
* 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);
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);
......
......@@ -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. */
......@@ -731,7 +738,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;
}
......@@ -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)->
......
......@@ -80,9 +80,10 @@ 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(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,
......
......@@ -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)
......@@ -449,7 +451,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);
......@@ -718,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
......@@ -883,14 +891,32 @@ 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);
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;
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);
if (unlikely(ret != 0))
goto out_no_kms;
......@@ -900,23 +926,14 @@ 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_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)
DRM_INFO("SM4 support available.\n");
snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s",
VMWGFX_REPO, VMWGFX_GIT_VERSION);
......
......@@ -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
......@@ -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;
......@@ -223,24 +225,58 @@ 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.
* @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.
* @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;
u32 buffer_byte_stride;
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 {
......@@ -441,6 +477,22 @@ 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_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
};
struct vmw_private {
struct ttm_bo_device bdev;
......@@ -475,9 +527,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 +700,39 @@ 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);
}
/**
* 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);
......@@ -1226,6 +1311,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
*/
......@@ -1258,6 +1348,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
*/
......
This diff is collapsed.
......@@ -114,10 +114,13 @@ 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;
case DRM_VMW_PARAM_SM5:
param->value = has_sm5_context(dev_priv);
break;
default:
return -EINVAL;
......@@ -126,14 +129,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 +170,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 +226,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);
......
......@@ -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 (!dev_priv->has_dx && format != surface->format) {
if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
DRM_ERROR("Invalid surface format for requested mode.\n");
return -EINVAL;
}
......@@ -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;
......@@ -2516,7 +2509,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;
......
......@@ -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;
......
......@@ -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[] = {
......
......@@ -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;
......@@ -123,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:
......
......@@ -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;
......@@ -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;
......@@ -1058,8 +1057,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;
......@@ -1067,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
......@@ -1082,15 +1081,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;
metadata.format = SVGA3D_X8R8G8B8;
break;
case 16:
content_srf.format = SVGA3D_R5G6B5;
metadata.format = SVGA3D_R5G6B5;
break;
case 8:
content_srf.format = SVGA3D_P8;
metadata.format = SVGA3D_P8;
break;
default:
......@@ -1098,22 +1097,20 @@ 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 =
SVGA3D_MS_PATTERN_NONE;
content_srf.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->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) {
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);
}
......@@ -1121,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.flags,
content_srf.format,
true, /* a scanout buffer */
content_srf.mip_levels[0],
content_srf.multisample_count,
0,
display_base_size,
content_srf.multisample_pattern,
content_srf.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;
......@@ -1311,7 +1296,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;
......
This diff is collapsed.
This diff is collapsed.
......@@ -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
......@@ -1133,7 +1137,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 +1148,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 +1157,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;
};
/**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment