kopper: copy a bunch of code for texture_from_pixmap
seems to work? Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16152>
This commit is contained in:
parent
89602c3970
commit
054bd2d38f
|
@ -43,9 +43,18 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/dri3.h>
|
||||
#include <xcb/present.h>
|
||||
#include <xcb/xfixes.h>
|
||||
#include "util/libsync.h"
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
|
||||
struct kopper_drawable {
|
||||
struct dri_drawable base;
|
||||
struct kopper_loader_info info;
|
||||
__DRIimage *image; //texture_from_pixmap
|
||||
bool is_pixmap;
|
||||
};
|
||||
|
||||
|
@ -199,6 +208,266 @@ dri_image_drawable_get_buffers(struct dri_drawable *drawable,
|
|||
const enum st_attachment_type *statts,
|
||||
unsigned statts_count);
|
||||
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
static int
|
||||
get_dri_format(enum pipe_format pf)
|
||||
{
|
||||
int image_format;
|
||||
switch (pf) {
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
image_format = __DRI_IMAGE_FORMAT_ABGR16161616F;
|
||||
break;
|
||||
case PIPE_FORMAT_R16G16B16X16_FLOAT:
|
||||
image_format = __DRI_IMAGE_FORMAT_XBGR16161616F;
|
||||
break;
|
||||
case PIPE_FORMAT_B5G5R5A1_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_ARGB1555;
|
||||
break;
|
||||
case PIPE_FORMAT_B5G6R5_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_RGB565;
|
||||
break;
|
||||
case PIPE_FORMAT_BGRX8888_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_XRGB8888;
|
||||
break;
|
||||
case PIPE_FORMAT_BGRA8888_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_ARGB8888;
|
||||
break;
|
||||
case PIPE_FORMAT_RGBX8888_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_XBGR8888;
|
||||
break;
|
||||
case PIPE_FORMAT_RGBA8888_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_ABGR8888;
|
||||
break;
|
||||
case PIPE_FORMAT_B10G10R10X2_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_XRGB2101010;
|
||||
break;
|
||||
case PIPE_FORMAT_B10G10R10A2_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_ARGB2101010;
|
||||
break;
|
||||
case PIPE_FORMAT_R10G10B10X2_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_XBGR2101010;
|
||||
break;
|
||||
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
||||
image_format = __DRI_IMAGE_FORMAT_ABGR2101010;
|
||||
break;
|
||||
default:
|
||||
image_format = __DRI_IMAGE_FORMAT_NONE;
|
||||
break;
|
||||
}
|
||||
return image_format;
|
||||
}
|
||||
|
||||
/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while
|
||||
* the createImageFromFds call takes DRM_FORMAT codes. To avoid
|
||||
* complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and
|
||||
* translate to DRM_FORMAT codes in the call to createImageFromFds
|
||||
*/
|
||||
static int
|
||||
image_format_to_fourcc(int format)
|
||||
{
|
||||
|
||||
/* Convert from __DRI_IMAGE_FORMAT to DRM_FORMAT (sigh) */
|
||||
switch (format) {
|
||||
case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
|
||||
case __DRI_IMAGE_FORMAT_SABGR8: return __DRI_IMAGE_FOURCC_SABGR8888;
|
||||
case __DRI_IMAGE_FORMAT_SXRGB8: return __DRI_IMAGE_FOURCC_SXRGB8888;
|
||||
case __DRI_IMAGE_FORMAT_RGB565: return DRM_FORMAT_RGB565;
|
||||
case __DRI_IMAGE_FORMAT_XRGB8888: return DRM_FORMAT_XRGB8888;
|
||||
case __DRI_IMAGE_FORMAT_ARGB8888: return DRM_FORMAT_ARGB8888;
|
||||
case __DRI_IMAGE_FORMAT_ABGR8888: return DRM_FORMAT_ABGR8888;
|
||||
case __DRI_IMAGE_FORMAT_XBGR8888: return DRM_FORMAT_XBGR8888;
|
||||
case __DRI_IMAGE_FORMAT_XRGB2101010: return DRM_FORMAT_XRGB2101010;
|
||||
case __DRI_IMAGE_FORMAT_ARGB2101010: return DRM_FORMAT_ARGB2101010;
|
||||
case __DRI_IMAGE_FORMAT_XBGR2101010: return DRM_FORMAT_XBGR2101010;
|
||||
case __DRI_IMAGE_FORMAT_ABGR2101010: return DRM_FORMAT_ABGR2101010;
|
||||
case __DRI_IMAGE_FORMAT_XBGR16161616F: return DRM_FORMAT_XBGR16161616F;
|
||||
case __DRI_IMAGE_FORMAT_ABGR16161616F: return DRM_FORMAT_ABGR16161616F;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DRI3_MODIFIERS
|
||||
static __DRIimage *
|
||||
dri3_create_image_from_buffers(xcb_connection_t *c,
|
||||
xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,
|
||||
unsigned int format,
|
||||
__DRIscreen *dri_screen,
|
||||
const __DRIimageExtension *image,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
__DRIimage *ret;
|
||||
int *fds;
|
||||
uint32_t *strides_in, *offsets_in;
|
||||
int strides[4], offsets[4];
|
||||
unsigned error;
|
||||
int i;
|
||||
|
||||
if (bp_reply->nfd > 4)
|
||||
return NULL;
|
||||
|
||||
fds = xcb_dri3_buffers_from_pixmap_reply_fds(c, bp_reply);
|
||||
strides_in = xcb_dri3_buffers_from_pixmap_strides(bp_reply);
|
||||
offsets_in = xcb_dri3_buffers_from_pixmap_offsets(bp_reply);
|
||||
for (i = 0; i < bp_reply->nfd; i++) {
|
||||
strides[i] = strides_in[i];
|
||||
offsets[i] = offsets_in[i];
|
||||
}
|
||||
|
||||
ret = image->createImageFromDmaBufs2(dri_screen,
|
||||
bp_reply->width,
|
||||
bp_reply->height,
|
||||
image_format_to_fourcc(format),
|
||||
bp_reply->modifier,
|
||||
fds, bp_reply->nfd,
|
||||
strides, offsets,
|
||||
0, 0, 0, 0, /* UNDEFINED */
|
||||
&error, loaderPrivate);
|
||||
|
||||
for (i = 0; i < bp_reply->nfd; i++)
|
||||
close(fds[i]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static __DRIimage *
|
||||
dri3_create_image(xcb_connection_t *c,
|
||||
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
|
||||
unsigned int format,
|
||||
__DRIscreen *dri_screen,
|
||||
const __DRIimageExtension *image,
|
||||
void *loaderPrivate)
|
||||
{
|
||||
int *fds;
|
||||
__DRIimage *image_planar, *ret;
|
||||
int stride, offset;
|
||||
|
||||
/* Get an FD for the pixmap object
|
||||
*/
|
||||
fds = xcb_dri3_buffer_from_pixmap_reply_fds(c, bp_reply);
|
||||
|
||||
stride = bp_reply->stride;
|
||||
offset = 0;
|
||||
|
||||
/* createImageFromFds creates a wrapper __DRIimage structure which
|
||||
* can deal with multiple planes for things like Yuv images. So, once
|
||||
* we've gotten the planar wrapper, pull the single plane out of it and
|
||||
* discard the wrapper.
|
||||
*/
|
||||
image_planar = image->createImageFromFds(dri_screen,
|
||||
bp_reply->width,
|
||||
bp_reply->height,
|
||||
image_format_to_fourcc(format),
|
||||
fds, 1,
|
||||
&stride, &offset, loaderPrivate);
|
||||
close(fds[0]);
|
||||
if (!image_planar)
|
||||
return NULL;
|
||||
|
||||
ret = image->fromPlanar(image_planar, 0, loaderPrivate);
|
||||
|
||||
if (!ret)
|
||||
ret = image_planar;
|
||||
else
|
||||
image->destroyImage(image_planar);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_in_fence(__DRIcontext *context, __DRIimage *img)
|
||||
{
|
||||
struct dri_context *ctx = dri_context(context);
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
struct pipe_fence_handle *fence;
|
||||
int fd = img->in_fence_fd;
|
||||
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
validate_fence_fd(fd);
|
||||
|
||||
img->in_fence_fd = -1;
|
||||
|
||||
pipe->create_fence_fd(pipe, &fence, fd, PIPE_FD_TYPE_NATIVE_SYNC);
|
||||
pipe->fence_server_sync(pipe, fence);
|
||||
pipe->screen->fence_reference(pipe->screen, &fence, NULL);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/** kopper_get_pixmap_buffer
|
||||
*
|
||||
* Get the DRM object for a pixmap from the X server and
|
||||
* wrap that with a __DRIimage structure using createImageFromFds
|
||||
*/
|
||||
static struct pipe_resource *
|
||||
kopper_get_pixmap_buffer(struct kopper_drawable *cdraw,
|
||||
enum pipe_format pf)
|
||||
{
|
||||
xcb_drawable_t pixmap;
|
||||
int width;
|
||||
int height;
|
||||
int format = get_dri_format(pf);
|
||||
__DRIscreen *cur_screen;
|
||||
struct kopper_loader_info *info = &cdraw->info;
|
||||
assert(info->bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
|
||||
xcb_connection_t *conn = info->xcb.connection;
|
||||
pixmap = info->xcb.window;
|
||||
|
||||
if (cdraw->image)
|
||||
return cdraw->image->texture;
|
||||
|
||||
/* FIXME: probably broken for OBS studio?
|
||||
* see dri3_get_pixmap_buffer()
|
||||
*/
|
||||
cur_screen = cdraw->base.sPriv;
|
||||
struct kopper_screen *kscreen = (struct kopper_screen*)cur_screen->driverPrivate;
|
||||
|
||||
#ifdef HAVE_DRI3_MODIFIERS
|
||||
if (kscreen->has_dmabuf) {
|
||||
xcb_dri3_buffers_from_pixmap_cookie_t bps_cookie;
|
||||
xcb_dri3_buffers_from_pixmap_reply_t *bps_reply;
|
||||
|
||||
bps_cookie = xcb_dri3_buffers_from_pixmap(conn, pixmap);
|
||||
bps_reply = xcb_dri3_buffers_from_pixmap_reply(conn, bps_cookie,
|
||||
NULL);
|
||||
if (!bps_reply)
|
||||
return NULL;
|
||||
cdraw->image =
|
||||
dri3_create_image_from_buffers(conn, bps_reply, format,
|
||||
cur_screen, &driVkImageExtension,
|
||||
cdraw);
|
||||
width = bps_reply->width;
|
||||
height = bps_reply->height;
|
||||
free(bps_reply);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
|
||||
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply;
|
||||
|
||||
bp_cookie = xcb_dri3_buffer_from_pixmap(conn, pixmap);
|
||||
bp_reply = xcb_dri3_buffer_from_pixmap_reply(conn, bp_cookie, NULL);
|
||||
if (!bp_reply)
|
||||
return NULL;
|
||||
|
||||
cdraw->image = dri3_create_image(conn, bp_reply, format,
|
||||
cur_screen, &driVkImageExtension,
|
||||
cdraw);
|
||||
width = bp_reply->width;
|
||||
height = bp_reply->height;
|
||||
free(bp_reply);
|
||||
}
|
||||
|
||||
cdraw->base.dPriv->w = width;
|
||||
cdraw->base.dPriv->h = height;
|
||||
|
||||
return cdraw->image->texture;
|
||||
}
|
||||
#endif //VK_USE_PLATFORM_XCB_KHR
|
||||
|
||||
static void
|
||||
kopper_allocate_textures(struct dri_context *ctx,
|
||||
struct dri_drawable *drawable,
|
||||
|
@ -215,6 +484,9 @@ kopper_allocate_textures(struct dri_context *ctx,
|
|||
const __DRIimageLoaderExtension *image = drawable->sPriv->image.loader;
|
||||
struct kopper_drawable *cdraw = (struct kopper_drawable *)drawable;
|
||||
|
||||
bool is_window = !cdraw->is_pixmap;
|
||||
bool is_pixmap = !is_window && cdraw->info.bos.sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
|
||||
|
||||
width = drawable->dPriv->w;
|
||||
height = drawable->dPriv->h;
|
||||
|
||||
|
@ -269,12 +541,16 @@ kopper_allocate_textures(struct dri_context *ctx,
|
|||
/* remove outdated textures */
|
||||
if (resized) {
|
||||
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
|
||||
if (drawable->textures[i] && i < ST_ATTACHMENT_DEPTH_STENCIL) {
|
||||
if (drawable->textures[i] && i < ST_ATTACHMENT_DEPTH_STENCIL && !is_pixmap) {
|
||||
drawable->textures[i]->width0 = width;
|
||||
drawable->textures[i]->height0 = height;
|
||||
} else
|
||||
pipe_resource_reference(&drawable->textures[i], NULL);
|
||||
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
|
||||
if (is_pixmap && i == ST_ATTACHMENT_FRONT_LEFT) {
|
||||
FREE(cdraw->image);
|
||||
cdraw->image = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -289,7 +565,16 @@ kopper_allocate_textures(struct dri_context *ctx,
|
|||
templ.depth0 = 1;
|
||||
templ.array_size = 1;
|
||||
templ.last_level = 0;
|
||||
bool is_window = !cdraw->is_pixmap;
|
||||
|
||||
#if 0
|
||||
XXX do this once swapinterval is hooked up
|
||||
/* pixmaps always have front buffers.
|
||||
* Exchange swaps also mandate fake front buffers.
|
||||
*/
|
||||
if (draw->type != LOADER_DRI3_DRAWABLE_WINDOW ||
|
||||
draw->swap_method == __DRI_ATTRIB_SWAP_EXCHANGE)
|
||||
buffer_mask |= __DRI_IMAGE_BUFFER_FRONT;
|
||||
#endif
|
||||
|
||||
uint32_t attachments = 0;
|
||||
for (i = 0; i < statts_count; i++)
|
||||
|
@ -326,9 +611,17 @@ kopper_allocate_textures(struct dri_context *ctx,
|
|||
assert(data);
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create_drawable(screen->base.screen, &templ, data);
|
||||
} else
|
||||
}
|
||||
#ifdef VK_USE_PLATFORM_XCB_KHR
|
||||
else if (is_pixmap && statts[i] == ST_ATTACHMENT_FRONT_LEFT) {
|
||||
drawable->textures[statts[i]] = kopper_get_pixmap_buffer(cdraw, format);
|
||||
handle_in_fence(ctx->cPriv, cdraw->image);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
drawable->textures[statts[i]] =
|
||||
screen->base.screen->resource_create(screen->base.screen, &templ);
|
||||
}
|
||||
}
|
||||
if (drawable->stvis.samples > 1 && !drawable->msaa_textures[statts[i]]) {
|
||||
templ.bind = templ.bind &
|
||||
|
|
Loading…
Reference in New Issue