summaryrefslogtreecommitdiff
path: root/src/gallium/winsys
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript5
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c43
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c2
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c83
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h5
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile1
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c195
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_screen.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c1
11 files changed, 307 insertions, 31 deletions
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
index e14e96e32f..6c00861f51 100644
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -2,11 +2,14 @@ Import('*')
env = drienv.Clone()
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
drivers = [
+ st_dri,
+ inteldrm,
softpipe,
i915simple,
trace,
- inteldrm
]
env.SharedLibrary(
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index c5217ad2d6..490baded66 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
DRIVER_SOURCES =
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
index d5e63c3bae..c4a79586e6 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -21,12 +21,10 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel)
batch->base.size = 0;
batch->base.actual_size = intel->device->max_batch_size;
batch->base.relocs = 0;
- batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/
+ batch->base.max_relocs = 100;/*INTEL_DEFAULT_RELOCS;*/
- batch->base.map = malloc(batch->base.actual_size);
- memset(batch->base.map, 0, batch->base.actual_size);
-
- batch->base.ptr = batch->base.map;
+ batch->intel = intel;
+ batch->device = intel->device;
intel_be_batchbuffer_reset(batch);
@@ -41,16 +39,17 @@ intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
+ batch->bo = drm_intel_bo_alloc(dev->pools.gem,
+ "gallium3d_batch_buffer",
+ batch->base.actual_size,
+ 4096);
+ drm_intel_bo_map(batch->bo, TRUE);
+ batch->base.map = batch->bo->virtual;
memset(batch->base.map, 0, batch->base.actual_size);
batch->base.ptr = batch->base.map;
batch->base.size = batch->base.actual_size - BATCH_RESERVED;
-
batch->base.relocs = 0;
-
- batch->bo = drm_intel_bo_alloc(dev->pools.gem,
- "gallium3d_batch_buffer",
- batch->base.actual_size, 0);
}
int
@@ -88,6 +87,7 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
struct i915_batchbuffer *i915 = &batch->base;
unsigned used = 0;
int ret = 0;
+ int i;
assert(i915_batchbuffer_space(i915) >= 0);
@@ -105,11 +105,29 @@ intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
used = batch->base.ptr - batch->base.map;
- drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
- ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+ drm_intel_bo_unmap(batch->bo);
+ /* Do the sending to HW */
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
assert(ret == 0);
+ if (batch->device->dump_cmd) {
+ unsigned *ptr;
+ drm_intel_bo_map(batch->bo, FALSE);
+ ptr = (unsigned*)batch->bo->virtual;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+
+ drm_intel_bo_unmap(batch->bo);
+ } else {
+ /* TODO figgure out why the gpu hangs if we don't run sync */
+ drm_intel_bo_map(batch->bo, FALSE);
+ drm_intel_bo_unmap(batch->bo);
+ }
+
intel_be_batchbuffer_reset(batch);
if (fence) {
@@ -134,6 +152,5 @@ intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
if (batch->bo)
drm_intel_bo_unreference(batch->bo);
- free(batch->base.map);
free(batch);
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
index db84f9af51..629987c6f9 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -36,7 +36,7 @@ intel_be_batch_reloc(struct i915_winsys *sws,
}
if (access_flags & I915_BUFFER_ACCESS_READ) {
- read |= I915_GEM_DOMAIN_VERTEX;
+ read |= I915_GEM_DOMAIN_SAMPLER;
}
ret = intel_be_offset_relocation(intel->batch,
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index e3630f5d12..5312865a03 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -7,6 +7,7 @@
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "util/u_debug.h"
+#include "util/u_math.h"
#include "intel_be_fence.h"
@@ -16,6 +17,8 @@
#include "intel_be_api.h"
#include <stdio.h>
+#define I915_TILING_X 1
+
/*
* Buffer
*/
@@ -25,9 +28,10 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
struct pipe_buffer *buf,
unsigned flags)
{
+ struct intel_be_buffer *buffer = intel_be_buffer(buf);
drm_intel_bo *bo = intel_bo(buf);
int write = 0;
- int ret;
+ int ret = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
/* Remove this when drm_intel_bo_map supports DONTBLOCK
@@ -38,19 +42,37 @@ intel_be_buffer_map(struct pipe_winsys *winsys,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
write = 1;
- ret = drm_intel_bo_map(bo, write);
+ if (buffer->map_count)
+ goto out;
+
+ if (buffer->map_gtt)
+ ret = drm_intel_gem_bo_map_gtt(bo);
+ else
+ ret = drm_intel_bo_map(bo, write);
+
+ buffer->ptr = bo->virtual;
+out:
if (ret)
return NULL;
- return bo->virtual;
+ buffer->map_count++;
+ return buffer->ptr;
}
static void
intel_be_buffer_unmap(struct pipe_winsys *winsys,
struct pipe_buffer *buf)
{
- drm_intel_bo_unmap(intel_bo(buf));
+ struct intel_be_buffer *buffer = intel_be_buffer(buf);
+
+ if (--buffer->map_count)
+ return;
+
+ if (buffer->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(intel_bo(buf));
+ else
+ drm_intel_bo_unmap(intel_bo(buf));
}
static void
@@ -80,8 +102,13 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
buffer->base.size = size;
buffer->flinked = FALSE;
buffer->flink = 0;
+ buffer->map_gtt = FALSE;
- if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
+ if (usage & I915_BUFFER_USAGE_SCANOUT) {
+ /* Scanout buffer */
+ name = "gallium3d_scanout";
+ pool = dev->pools.gem;
+ } else if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
/* Local buffer */
name = "gallium3d_local";
pool = dev->pools.gem;
@@ -96,6 +123,12 @@ intel_be_buffer_create(struct pipe_winsys *winsys,
}
buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+ if (usage & I915_BUFFER_USAGE_SCANOUT) {
+ unsigned tiling = I915_TILING_X;
+ unsigned stride = 2048 * 4; /* TODO do something smarter here */
+ drm_intel_bo_set_tiling(buffer->bo, &tiling, stride);
+ buffer->map_gtt = TRUE;
+ }
if (!buffer->bo)
goto err;
@@ -142,6 +175,40 @@ err:
return NULL;
}
+static struct pipe_buffer *
+intel_be_surface_buffer_create(struct pipe_winsys *winsys,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned tex_usage,
+ unsigned *stride)
+{
+ struct pipe_format_block block;
+ unsigned buf_usage = 0;
+ unsigned buf_stride = 0;
+ unsigned buf_size = 0;
+
+ pf_get_block(format, &block);
+ buf_stride = pf_get_stride(&block, width);
+ buf_stride = align(buf_stride, 64);
+
+ if (tex_usage & PIPE_TEXTURE_USAGE_PRIMARY) {
+ /* TODO more checks */
+ assert(buf_stride <= 2048*4);
+ assert(height % 8 == 0);
+ buf_stride = 2048 * 4;
+ buf_usage |= I915_BUFFER_USAGE_SCANOUT;
+ }
+
+ buf_size = buf_stride * height;
+ *stride = buf_stride;
+
+ return intel_be_buffer_create(winsys,
+ 0,
+ buf_usage,
+ buf_size);
+}
+
boolean
intel_be_get_texture_buffer(struct drm_api *api,
struct pipe_texture *texture,
@@ -225,6 +292,7 @@ intel_be_global_handle_from_buffer(struct drm_api *api,
*handle = buf->flink;
return TRUE;
}
+
/*
* Fence
*/
@@ -296,8 +364,8 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
dev->base.buffer_unmap = intel_be_buffer_unmap;
dev->base.buffer_destroy = intel_be_buffer_destroy;
- /* Not used anymore */
- dev->base.surface_buffer_create = NULL;
+ /* Used by softpipe */
+ dev->base.surface_buffer_create = intel_be_surface_buffer_create;
dev->base.fence_reference = intel_be_fence_refunref;
dev->base.fence_signalled = intel_be_fence_signalled;
@@ -308,6 +376,7 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
+ dev->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
return true;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
index 56d95bd7fe..c397048f8c 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -19,6 +19,7 @@ struct intel_be_device
struct pipe_winsys base;
boolean softpipe;
+ boolean dump_cmd;
int fd; /**< Drm file discriptor */
@@ -47,6 +48,10 @@ intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
struct intel_be_buffer {
struct pipe_buffer base;
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
drm_intel_bo *bo;
boolean flinked;
unsigned flink;
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile
index d51cca8d21..9e56853b02 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/winsys/drm/intel/xorg/Makefile
@@ -19,6 +19,7 @@ LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index e1ddcae97b..f409a3fd6b 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -82,6 +82,7 @@ struct xlib_egl_surface
{
_EGLSurface Base; /**< base class */
+ /* These are set for window surface */
Display *Dpy; /**< The X Display of the window */
Window Win; /**< The user-created window ID */
GC Gc;
@@ -101,7 +102,7 @@ xlib_egl_driver(_EGLDriver *drv)
}
-static struct xlib_egl_surface *
+static INLINE struct xlib_egl_surface *
lookup_surface(EGLSurface surf)
{
_EGLSurface *surface = _eglLookupSurface(surf);
@@ -109,10 +110,10 @@ lookup_surface(EGLSurface surf)
}
-static struct xlib_egl_context *
-lookup_context(EGLContext surf)
+static INLINE struct xlib_egl_context *
+lookup_context(EGLContext ctx)
{
- _EGLContext *context = _eglLookupContext(surf);
+ _EGLContext *context = _eglLookupContext(ctx);
return (struct xlib_egl_context *) context;
}
@@ -180,7 +181,9 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
- SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
_eglAddConfig(disp, config);
}
@@ -264,7 +267,13 @@ static void
check_and_update_buffer_size(struct xlib_egl_surface *surface)
{
uint width, height;
- get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ if (surface->Base.Type == EGL_PBUFFER_BIT) {
+ width = surface->Base.Width;
+ height = surface->Base.Height;
+ }
+ else {
+ get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ }
st_resize_framebuffer(surface->Framebuffer, width, height);
surface->Base.Width = width;
surface->Base.Height = height;
@@ -281,6 +290,9 @@ display_surface(struct pipe_winsys *pws,
XImage *ximage;
void *data;
+ if (xsurf->Base.Type == EGL_PBUFFER_BIT)
+ return;
+
ximage = XCreateImage(xsurf->Dpy,
xsurf->VisInfo.visual,
xsurf->VisInfo.depth,
@@ -382,7 +394,7 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
struct xlib_egl_context *context = lookup_context(ctx);
if (context) {
_eglUnlinkContext(&context->Base);
- if (!context->Base.IsBound) {
+ if (!_eglIsContextBound(&context->Base)) {
/* API-dependent clean-up */
switch (context->Base.ClientAPI) {
case EGL_OPENGL_ES_API:
@@ -415,10 +427,14 @@ xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy,
struct xlib_egl_context *context = lookup_context(ctx);
struct xlib_egl_surface *draw_surf = lookup_surface(draw);
struct xlib_egl_surface *read_surf = lookup_surface(read);
+ struct st_context *oldctx = st_get_current();
if (!_eglMakeCurrent(drv, dpy, draw, read, context))
return EGL_FALSE;
+ /* Flush before switching context. Check client API? */
+ if (oldctx)
+ st_flush(oldctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
st_make_current((context ? context->Context : NULL),
(draw_surf ? draw_surf->Framebuffer : NULL),
(read_surf ? read_surf->Framebuffer : NULL));
@@ -527,14 +543,92 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
}
+static EGLSurface
+xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+ struct xlib_egl_surface *surf;
+ __GLcontextModes visual;
+ uint width, height;
+ EGLBoolean bind_texture;
+
+ if (!disp) {
+ _eglError(EGL_BAD_DISPLAY, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ surf = CALLOC_STRUCT(xlib_egl_surface);
+ if (!surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
+ conf, attrib_list)) {
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ if (surf->Base.Width < 0 || surf->Base.Height < 0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+
+ bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE);
+ width = (uint) surf->Base.Width;
+ height = (uint) surf->Base.Height;
+ if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) ||
+ (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ /* a framebuffer of zero width or height confuses st */
+ if (width == 0 || height == 0) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+ /* no mipmap generation */
+ if (surf->Base.MipmapTexture) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return EGL_NO_SURFACE;
+ }
+
+ surf->winsys = xdrv->winsys;
+
+ _eglConfigToContextModesRec(conf, &visual);
+
+ /* Create GL statetracker framebuffer */
+ surf->Framebuffer = st_create_framebuffer(&visual,
+ choose_color_format(&visual),
+ choose_depth_format(&visual),
+ choose_stencil_format(&visual),
+ width, height,
+ (void *) surf);
+ st_resize_framebuffer(surf->Framebuffer, width, height);
+
+ return _eglLinkSurface(&surf->Base, disp);
+}
+
+
static EGLBoolean
xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct xlib_egl_surface *surf = lookup_surface(surface);
if (surf) {
_eglUnlinkSurface(&surf->Base);
- if (!surf->Base.IsBound) {
- XFreeGC(surf->Dpy, surf->Gc);
+ if (!_eglIsSurfaceBound(&surf->Base)) {
+ if (surf->Base.Type != EGL_PBUFFER_BIT)
+ XFreeGC(surf->Dpy, surf->Gc);
st_unreference_framebuffer(surf->Framebuffer);
free(surf);
}
@@ -548,6 +642,86 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
static EGLBoolean
+xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy,
+ EGLSurface surface, EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct xlib_egl_context *xctx;
+ struct pipe_surface *psurf;
+ enum pipe_format format;
+ int target;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT)
+ return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ if (xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+ /* this should be updated when choose_color_format is */
+ switch (xsurf->Base.TextureFormat) {
+ case EGL_TEXTURE_RGB:
+ format = PIPE_FORMAT_R8G8B8_UNORM;
+ break;
+ case EGL_TEXTURE_RGBA:
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ switch (xsurf->Base.TextureTarget) {
+ case EGL_TEXTURE_2D:
+ target = ST_TEXTURE_2D;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ /* flush properly */
+ if (eglGetCurrentSurface(EGL_DRAW) == surface) {
+ xctx = lookup_context(eglGetCurrentContext());
+ st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
+ NULL);
+ }
+ else if (_eglIsSurfaceBound(&xsurf->Base)) {
+ xctx = lookup_context(_eglGetContextHandle(xsurf->Base.Binding));
+ if (xctx)
+ st_finish(xctx->Context);
+ }
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format);
+ xsurf->Base.BoundToTexture = EGL_TRUE;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
+xlib_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+ EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct pipe_surface *psurf;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT ||
+ !xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel);
+ xsurf->Base.BoundToTexture = EGL_FALSE;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
/* error checking step: */
@@ -631,7 +805,10 @@ _eglMain(_EGLDisplay *dpy, const char *args)
xdrv->Base.API.CreateContext = xlib_eglCreateContext;
xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
+ xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface;
xdrv->Base.API.DestroySurface = xlib_eglDestroySurface;
+ xdrv->Base.API.BindTexImage = xlib_eglBindTexImage;
+ xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage;
xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
index aa1bfa8e88..79ff2cc985 100644
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -166,6 +166,7 @@ surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c
index fe8dfff767..6f3861e2cd 100644
--- a/src/gallium/winsys/xlib/xlib_brw_screen.c
+++ b/src/gallium/winsys/xlib/xlib_brw_screen.c
@@ -249,6 +249,7 @@ aub_i915_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 44b8464518..277e724d2a 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -375,6 +375,7 @@ xm_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;