Like xa_surface_from_handle(), but takes a handle type, rather than hard-coding 'shared' handle. This is needed to fix bugs seen with xf86-video-freedreno with xrandr rotation, for example. The root issue is that doing a GEM_OPEN ioctl on a bo that already has a GEM handle associated with the drm_file will result in two unique handles for the same bo. Which causes all sorts of follow-on fail. v2: - Add support for for fd handles. - Avoid duplicating code. - Bump xa version minor. Signed-off-by: Rob Clark <robclark@freedesktop.org> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>tags/11.1-branchpoint
@@ -298,6 +298,20 @@ xa_format_check_supported(struct xa_tracker *xa, | |||
return XA_ERR_NONE; | |||
} | |||
static unsigned | |||
handle_type(enum xa_handle_type type) | |||
{ | |||
switch (type) { | |||
case xa_handle_type_kms: | |||
return DRM_API_HANDLE_TYPE_KMS; | |||
case xa_handle_type_fd: | |||
return DRM_API_HANDLE_TYPE_FD; | |||
case xa_handle_type_shared: | |||
default: | |||
return DRM_API_HANDLE_TYPE_SHARED; | |||
} | |||
} | |||
static struct xa_surface * | |||
surface_create(struct xa_tracker *xa, | |||
int width, | |||
@@ -379,10 +393,25 @@ xa_surface_from_handle(struct xa_tracker *xa, | |||
enum xa_surface_type stype, | |||
enum xa_formats xa_format, unsigned int flags, | |||
uint32_t handle, uint32_t stride) | |||
{ | |||
return xa_surface_from_handle2(xa, width, height, depth, stype, xa_format, | |||
DRM_API_HANDLE_TYPE_SHARED, flags, handle, | |||
stride); | |||
} | |||
XA_EXPORT struct xa_surface * | |||
xa_surface_from_handle2(struct xa_tracker *xa, | |||
int width, | |||
int height, | |||
int depth, | |||
enum xa_surface_type stype, | |||
enum xa_formats xa_format, unsigned int flags, | |||
enum xa_handle_type type, | |||
uint32_t handle, uint32_t stride) | |||
{ | |||
struct winsys_handle whandle; | |||
memset(&whandle, 0, sizeof(whandle)); | |||
whandle.type = DRM_API_HANDLE_TYPE_SHARED; | |||
whandle.type = handle_type(type); | |||
whandle.handle = handle; | |||
whandle.stride = stride; | |||
return surface_create(xa, width, height, depth, stype, xa_format, flags, &whandle); | |||
@@ -511,15 +540,7 @@ xa_surface_handle(struct xa_surface *srf, | |||
boolean res; | |||
memset(&whandle, 0, sizeof(whandle)); | |||
switch (type) { | |||
case xa_handle_type_kms: | |||
whandle.type = DRM_API_HANDLE_TYPE_KMS; | |||
break; | |||
case xa_handle_type_shared: | |||
default: | |||
whandle.type = DRM_API_HANDLE_TYPE_SHARED; | |||
break; | |||
} | |||
whandle.type = handle_type(type); | |||
res = screen->resource_get_handle(screen, srf->tex, &whandle); | |||
if (!res) | |||
return -XA_ERR_INVAL; |
@@ -37,7 +37,7 @@ | |||
#include <stdint.h> | |||
#define XA_TRACKER_VERSION_MAJOR 2 | |||
#define XA_TRACKER_VERSION_MINOR 2 | |||
#define XA_TRACKER_VERSION_MINOR 3 | |||
#define XA_TRACKER_VERSION_PATCH 0 | |||
#define XA_FLAG_SHARED (1 << 0) | |||
@@ -149,6 +149,7 @@ struct xa_box { | |||
enum xa_handle_type { | |||
xa_handle_type_shared, | |||
xa_handle_type_kms, | |||
xa_handle_type_fd, | |||
}; | |||
extern void xa_tracker_version(int *major, int *minor, int *patch); | |||
@@ -177,6 +178,17 @@ extern struct xa_surface * xa_surface_from_handle(struct xa_tracker *xa, | |||
enum xa_formats pform, | |||
unsigned int flags, | |||
uint32_t handle, uint32_t stride); | |||
extern struct xa_surface * | |||
xa_surface_from_handle2(struct xa_tracker *xa, | |||
int width, | |||
int height, | |||
int depth, | |||
enum xa_surface_type stype, | |||
enum xa_formats xa_format, | |||
unsigned int flags, | |||
enum xa_handle_type type, | |||
uint32_t handle, | |||
uint32_t stride); | |||
enum xa_formats xa_surface_format(const struct xa_surface *srf); | |||
@@ -23,6 +23,7 @@ | |||
xa_surface_dma; | |||
xa_surface_format; | |||
xa_surface_from_handle; | |||
xa_surface_from_handle2; | |||
xa_surface_handle; | |||
xa_surface_map; | |||
xa_surface_redefine; |