winsys/svga: Fix prime surface references also for guest-backed surfaces
Implement guest-backed surface sharing using prime fds. Previously only legacy surfaces could use this functionality. Also use the vmwgfx 2.6 single-ioctl prime fd reference if available. Cc: "10.1" <mesa-stable@lists.freedesktop.org> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
parent
0887b499e9
commit
2f6fcd65f2
|
@ -74,6 +74,7 @@ struct vmw_winsys_screen
|
|||
struct vmw_cap_3d *cap_3d;
|
||||
uint64_t max_mob_memory;
|
||||
uint64_t max_surface_memory;
|
||||
boolean have_drm_2_6;
|
||||
} ioctl;
|
||||
|
||||
struct {
|
||||
|
@ -138,10 +139,11 @@ vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
|
|||
|
||||
int
|
||||
vmw_ioctl_gb_surface_ref(struct vmw_winsys_screen *vws,
|
||||
uint32_t handle,
|
||||
const struct winsys_handle *whandle,
|
||||
SVGA3dSurfaceFlags *flags,
|
||||
SVGA3dSurfaceFormat *format,
|
||||
uint32_t *numMipLevels,
|
||||
uint32_t *handle,
|
||||
struct vmw_region **p_region);
|
||||
|
||||
void
|
||||
|
|
|
@ -183,10 +183,11 @@ vmw_drm_gb_surface_from_handle(struct svga_winsys_screen *sws,
|
|||
struct vmw_buffer_desc desc;
|
||||
struct pb_manager *provider = vws->pools.gmr;
|
||||
struct pb_buffer *pb_buf;
|
||||
uint32_t handle;
|
||||
int ret;
|
||||
|
||||
ret = vmw_ioctl_gb_surface_ref(vws, whandle->handle, &flags, format,
|
||||
&mip_levels, &desc.region);
|
||||
ret = vmw_ioctl_gb_surface_ref(vws, whandle, &flags, format,
|
||||
&mip_levels, &handle, &desc.region);
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
|
||||
|
@ -209,7 +210,7 @@ vmw_drm_gb_surface_from_handle(struct svga_winsys_screen *sws,
|
|||
pipe_reference_init(&vsrf->refcnt, 1);
|
||||
p_atomic_set(&vsrf->validated, 0);
|
||||
vsrf->screen = vws;
|
||||
vsrf->sid = whandle->handle;
|
||||
vsrf->sid = handle;
|
||||
vsrf->size = vmw_region_size(desc.region);
|
||||
|
||||
/*
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
#include "svgadump/svga_dump.h"
|
||||
#include "state_tracker/drm_driver.h"
|
||||
#include "vmw_screen.h"
|
||||
#include "vmw_context.h"
|
||||
#include "vmw_fence.h"
|
||||
|
@ -250,6 +251,63 @@ out_fail_create:
|
|||
return SVGA3D_INVALID_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_ioctl_surface_req - Fill in a struct surface_req
|
||||
*
|
||||
* @vws: Winsys screen
|
||||
* @whandle: Surface handle
|
||||
* @req: The struct surface req to fill in
|
||||
* @needs_unref: This call takes a kernel surface reference that needs to
|
||||
* be unreferenced.
|
||||
*
|
||||
* Returns 0 on success, negative error type otherwise.
|
||||
* Fills in the surface_req structure according to handle type and kernel
|
||||
* capabilities.
|
||||
*/
|
||||
static int
|
||||
vmw_ioctl_surface_req(const struct vmw_winsys_screen *vws,
|
||||
const struct winsys_handle *whandle,
|
||||
struct drm_vmw_surface_arg *req,
|
||||
boolean *needs_unref)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch(whandle->type) {
|
||||
case DRM_API_HANDLE_TYPE_SHARED:
|
||||
case DRM_API_HANDLE_TYPE_KMS:
|
||||
*needs_unref = FALSE;
|
||||
req->handle_type = DRM_VMW_HANDLE_LEGACY;
|
||||
req->sid = whandle->handle;
|
||||
break;
|
||||
case DRM_API_HANDLE_TYPE_FD:
|
||||
if (!vws->ioctl.have_drm_2_6) {
|
||||
uint32_t handle;
|
||||
|
||||
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 -EINVAL;
|
||||
}
|
||||
|
||||
*needs_unref = TRUE;
|
||||
req->handle_type = DRM_VMW_HANDLE_LEGACY;
|
||||
req->sid = handle;
|
||||
} else {
|
||||
*needs_unref = FALSE;
|
||||
req->handle_type = DRM_VMW_HANDLE_PRIME;
|
||||
req->sid = whandle->handle;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vmw_error("Attempt to import unsupported handle type %d.\n",
|
||||
whandle->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_ioctl_gb_surface_ref - Put a reference on a guest-backed surface and
|
||||
* get surface information
|
||||
|
@ -266,16 +324,18 @@ out_fail_create:
|
|||
*/
|
||||
int
|
||||
vmw_ioctl_gb_surface_ref(struct vmw_winsys_screen *vws,
|
||||
uint32_t handle,
|
||||
const struct winsys_handle *whandle,
|
||||
SVGA3dSurfaceFlags *flags,
|
||||
SVGA3dSurfaceFormat *format,
|
||||
uint32_t *numMipLevels,
|
||||
uint32_t *handle,
|
||||
struct vmw_region **p_region)
|
||||
{
|
||||
union drm_vmw_gb_surface_reference_arg s_arg;
|
||||
struct drm_vmw_surface_arg *req = &s_arg.req;
|
||||
struct drm_vmw_gb_surface_ref_rep *rep = &s_arg.rep;
|
||||
struct vmw_region *region = NULL;
|
||||
boolean needs_unref = FALSE;
|
||||
int ret;
|
||||
|
||||
vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
|
||||
|
@ -286,8 +346,11 @@ vmw_ioctl_gb_surface_ref(struct vmw_winsys_screen *vws,
|
|||
return -ENOMEM;
|
||||
|
||||
memset(&s_arg, 0, sizeof(s_arg));
|
||||
req->sid = handle;
|
||||
ret = vmw_ioctl_surface_req(vws, whandle, req, &needs_unref);
|
||||
if (ret)
|
||||
goto out_fail_req;
|
||||
|
||||
*handle = req->sid;
|
||||
ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GB_SURFACE_REF,
|
||||
&s_arg, sizeof(s_arg));
|
||||
|
||||
|
@ -300,12 +363,19 @@ vmw_ioctl_gb_surface_ref(struct vmw_winsys_screen *vws,
|
|||
region->size = rep->crep.backup_size;
|
||||
*p_region = region;
|
||||
|
||||
*handle = rep->crep.handle;
|
||||
*flags = rep->creq.svga3d_flags;
|
||||
*format = rep->creq.format;
|
||||
*numMipLevels = rep->creq.mip_levels;
|
||||
|
||||
if (needs_unref)
|
||||
vmw_ioctl_surface_destroy(vws, *handle);
|
||||
|
||||
return 0;
|
||||
out_fail_ref:
|
||||
if (needs_unref)
|
||||
vmw_ioctl_surface_destroy(vws, *handle);
|
||||
out_fail_req:
|
||||
if (region)
|
||||
FREE(region);
|
||||
return ret;
|
||||
|
@ -772,6 +842,8 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
|
|||
|
||||
have_drm_2_5 = version->version_major > 2 ||
|
||||
(version->version_major == 2 && version->version_minor > 4);
|
||||
vws->ioctl.have_drm_2_6 = version->version_major > 2 ||
|
||||
(version->version_major == 2 && version->version_minor > 5);
|
||||
|
||||
memset(&gp_arg, 0, sizeof(gp_arg));
|
||||
gp_arg.param = DRM_VMW_PARAM_3D;
|
||||
|
|
Loading…
Reference in New Issue