mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
Merge branch 'require-gb' into 'main'
winsys/svga: Require Guest-Backed (GB) Objects See merge request mesa/mesa!38774
This commit is contained in:
commit
081acef9ef
5 changed files with 22 additions and 297 deletions
|
|
@ -524,8 +524,6 @@ vmw_swc_surface_relocation(struct svga_winsys_context *swc,
|
|||
{
|
||||
struct vmw_svga_winsys_surface *vsurf;
|
||||
|
||||
assert(swc->have_gb_objects || mobid == NULL);
|
||||
|
||||
if (!surface) {
|
||||
*where = SVGA3D_INVALID_ID;
|
||||
if (mobid)
|
||||
|
|
@ -536,7 +534,7 @@ vmw_swc_surface_relocation(struct svga_winsys_context *swc,
|
|||
vsurf = vmw_svga_winsys_surface(surface);
|
||||
vmw_swc_surface_only_relocation(swc, where, vsurf, flags);
|
||||
|
||||
if (swc->have_gb_objects && vsurf->buf != NULL) {
|
||||
if (vsurf->buf != NULL) {
|
||||
|
||||
/*
|
||||
* Make sure backup buffer ends up fenced.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ vmw_winsys_screen(struct svga_winsys_screen *base)
|
|||
static inline bool
|
||||
vmw_has_userspace_surface(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
if (!vws->base.have_gb_objects || !vws->base.have_vgpu10)
|
||||
if (!vws->base.have_vgpu10)
|
||||
return false;
|
||||
return vws->userspace_surface;
|
||||
}
|
||||
|
|
@ -139,15 +139,6 @@ vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
|
|||
uint32 cid);
|
||||
|
||||
uint32
|
||||
vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurface1Flags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
unsigned usage,
|
||||
SVGA3dSize size,
|
||||
uint32 numFaces,
|
||||
uint32 numMipLevels,
|
||||
unsigned sampleCount);
|
||||
uint32
|
||||
vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurfaceAllFlags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
|
|
|
|||
|
|
@ -32,11 +32,6 @@ struct dri1_api_version {
|
|||
int patch_level;
|
||||
};
|
||||
|
||||
static struct svga_winsys_surface *
|
||||
vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
|
||||
struct winsys_handle *whandle,
|
||||
SVGA3dSurfaceFormat *format);
|
||||
|
||||
static struct svga_winsys_surface *
|
||||
vmw_drm_gb_surface_from_handle(struct svga_winsys_screen *sws,
|
||||
struct winsys_handle *whandle,
|
||||
|
|
@ -97,9 +92,7 @@ svga_drm_winsys_screen_create(int fd)
|
|||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
/* XXX do this properly */
|
||||
vws->base.surface_from_handle = vws->base.have_gb_objects ?
|
||||
vmw_drm_gb_surface_from_handle : vmw_drm_surface_from_handle;
|
||||
vws->base.surface_from_handle = vmw_drm_gb_surface_from_handle;
|
||||
vws->base.surface_get_handle = vmw_drm_surface_get_handle;
|
||||
|
||||
return &vws->base;
|
||||
|
|
@ -192,117 +185,6 @@ out_mip:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct svga_winsys_surface *
|
||||
vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
|
||||
struct winsys_handle *whandle,
|
||||
SVGA3dSurfaceFormat *format)
|
||||
{
|
||||
struct vmw_svga_winsys_surface *vsrf;
|
||||
struct svga_winsys_surface *ssrf;
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
union drm_vmw_surface_reference_arg arg;
|
||||
struct drm_vmw_surface_arg *req = &arg.req;
|
||||
struct drm_vmw_surface_create_req *rep = &arg.rep;
|
||||
uint32_t handle = 0;
|
||||
struct drm_vmw_size size;
|
||||
SVGA3dSize base_size;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (whandle->offset != 0) {
|
||||
fprintf(stderr, "Attempt to import unsupported winsys offset %u\n",
|
||||
whandle->offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (whandle->type) {
|
||||
case WINSYS_HANDLE_TYPE_SHARED:
|
||||
case WINSYS_HANDLE_TYPE_KMS:
|
||||
handle = whandle->handle;
|
||||
break;
|
||||
case WINSYS_HANDLE_TYPE_FD:
|
||||
ret = drmPrimeFDToHandle(vws->ioctl.drm_fd, whandle->handle,
|
||||
&handle);
|
||||
if (ret) {
|
||||
vmw_error("Failed to get handle from prime fd %d.\n",
|
||||
(int) whandle->handle);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vmw_error("Attempt to import unsupported handle type %d.\n",
|
||||
whandle->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
req->sid = handle;
|
||||
rep->size_addr = (unsigned long)&size;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
|
||||
&arg, sizeof(arg));
|
||||
|
||||
/*
|
||||
* Need to close the handle we got from prime.
|
||||
*/
|
||||
if (whandle->type == WINSYS_HANDLE_TYPE_FD)
|
||||
vmw_ioctl_surface_destroy(vws, handle);
|
||||
|
||||
if (ret) {
|
||||
/*
|
||||
* Any attempt to share something other than a surface, like a dumb
|
||||
* kms buffer, should fail here.
|
||||
*/
|
||||
vmw_error("Failed referencing shared surface. SID %d.\n"
|
||||
"Error %d (%s).\n",
|
||||
handle, ret, strerror(-ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rep->mip_levels[0] != 1) {
|
||||
vmw_error("Incorrect number of mipmap levels on shared surface."
|
||||
" SID %d, levels %d\n",
|
||||
handle, rep->mip_levels[0]);
|
||||
goto out_mip;
|
||||
}
|
||||
|
||||
for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
|
||||
if (rep->mip_levels[i] != 0) {
|
||||
vmw_error("Incorrect number of faces levels on shared surface."
|
||||
" SID %d, face %d present.\n",
|
||||
handle, i);
|
||||
goto out_mip;
|
||||
}
|
||||
}
|
||||
|
||||
vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface);
|
||||
if (!vsrf)
|
||||
goto out_mip;
|
||||
|
||||
pipe_reference_init(&vsrf->refcnt, 1);
|
||||
p_atomic_set(&vsrf->validated, 0);
|
||||
vsrf->screen = vws;
|
||||
vsrf->sid = handle;
|
||||
ssrf = svga_winsys_surface(vsrf);
|
||||
*format = rep->format;
|
||||
|
||||
/* Estimate usage, for early flushing. */
|
||||
|
||||
base_size.width = size.width;
|
||||
base_size.height = size.height;
|
||||
base_size.depth = size.depth;
|
||||
vsrf->size = vmw_surf_get_serialized_size(rep->format, base_size,
|
||||
rep->mip_levels[0],
|
||||
false);
|
||||
|
||||
return ssrf;
|
||||
|
||||
out_mip:
|
||||
vmw_ioctl_surface_destroy(vws, handle);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
|
||||
struct svga_winsys_surface *surface,
|
||||
|
|
|
|||
|
|
@ -116,68 +116,6 @@ vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
|
|||
|
||||
}
|
||||
|
||||
uint32
|
||||
vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurface1Flags flags,
|
||||
SVGA3dSurfaceFormat format,
|
||||
unsigned usage,
|
||||
SVGA3dSize size,
|
||||
uint32_t numFaces, uint32_t numMipLevels,
|
||||
unsigned sampleCount)
|
||||
{
|
||||
union drm_vmw_surface_create_arg s_arg;
|
||||
struct drm_vmw_surface_create_req *req = &s_arg.req;
|
||||
struct drm_vmw_surface_arg *rep = &s_arg.rep;
|
||||
struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
|
||||
DRM_VMW_MAX_MIP_LEVELS];
|
||||
struct drm_vmw_size *cur_size;
|
||||
uint32_t iFace;
|
||||
uint32_t iMipLevel;
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s flags %d format %d\n", __func__, flags, format);
|
||||
|
||||
memset(&s_arg, 0, sizeof(s_arg));
|
||||
req->flags = (uint32_t) flags;
|
||||
req->scanout = !!(usage & SVGA_SURFACE_USAGE_SCANOUT);
|
||||
req->format = (uint32_t) format;
|
||||
req->shareable = true;
|
||||
|
||||
assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
|
||||
DRM_VMW_MAX_MIP_LEVELS);
|
||||
cur_size = sizes;
|
||||
for (iFace = 0; iFace < numFaces; ++iFace) {
|
||||
SVGA3dSize mipSize = size;
|
||||
|
||||
req->mip_levels[iFace] = numMipLevels;
|
||||
for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
|
||||
cur_size->width = mipSize.width;
|
||||
cur_size->height = mipSize.height;
|
||||
cur_size->depth = mipSize.depth;
|
||||
mipSize.width = MAX2(mipSize.width >> 1, 1);
|
||||
mipSize.height = MAX2(mipSize.height >> 1, 1);
|
||||
mipSize.depth = MAX2(mipSize.depth >> 1, 1);
|
||||
cur_size++;
|
||||
}
|
||||
}
|
||||
for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
|
||||
req->mip_levels[iFace] = 0;
|
||||
}
|
||||
|
||||
req->size_addr = (unsigned long)&sizes;
|
||||
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
|
||||
&s_arg, sizeof(s_arg));
|
||||
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
vmw_printf("Surface id is %d\n", rep->sid);
|
||||
|
||||
return rep->sid;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
|
||||
SVGA3dSurfaceAllFlags flags,
|
||||
|
|
@ -911,55 +849,9 @@ static int
|
|||
vmw_ioctl_parse_caps(struct vmw_winsys_screen *vws,
|
||||
const uint32_t *cap_buffer)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vws->base.have_gb_objects) {
|
||||
for (i = 0; i < vws->ioctl.num_cap_3d; ++i) {
|
||||
vws->ioctl.cap_3d[i].has_cap = true;
|
||||
vws->ioctl.cap_3d[i].result.u = cap_buffer[i];
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
const uint32 *capsBlock;
|
||||
const struct svga_3d_compat_cap *capsRecord = NULL;
|
||||
uint32 offset;
|
||||
const SVGA3dFifoCapPair *capArray;
|
||||
int numCaps, index;
|
||||
|
||||
/*
|
||||
* Search linearly through the caps block records for the specified type.
|
||||
*/
|
||||
capsBlock = cap_buffer;
|
||||
for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
|
||||
const struct svga_3d_compat_cap *record;
|
||||
assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
|
||||
record = (const struct svga_3d_compat_cap *) (capsBlock + offset);
|
||||
if ((record->header.type >= 0) &&
|
||||
(record->header.type <= SVGA3D_DEVCAP_MAX) &&
|
||||
(!capsRecord || (record->header.type > capsRecord->header.type))) {
|
||||
capsRecord = record;
|
||||
}
|
||||
}
|
||||
|
||||
if (!capsRecord)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Calculate the number of caps from the size of the record.
|
||||
*/
|
||||
capArray = (const SVGA3dFifoCapPair *) capsRecord->pairs;
|
||||
numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
|
||||
sizeof capsRecord->header) / (2 * sizeof(uint32)));
|
||||
|
||||
for (i = 0; i < numCaps; i++) {
|
||||
index = capArray[i][0];
|
||||
if (index < vws->ioctl.num_cap_3d) {
|
||||
vws->ioctl.cap_3d[index].has_cap = true;
|
||||
vws->ioctl.cap_3d[index].result.u = capArray[i][1];
|
||||
} else {
|
||||
debug_printf("Unknown devcaps seen: %d\n", index);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < vws->ioctl.num_cap_3d; ++i) {
|
||||
vws->ioctl.cap_3d[i].has_cap = true;
|
||||
vws->ioctl.cap_3d[i].result.u = cap_buffer[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -973,7 +865,6 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
int ret;
|
||||
uint32_t *cap_buffer;
|
||||
drmVersionPtr version;
|
||||
bool drm_gb_capable;
|
||||
bool have_drm_2_5;
|
||||
const char *getenv_val;
|
||||
|
||||
|
|
@ -1004,8 +895,6 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
|
||||
vws->ioctl.drm_execbuf_version = vws->ioctl.have_drm_2_9 ? 2 : 1;
|
||||
|
||||
drm_gb_capable = have_drm_2_5;
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_3D;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
|
|
@ -1025,23 +914,26 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
goto out_no_3d;
|
||||
}
|
||||
vws->ioctl.hwversion = gp_arg.value;
|
||||
getenv_val = os_get_option("SVGA_FORCE_HOST_BACKED");
|
||||
if (!getenv_val || strcmp(getenv_val, "0") == 0) {
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_HW_CAPS;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
&gp_arg, sizeof(gp_arg));
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (ret)
|
||||
vws->base.have_gb_objects = false;
|
||||
else
|
||||
vws->base.have_gb_objects =
|
||||
!!(gp_arg.value & (uint64_t) SVGA_CAP_GBOBJECTS);
|
||||
|
||||
if (vws->base.have_gb_objects && !drm_gb_capable)
|
||||
if (!have_drm_2_5) {
|
||||
vmw_error("SVGA requires a vmwgfx kernel driver >= 2.5! 3D will be disabled.\n");
|
||||
goto out_no_3d;
|
||||
}
|
||||
|
||||
if (!vws->base.have_gb_objects) {
|
||||
vmw_error("No GB Objects! 3D will be disabled.\n");
|
||||
goto out_no_3d;
|
||||
}
|
||||
|
||||
vws->base.have_vgpu10 = false;
|
||||
vws->base.have_sm4_1 = false;
|
||||
|
|
@ -1057,7 +949,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
vws->base.device_id = gp_arg.value;
|
||||
}
|
||||
|
||||
if (vws->base.have_gb_objects) {
|
||||
{
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_MAX_MOB_MEMORY;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
|
|
@ -1150,10 +1042,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
else
|
||||
size = gp_arg.value;
|
||||
|
||||
if (vws->base.have_gb_objects)
|
||||
vws->ioctl.num_cap_3d = size / sizeof(uint32_t);
|
||||
else
|
||||
vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
|
||||
vws->ioctl.num_cap_3d = size / sizeof(uint32_t);
|
||||
|
||||
if (vws->ioctl.have_drm_2_16) {
|
||||
vws->base.have_coherent = true;
|
||||
|
|
@ -1161,31 +1050,12 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
if (getenv_val && strcmp(getenv_val, "0") != 0)
|
||||
vws->force_coherent = true;
|
||||
}
|
||||
} else {
|
||||
vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_MAX_SURF_MEMORY;
|
||||
if (have_drm_2_5)
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
|
||||
&gp_arg, sizeof(gp_arg));
|
||||
if (!have_drm_2_5 || ret) {
|
||||
/* Just guess a large enough value, around 800mb. */
|
||||
vws->ioctl.max_surface_memory = 0x30000000;
|
||||
} else {
|
||||
vws->ioctl.max_surface_memory = gp_arg.value;
|
||||
}
|
||||
|
||||
vws->ioctl.max_texture_size = VMW_MAX_DEFAULT_TEXTURE_SIZE;
|
||||
|
||||
size = SVGA_FIFO_3D_CAPS_SIZE * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/* Userspace surfaces are only supported on guest-backed hardware */
|
||||
vws->userspace_surface = false;
|
||||
getenv_val = os_get_option("VMW_SVGA_USERSPACE_SURFACE");
|
||||
if (getenv_val && atoi(getenv_val)) {
|
||||
assert(vws->base.have_gb_objects);
|
||||
assert(vws->base.have_vgpu10);
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_USER_SRF;
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
|
|||
}
|
||||
|
||||
swc->flush(swc, NULL);
|
||||
} else if (sws->have_gb_objects) {
|
||||
} else {
|
||||
struct pb_buffer *pb_buf;
|
||||
|
||||
surface->sid = vmw_ioctl_gb_surface_create(vws, flags, format, usage,
|
||||
|
|
@ -610,17 +610,6 @@ vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
|
|||
vmw_ioctl_surface_destroy(vws, surface->sid);
|
||||
goto no_sid;
|
||||
}
|
||||
} else {
|
||||
/* Legacy surface only support 32-bit svga3d flags */
|
||||
surface->sid = vmw_ioctl_surface_create(vws, (SVGA3dSurface1Flags)flags,
|
||||
format, usage, size, numLayers,
|
||||
numMipLevels, sampleCount);
|
||||
if (surface->sid == SVGA3D_INVALID_ID)
|
||||
goto no_sid;
|
||||
|
||||
/* Best estimate for surface size, used for early flushing. */
|
||||
surface->size = buffer_size;
|
||||
surface->buf = NULL;
|
||||
}
|
||||
|
||||
return svga_winsys_surface(surface);
|
||||
|
|
@ -692,12 +681,7 @@ vmw_svga_winsys_destroy(struct svga_winsys_screen *sws)
|
|||
static SVGA3dHardwareVersion
|
||||
vmw_svga_winsys_get_hw_version(struct svga_winsys_screen *sws)
|
||||
{
|
||||
struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
|
||||
|
||||
if (sws->have_gb_objects)
|
||||
return SVGA3D_HWVERSION_WS8_B1;
|
||||
|
||||
return (SVGA3dHardwareVersion) vws->ioctl.hwversion;
|
||||
return SVGA3D_HWVERSION_WS8_B1;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue