gallium/xlib: Partial fix for glXCopySubBufferMESA

xmesa_copy_st_framebuffer would attempt to flush from the front buffer
to the display, but we don't actually have an attachment for the front
buffer (just the back) so nothing would happen. Fix this by flushing
fron the back to the display, threading the dirty box through so we
don't update more than we were told to.

This has the virtue of displaying correctly, but glx-copy-sub-buffer
still fails since there is no real front buffer, reads from GL_FRONT
actually read from the back buffer. The test does: clear to red, swap,
clear to green, copy sub-buffer, expect a green square inside of a red
one from the front buffer. Since you're really reading from the back you
instead get solid green.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9140>
This commit is contained in:
Adam Jackson
2021-02-17 15:55:26 -05:00
committed by Marge Bot
parent 6635a47038
commit 292d45497f
2 changed files with 28 additions and 10 deletions

View File

@@ -60,7 +60,8 @@ xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
static bool
xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
struct st_context_iface *stctx,
enum st_attachment_type statt)
enum st_attachment_type statt,
struct pipe_box *box)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_resource *ptex = xstfb->textures[statt];
@@ -77,7 +78,7 @@ xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
pres = xstfb->display_resource;
}
xstfb->screen->flush_frontbuffer(xstfb->screen, pctx, pres, 0, 0, &xstfb->buffer->ws, NULL);
xstfb->screen->flush_frontbuffer(xstfb->screen, pctx, pres, 0, 0, &xstfb->buffer->ws, box);
return true;
}
@@ -267,7 +268,7 @@ xmesa_st_framebuffer_flush_front(struct st_context_iface *stctx,
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
bool ret;
ret = xmesa_st_framebuffer_display(stfbi, stctx, statt);
ret = xmesa_st_framebuffer_display(stfbi, stctx, statt, NULL);
if (ret && xmesa_strict_invalidate)
xmesa_check_buffer_size(xstfb->buffer);
@@ -349,7 +350,7 @@ xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
bool ret;
ret = xmesa_st_framebuffer_display(stfbi, NULL, ST_ATTACHMENT_BACK_LEFT);
ret = xmesa_st_framebuffer_display(stfbi, NULL, ST_ATTACHMENT_BACK_LEFT, NULL);
if (ret) {
struct pipe_resource **front, **back, *tmp;
@@ -379,8 +380,15 @@ xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
int x, int y, int w, int h)
{
xmesa_st_framebuffer_copy_textures(stfbi, src, dst, x, y, w, h);
if (dst == ST_ATTACHMENT_FRONT_LEFT)
xmesa_st_framebuffer_display(stfbi, NULL, dst);
if (dst == ST_ATTACHMENT_FRONT_LEFT) {
struct pipe_box box = {};
box.x = x;
box.y = y;
box.width = w;
box.height = h;
xmesa_st_framebuffer_display(stfbi, NULL, src, &box);
}
}

View File

@@ -295,13 +295,15 @@ xlib_displaytarget_destroy(struct sw_winsys *ws,
*/
static void
xlib_sw_display(struct xlib_drawable *xlib_drawable,
struct sw_displaytarget *dt)
struct sw_displaytarget *dt,
struct pipe_box *box)
{
static bool no_swap = false;
static bool firsttime = true;
struct xlib_displaytarget *xlib_dt = xlib_displaytarget(dt);
Display *display = xlib_dt->display;
XImage *ximage;
struct pipe_box _box = {};
if (firsttime) {
no_swap = getenv("SP_NO_RAST") != NULL;
@@ -311,6 +313,12 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
if (no_swap)
return;
if (!box) {
_box.width = xlib_dt->width;
_box.height = xlib_dt->height;
box = &_box;
}
if (xlib_dt->drawable != xlib_drawable->drawable) {
if (xlib_dt->gc) {
XFreeGC(display, xlib_dt->gc);
@@ -346,7 +354,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
/* _debug_printf("XSHM\n"); */
XShmPutImage(xlib_dt->display, xlib_drawable->drawable, xlib_dt->gc,
ximage, 0, 0, 0, 0, xlib_dt->width, xlib_dt->height, False);
ximage, box->x, box->y, box->x, box->y,
box->width, box->height, False);
}
else {
/* display image in Window */
@@ -364,7 +373,8 @@ xlib_sw_display(struct xlib_drawable *xlib_drawable,
/* _debug_printf("XPUT\n"); */
XPutImage(xlib_dt->display, xlib_drawable->drawable, xlib_dt->gc,
ximage, 0, 0, 0, 0, xlib_dt->width, xlib_dt->height);
ximage, box->x, box->y, box->x, box->y,
box->width, box->height);
}
XFlush(xlib_dt->display);
@@ -382,7 +392,7 @@ xlib_displaytarget_display(struct sw_winsys *ws,
struct pipe_box *box)
{
struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
xlib_sw_display(xlib_drawable, dt);
xlib_sw_display(xlib_drawable, dt, box);
}