summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/dri/drisw.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-10-09 01:38:08 +0100
committerDave Airlie <airlied@gmail.com>2015-10-31 16:04:36 +1000
commit2b676570960277d47477822ffeccc672613f9142 (patch)
tree84194de9b3e72ac548512b07c57e6a938d5efa19 /src/gallium/state_trackers/dri/drisw.c
parent103de0225b1e22aabc3e132ff30393765061ff03 (diff)
downloadexternal_mesa3d-2b676570960277d47477822ffeccc672613f9142.zip
external_mesa3d-2b676570960277d47477822ffeccc672613f9142.tar.gz
external_mesa3d-2b676570960277d47477822ffeccc672613f9142.tar.bz2
gallium/swrast: fix front buffer blitting. (v2)
So I've known this was broken before, cogl has a workaround for it from what I know, but with the gallium based swrast drivers BlitFramebuffer from back to front or vice-versa was pretty broken. The legacy swrast driver tracks when a front buffer is used and does the get/put images when it is mapped/unmapped, so this patch attempts to add the same functionality to the gallium drivers. It creates a new context interface to denote when a front buffer is being created, and passes a private pointer to it, this pointer is then used to decide on map/unmap if the contents should be updated from the real frontbuffer using get/put image. This is primarily to make gtk's gl code work, the only thing I've tested so far is the glarea test from https://github.com/ebassi/glarea-example.git v2: bump extension version, check extension version before calling get image. (Ian) Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91930 Cc: <mesa-stable@lists.freedesktop.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/gallium/state_trackers/dri/drisw.c')
-rw-r--r--src/gallium/state_trackers/dri/drisw.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
index 4ec6992..753c59d 100644
--- a/src/gallium/state_trackers/dri/drisw.c
+++ b/src/gallium/state_trackers/dri/drisw.c
@@ -95,6 +95,21 @@ get_image(__DRIdrawable *dPriv, int x, int y, int width, int height, void *data)
data, dPriv->loaderPrivate);
}
+static inline void
+get_image2(__DRIdrawable *dPriv, int x, int y, int width, int height, int stride, void *data)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
+
+ /* getImage2 support is only in version 3 or newer */
+ if (loader->base.version < 3)
+ return;
+
+ loader->getImage2(dPriv,
+ x, y, width, height, stride,
+ data, dPriv->loaderPrivate);
+}
+
static void
drisw_update_drawable_info(struct dri_drawable *drawable)
{
@@ -105,6 +120,18 @@ drisw_update_drawable_info(struct dri_drawable *drawable)
}
static void
+drisw_get_image(struct dri_drawable *drawable,
+ int x, int y, unsigned width, unsigned height, unsigned stride,
+ void *data)
+{
+ __DRIdrawable *dPriv = drawable->dPriv;
+ int draw_x, draw_y, draw_w, draw_h;
+
+ get_drawable_info(dPriv, &draw_x, &draw_y, &draw_w, &draw_h);
+ get_image2(dPriv, x, y, draw_w, draw_h, stride, data);
+}
+
+static void
drisw_put_image(struct dri_drawable *drawable,
void *data, unsigned width, unsigned height)
{
@@ -236,6 +263,7 @@ drisw_allocate_textures(struct dri_context *stctx,
unsigned count)
{
struct dri_screen *screen = dri_screen(drawable->sPriv);
+ const __DRIswrastLoaderExtension *loader = drawable->dPriv->driScreenPriv->swrast_loader;
struct pipe_resource templ;
unsigned width, height;
boolean resized;
@@ -281,8 +309,14 @@ drisw_allocate_textures(struct dri_context *stctx,
templ.format = format;
templ.bind = bind;
- drawable->textures[statts[i]] =
- screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (statts[i] == ST_ATTACHMENT_FRONT_LEFT &&
+ screen->base.screen->resource_create_front &&
+ loader->base.version >= 3) {
+ drawable->textures[statts[i]] =
+ screen->base.screen->resource_create_front(screen->base.screen, &templ, (const void *)drawable);
+ } else
+ drawable->textures[statts[i]] =
+ screen->base.screen->resource_create(screen->base.screen, &templ);
}
drawable->old_w = width;
@@ -338,6 +372,7 @@ static const __DRIextension *drisw_screen_extensions[] = {
};
static struct drisw_loader_funcs drisw_lf = {
+ .get_image = drisw_get_image,
.put_image = drisw_put_image,
.put_image2 = drisw_put_image2
};