summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers
diff options
context:
space:
mode:
authorMichal Krol <[email protected]>2010-03-10 15:49:30 +0100
committerMichal Krol <[email protected]>2010-03-10 15:49:30 +0100
commit3ce4375912c8ea488460e593e07c5bb15b92dca9 (patch)
tree1011fa439bd829fd46a44fd99478135848800e73 /src/gallium/state_trackers
parentf59f28093ea827bd234d8e1a36bdd56a9fce5f09 (diff)
parent9b348d0ed125a22be3f318ac60cef6f201edfdab (diff)
Merge branch 'master' into gallium-sampler-view
Conflicts: src/gallium/auxiliary/Makefile src/gallium/auxiliary/SConscript src/gallium/auxiliary/tgsi/tgsi_exec.c src/gallium/auxiliary/util/u_blitter.c src/gallium/drivers/i915/i915_context.h src/gallium/drivers/i965/brw_context.h src/gallium/drivers/llvmpipe/lp_context.h src/gallium/drivers/nv50/nv50_context.h src/gallium/drivers/nv50/nv50_state_validate.c src/gallium/drivers/nv50/nv50_tex.c src/gallium/drivers/r300/r300_blit.c src/gallium/drivers/r300/r300_context.h src/gallium/drivers/r300/r300_emit.c src/gallium/drivers/r300/r300_state.c src/gallium/drivers/softpipe/sp_context.h src/gallium/drivers/svga/svga_context.h src/gallium/drivers/svga/svga_pipe_sampler.c
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c12
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c30
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c14
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c301
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h14
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c136
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.h41
-rw-r--r--src/gallium/state_trackers/egl/common/native.h91
-rw-r--r--src/gallium/state_trackers/egl/common/native_modeset.h87
-rw-r--r--src/gallium/state_trackers/egl/common/st_public_tmp.h2
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c56
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h2
-rw-r--r--src/gallium/state_trackers/egl/x11/native_dri2.c510
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.c9
-rw-r--r--src/gallium/state_trackers/egl/x11/native_x11.h7
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c476
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.c231
-rw-r--r--src/gallium/state_trackers/egl/x11/sw_winsys.h40
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c68
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.h10
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript2
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c53
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_usefont.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c249
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h19
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_public.h (renamed from src/gallium/state_trackers/glx/xlib/xm_winsys.h)16
-rw-r--r--src/gallium/state_trackers/python/README2
-rw-r--r--src/gallium/state_trackers/python/SConscript31
-rw-r--r--src/gallium/state_trackers/python/p_context.i8
-rw-r--r--src/gallium/state_trackers/python/st_device.c54
-rw-r--r--src/gallium/state_trackers/python/st_device.h9
-rw-r--r--src/gallium/state_trackers/python/st_hardpipe_winsys.c16
-rw-r--r--src/gallium/state_trackers/python/st_llvmpipe_winsys.c141
-rw-r--r--src/gallium/state_trackers/python/st_sample.c2
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c55
-rw-r--r--src/gallium/state_trackers/python/st_winsys.h14
-rw-r--r--src/gallium/state_trackers/vega/Makefile2
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c2
-rw-r--r--src/gallium/state_trackers/vega/api_masks.c2
-rw-r--r--src/gallium/state_trackers/vega/image.c10
-rw-r--r--src/gallium/state_trackers/vega/mask.c2
-rw-r--r--src/gallium/state_trackers/vega/paint.c5
-rw-r--r--src/gallium/state_trackers/vega/polygon.c4
-rw-r--r--src/gallium/state_trackers/vega/renderer.c5
-rw-r--r--src/gallium/state_trackers/vega/vg_context.c8
-rw-r--r--src/gallium/state_trackers/vega/vg_context.h1
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c20
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h3
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c18
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c19
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c24
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c17
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c22
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c170
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c20
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c13
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h18
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c4
62 files changed, 1706 insertions, 1511 deletions
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 908cef454e9..2f991c39e33 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -128,7 +128,7 @@ dri_unbind_context(__DRIcontext * cPriv)
if (--ctx->bind_count == 0) {
if (ctx->st && ctx->st == st_get_current()) {
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- st_make_current(NULL, NULL, NULL);
+ st_make_current(NULL, NULL, NULL, NULL);
}
}
}
@@ -161,7 +161,13 @@ dri_make_current(__DRIcontext * cPriv,
ctx->r_stamp = driReadPriv->lastStamp - 1;
}
- st_make_current(ctx->st, draw->stfb, read->stfb);
+ /* DRI co-state tracker currently overrides flush_frontbuffer.
+ * When this is fixed, will need to pass the drawable in the
+ * fourth parameter here so that when Mesa calls
+ * flush_frontbuffer directly (in front-buffer rendering), it
+ * will have access to the drawable argument:
+ */
+ st_make_current(ctx->st, draw->stfb, read->stfb, NULL);
if (__dri1_api_hooks) {
dri1_update_drawables(ctx, draw, read);
@@ -170,7 +176,7 @@ dri_make_current(__DRIcontext * cPriv,
ctx->pipe->priv);
}
} else {
- st_make_current(NULL, NULL, NULL);
+ st_make_current(NULL, NULL, NULL, NULL);
}
return GL_TRUE;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 195ae7b8bc2..458473853cf 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -58,6 +58,7 @@ dri_surface_from_handle(struct drm_api *api,
struct pipe_surface *surface = NULL;
struct pipe_texture *texture = NULL;
struct pipe_texture templat;
+ struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -68,8 +69,11 @@ dri_surface_from_handle(struct drm_api *api,
templat.width0 = width;
templat.height0 = height;
- texture = api->texture_from_shared_handle(api, screen, &templat,
- "dri2 buffer", pitch, handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.handle = handle;
+ whandle.stride = pitch;
+
+ texture = screen->texture_from_handle(screen, &templat, &whandle);
if (!texture) {
debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
@@ -134,12 +138,13 @@ dri_get_buffers(__DRIdrawable * dPriv)
if ((dri_screen->dri2.loader
&& (dri_screen->dri2.loader->base.version > 2)
- && (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
+ && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) {
buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
(dri_drawable, &dri_drawable->w, &dri_drawable->h,
drawable->attachments, drawable->num_attachments,
&count, dri_drawable->loaderPrivate);
- else
+ } else {
+ assert(dri_screen->dri2.loader);
buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
&dri_drawable->w,
&dri_drawable->h,
@@ -148,6 +153,7 @@ dri_get_buffers(__DRIdrawable * dPriv)
num_attachments, &count,
dri_drawable->
loaderPrivate);
+ }
if (buffers == NULL) {
return;
@@ -288,8 +294,6 @@ dri_update_buffer(struct pipe_screen *screen, void *context_private)
ctx->r_stamp == *ctx->rPriv->pStamp)
return;
- st_flush(ctx->st, PIPE_FLUSH_FRAME, NULL);
-
ctx->d_stamp = *ctx->dPriv->pStamp;
ctx->r_stamp = *ctx->rPriv->pStamp;
@@ -349,11 +353,11 @@ dri_create_buffer(__DRIscreen * sPriv,
if (visual->redBits == 8) {
if (visual->alphaBits == 8)
- drawable->color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
else
- drawable->color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
} else {
- drawable->color_format = PIPE_FORMAT_R5G6B5_UNORM;
+ drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM;
}
switch(visual->depthBits) {
@@ -367,12 +371,12 @@ dri_create_buffer(__DRIscreen * sPriv,
case 24:
if (visual->stencilBits == 0) {
drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
- PIPE_FORMAT_X8Z24_UNORM:
- PIPE_FORMAT_Z24X8_UNORM;
+ PIPE_FORMAT_Z24X8_UNORM:
+ PIPE_FORMAT_X8Z24_UNORM;
} else {
drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
- PIPE_FORMAT_S8Z24_UNORM:
- PIPE_FORMAT_Z24S8_UNORM;
+ PIPE_FORMAT_Z24S8_UNORM:
+ PIPE_FORMAT_S8Z24_UNORM;
}
break;
case 32:
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 77d640227fb..60bc560049c 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -109,22 +109,22 @@ dri_fill_in_modes(struct dri_screen *screen,
stencil_bits_array[0] = 0;
depth_buffer_factor = 1;
- pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
+ pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
+ pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM,
+ pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+ pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
+ pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
- pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM,
+ pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
@@ -139,7 +139,7 @@ dri_fill_in_modes(struct dri_screen *screen,
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
- pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
+ pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
} else {
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 80dd1269955..e4972d493d6 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -36,6 +36,7 @@
#include "native.h"
#include "egl_g3d.h"
+#include "egl_g3d_image.h"
#include "egl_st.h"
/**
@@ -508,35 +509,33 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
}
/**
- * Flush the front buffer of the context's draw surface.
+ * Re-validate the context.
*/
static void
-egl_g3d_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf, void *context_private)
+egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
{
struct egl_g3d_context *gctx = egl_g3d_context(context_private);
- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface);
-
- if (gsurf)
- gsurf->native->flush_frontbuffer(gsurf->native);
+ egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
}
-/**
- * Re-validate the context.
- */
static void
-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
+egl_g3d_invalid_surface(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num)
{
- struct egl_g3d_context *gctx = egl_g3d_context(context_private);
+ /* XXX not thread safe? */
+ struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+ struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
- /**
- * It is likely that the surface has changed when this function is called.
- * Set force_validate to skip an unnecessary check.
- */
- gctx->force_validate = EGL_TRUE;
- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
+ /* set force_validate to skip an unnecessary check */
+ if (gctx)
+ gctx->force_validate = TRUE;
}
+static struct native_event_handler egl_g3d_native_event_handler = {
+ .invalid_surface = egl_g3d_invalid_surface
+};
+
static EGLBoolean
egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
@@ -581,31 +580,36 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
}
dpy->DriverData = gdpy;
- gdpy->native = native_create_display(dpy->NativeDisplay);
+ gdpy->native = native_create_display(dpy->NativeDisplay,
+ &egl_g3d_native_event_handler);
if (!gdpy->native) {
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
goto fail;
}
- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
+ gdpy->native->user_data = (void *) dpy;
gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
egl_g3d_init_st(&gdrv->base);
dpy->ClientAPIsMask = gdrv->api_mask;
- if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
- _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
- goto fail;
- }
-
#ifdef EGL_MESA_screen_surface
- /* enable MESA_screen_surface */
+ /* enable MESA_screen_surface before adding (and validating) configs */
if (gdpy->native->modeset) {
dpy->Extensions.MESA_screen_surface = EGL_TRUE;
egl_g3d_add_screens(drv, dpy);
}
#endif
+ dpy->Extensions.KHR_image_base = EGL_TRUE;
+ if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_USE_NATIVE_BUFFER))
+ dpy->Extensions.KHR_image_pixmap = EGL_TRUE;
+
+ if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
+ _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
+ goto fail;
+ }
+
*major = 1;
*minor = 4;
@@ -693,131 +697,144 @@ egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
return EGL_TRUE;
}
-static EGLBoolean
-init_surface_geometry(_EGLSurface *surf)
-{
- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
-
- return gsurf->native->validate(gsurf->native, 0x0,
- &gsurf->sequence_number, NULL,
- &gsurf->base.Width, &gsurf->base.Height);
-}
+struct egl_g3d_create_surface_arg {
+ EGLint type;
+ union {
+ EGLNativeWindowType win;
+ EGLNativePixmapType pix;
+ } u;
+};
static _EGLSurface *
-egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, EGLNativeWindowType win,
- const EGLint *attribs)
+egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ struct egl_g3d_create_surface_arg *arg,
+ const EGLint *attribs)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_surface *gsurf;
+ struct native_surface *nsurf;
+ const char *err;
+
+ switch (arg->type) {
+ case EGL_WINDOW_BIT:
+ err = "eglCreateWindowSurface";
+ break;
+ case EGL_PIXMAP_BIT:
+ err = "eglCreatePixmapSurface";
+ break;
+ case EGL_PBUFFER_BIT:
+ err = "eglCreatePBufferSurface";
+ break;
+#ifdef EGL_MESA_screen_surface
+ case EGL_SCREEN_BIT_MESA:
+ err = "eglCreateScreenSurface";
+ break;
+#endif
+ default:
+ err = "eglCreateUnknownSurface";
+ break;
+ }
gsurf = CALLOC_STRUCT(egl_g3d_surface);
if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ _eglError(EGL_BAD_ALLOC, err);
return NULL;
}
- if (!_eglInitSurface(&gsurf->base, dpy, EGL_WINDOW_BIT, conf, attribs)) {
+ if (!_eglInitSurface(&gsurf->base, dpy, arg->type, conf, attribs)) {
free(gsurf);
return NULL;
}
- gsurf->native =
- gdpy->native->create_window_surface(gdpy->native, win, gconf->native);
- if (!gsurf->native) {
+ /* create the native surface */
+ switch (arg->type) {
+ case EGL_WINDOW_BIT:
+ nsurf = gdpy->native->create_window_surface(gdpy->native,
+ arg->u.win, gconf->native);
+ break;
+ case EGL_PIXMAP_BIT:
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ arg->u.pix, gconf->native);
+ break;
+ case EGL_PBUFFER_BIT:
+ nsurf = gdpy->native->create_pbuffer_surface(gdpy->native,
+ gconf->native, gsurf->base.Width, gsurf->base.Height);
+ break;
+#ifdef EGL_MESA_screen_surface
+ case EGL_SCREEN_BIT_MESA:
+ /* prefer back buffer (move to _eglInitSurface?) */
+ gsurf->base.RenderBuffer = EGL_BACK_BUFFER;
+ nsurf = gdpy->native->modeset->create_scanout_surface(gdpy->native,
+ gconf->native, gsurf->base.Width, gsurf->base.Height);
+ break;
+#endif
+ default:
+ nsurf = NULL;
+ break;
+ }
+
+ if (!nsurf) {
free(gsurf);
return NULL;
}
-
- if (!init_surface_geometry(&gsurf->base)) {
- gsurf->native->destroy(gsurf->native);
+ /* initialize the geometry */
+ if (!nsurf->validate(nsurf, 0x0, &gsurf->sequence_number, NULL,
+ &gsurf->base.Width, &gsurf->base.Height)) {
+ nsurf->destroy(nsurf);
free(gsurf);
return NULL;
}
- gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER ||
- !gconf->native->mode.doubleBufferMode) ?
+ nsurf->user_data = &gsurf->base;
+ gsurf->native = nsurf;
+
+ gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+ if (!gconf->native->mode.doubleBufferMode)
+ gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
return &gsurf->base;
}
static _EGLSurface *
-egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, EGLNativePixmapType pix,
+egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativeWindowType win,
const EGLint *attribs)
{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- struct egl_g3d_surface *gsurf;
+ struct egl_g3d_create_surface_arg arg;
- gsurf = CALLOC_STRUCT(egl_g3d_surface);
- if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface");
- return NULL;
- }
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_WINDOW_BIT;
+ arg.u.win = win;
- if (!_eglInitSurface(&gsurf->base, dpy, EGL_PIXMAP_BIT, conf, attribs)) {
- free(gsurf);
- return NULL;
- }
-
- gsurf->native =
- gdpy->native->create_pixmap_surface(gdpy->native, pix, gconf->native);
- if (!gsurf->native) {
- free(gsurf);
- return NULL;
- }
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
+}
- if (!init_surface_geometry(&gsurf->base)) {
- gsurf->native->destroy(gsurf->native);
- free(gsurf);
- return NULL;
- }
+static _EGLSurface *
+egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, EGLNativePixmapType pix,
+ const EGLint *attribs)
+{
+ struct egl_g3d_create_surface_arg arg;
- gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT;
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_PIXMAP_BIT;
+ arg.u.pix = pix;
- return &gsurf->base;
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
static _EGLSurface *
egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const EGLint *attribs)
{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- struct egl_g3d_surface *gsurf;
-
- gsurf = CALLOC_STRUCT(egl_g3d_surface);
- if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
- return NULL;
- }
-
- if (!_eglInitSurface(&gsurf->base, dpy, EGL_PBUFFER_BIT, conf, attribs)) {
- free(gsurf);
- return NULL;
- }
-
- gsurf->native =
- gdpy->native->create_pbuffer_surface(gdpy->native, gconf->native,
- gsurf->base.Width, gsurf->base.Height);
- if (!gsurf->native) {
- free(gsurf);
- return NULL;
- }
+ struct egl_g3d_create_surface_arg arg;
- if (!init_surface_geometry(&gsurf->base)) {
- gsurf->native->destroy(gsurf->native);
- free(gsurf);
- return NULL;
- }
-
- gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_PBUFFER_BIT;
- return &gsurf->base;
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
/**
@@ -875,8 +892,13 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
if (gctx) {
ok = egl_g3d_realloc_context(dpy, &gctx->base);
if (ok) {
+ /* XXX: need to pass the winsys argument for
+ * flush_frontbuffer in the fourth parameter here:
+ */
ok = gctx->stapi->st_make_current(gctx->st_ctx,
- gctx->draw.st_fb, gctx->read.st_fb);
+ gctx->draw.st_fb,
+ gctx->read.st_fb,
+ NULL);
if (ok) {
egl_g3d_validate_context(dpy, &gctx->base);
if (gdraw->base.Type == EGL_WINDOW_BIT) {
@@ -888,7 +910,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy,
}
}
else if (old_gctx) {
- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL);
+ ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL, NULL);
old_gctx->base.WindowRenderBuffer = EGL_NONE;
}
@@ -925,32 +947,14 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
if (gctx)
gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb);
- /*
- * We drew on the back buffer, unless there was no back buffer.
- * In that case, we drew on the front buffer. Either case, we call
- * swap_buffers.
- */
- if (!gsurf->native->swap_buffers(gsurf->native))
- return EGL_FALSE;
-
- if (gctx) {
- struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config);
-
- /* force validation if the swap method is not copy */
- if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) {
- gctx->force_validate = EGL_TRUE;
- egl_g3d_validate_context(dpy, &gctx->base);
- }
- }
-
- return EGL_TRUE;
+ return gsurf->native->swap_buffers(gsurf->native);
}
/**
* Find a config that supports the pixmap.
*/
-static _EGLConfig *
-find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
+_EGLConfig *
+egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
{
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
struct egl_g3d_config *gconf;
@@ -1002,7 +1006,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
if (!gsurf->render_surface)
return EGL_TRUE;
- gconf = egl_g3d_config(find_pixmap_config(dpy, target));
+ gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, target));
if (!gconf)
return _eglError(EGL_BAD_NATIVE_PIXMAP, "eglCopyBuffers");
@@ -1109,7 +1113,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy,
target_format = PIPE_FORMAT_R8G8B8_UNORM;
break;
case EGL_TEXTURE_RGBA:
- target_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ target_format = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
default:
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
@@ -1177,34 +1181,12 @@ static _EGLSurface *
egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy,
_EGLConfig *conf, const EGLint *attribs)
{
- struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
- struct egl_g3d_config *gconf = egl_g3d_config(conf);
- struct egl_g3d_surface *gsurf;
+ struct egl_g3d_create_surface_arg arg;
- gsurf = CALLOC_STRUCT(egl_g3d_surface);
- if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
- return NULL;
- }
+ memset(&arg, 0, sizeof(arg));
+ arg.type = EGL_SCREEN_BIT_MESA;
- if (!_eglInitSurface(&gsurf->base, dpy,
- EGL_SCREEN_BIT_MESA, conf, attribs)) {
- free(gsurf);
- return NULL;
- }
-
- gsurf->native =
- gdpy->native->modeset->create_scanout_surface(gdpy->native,
- gconf->native, gsurf->base.Width, gsurf->base.Height);
- if (!gsurf->native) {
- free(gsurf);
- return NULL;
- }
-
- gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ?
- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT;
-
- return &gsurf->base;
+ return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
static EGLBoolean
@@ -1335,6 +1317,9 @@ _eglMain(const char *args)
gdrv->base.API.BindTexImage = egl_g3d_bind_tex_image;
gdrv->base.API.ReleaseTexImage = egl_g3d_release_tex_image;
+ gdrv->base.API.CreateImageKHR = egl_g3d_create_image;
+ gdrv->base.API.DestroyImageKHR = egl_g3d_destroy_image;
+
#ifdef EGL_MESA_screen_surface
gdrv->base.API.CreateScreenSurfaceMESA = egl_g3d_create_screen_surface;
gdrv->base.API.ShowScreenSurfaceMESA = egl_g3d_show_screen_surface;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 5d2d9c481ab..e3e55e46d3b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -34,6 +34,7 @@
#include "eglcontext.h"
#include "eglsurface.h"
#include "eglconfig.h"
+#include "eglimage.h"
#include "eglscreen.h"
#include "eglmode.h"
@@ -81,6 +82,14 @@ struct egl_g3d_config {
const struct native_config *native;
};
+struct egl_g3d_image {
+ _EGLImage base;
+ struct pipe_texture *texture;
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
+};
+
struct egl_g3d_screen {
_EGLScreen base;
const struct native_connector *native;
@@ -90,5 +99,10 @@ struct egl_g3d_screen {
/* standard typecasts */
_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d)
_EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj)
+_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj)
+
+
+_EGLConfig *
+egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix);
#endif /* _EGL_G3D_H_ */
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
new file mode 100644
index 00000000000..d701f9c9a88
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -0,0 +1,136 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#include <assert.h>
+#include "pipe/p_screen.h"
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_inlines.h"
+#include "eglcurrent.h"
+#include "egllog.h"
+
+#include "native.h"
+#include "egl_g3d.h"
+#include "egl_g3d_image.h"
+
+/**
+ * Reference and return the front left buffer of the native pixmap.
+ */
+static struct pipe_texture *
+egl_g3d_reference_native_pixmap(_EGLDisplay *dpy, EGLNativePixmapType pix)
+{
+ struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+ struct egl_g3d_config *gconf;
+ struct native_surface *nsurf;
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ enum native_attachment natt;
+
+ gconf = egl_g3d_config(egl_g3d_find_pixmap_config(dpy, pix));
+ if (!gconf)
+ return NULL;
+
+ nsurf = gdpy->native->create_pixmap_surface(gdpy->native,
+ pix, gconf->native);
+ if (!nsurf)
+ return NULL;
+
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ if (!nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL))
+ textures[natt] = NULL;
+
+ nsurf->destroy(nsurf);
+
+ return textures[natt];
+}
+
+_EGLImage *
+egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
+ EGLenum target, EGLClientBuffer buffer,
+ const EGLint *attribs)
+{
+ struct pipe_texture *ptex;
+ struct egl_g3d_image *gimg;
+ unsigned face = 0, level = 0, zslice = 0;
+
+ gimg = CALLOC_STRUCT(egl_g3d_image);
+ if (!gimg) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&gimg->base, dpy, attribs)) {
+ free(gimg);
+ return NULL;
+ }
+
+ switch (target) {
+ case EGL_NATIVE_PIXMAP_KHR:
+ ptex = egl_g3d_reference_native_pixmap(dpy,
+ (EGLNativePixmapType) buffer);
+ break;
+ default:
+ ptex = NULL;
+ break;
+ }
+
+ if (!ptex) {
+ free(gimg);
+ return NULL;
+ }
+
+ if (level > ptex->last_level) {
+ _eglError(EGL_BAD_MATCH, "eglCreateEGLImageKHR");
+ pipe_texture_reference(&gimg->texture, NULL);
+ free(gimg);
+ return NULL;
+ }
+ if (zslice > ptex->depth0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ pipe_texture_reference(&gimg->texture, NULL);
+ free(gimg);
+ return NULL;
+ }
+
+ /* transfer the ownership to the image */
+ gimg->texture = ptex;
+ gimg->face = face;
+ gimg->level = level;
+ gimg->zslice = zslice;
+
+ return &gimg->base;
+}
+
+EGLBoolean
+egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img)
+{
+ struct egl_g3d_image *gimg = egl_g3d_image(img);
+
+ pipe_texture_reference(&gimg->texture, NULL);
+ free(gimg);
+
+ return EGL_TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.h b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
new file mode 100644
index 00000000000..c199c466456
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.h
@@ -0,0 +1,41 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <[email protected]>
+ */
+
+#ifndef _EGL_G3D_IMAGE_H_
+#define _EGL_G3D_IMAGE_H_
+
+#include "egl_g3d.h"
+
+_EGLImage *
+egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
+ EGLenum target, EGLClientBuffer buffer,
+ const EGLint *attribs);
+
+EGLBoolean
+egl_g3d_destroy_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image);
+
+#endif /* _EGL_G3D_IMAGE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 4f9758545ab..93c81b26e10 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -34,6 +34,8 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "native_modeset.h"
+
/**
* Only color buffers are listed. The others are allocated privately through,
* for example, st_renderbuffer_alloc_storage().
@@ -47,6 +49,14 @@ enum native_attachment {
NUM_NATIVE_ATTACHMENTS
};
+enum native_param_type {
+ /*
+ * Return TRUE if window/pixmap surfaces use the buffers of the native
+ * types.
+ */
+ NATIVE_PARAM_USE_NATIVE_BUFFER
+};
+
/**
* Enumerations for probe results.
*/
@@ -69,6 +79,11 @@ struct native_probe {
};
struct native_surface {
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_surface *nsurf);
/**
@@ -117,18 +132,6 @@ struct native_config {
boolean scanout_bit;
};
-struct native_connector {
- int dummy;
-};
-
-struct native_mode {
- const char *desc;
- int width, height;
- int refresh_rate;
-};
-
-struct native_display_modeset;
-
/**
* A pipe winsys abstracts the OS. A pipe screen abstracts the graphcis
* hardware. A native display consists of a pipe winsys, a pipe screen, and
@@ -137,15 +140,25 @@ struct native_display_modeset;
struct native_display {
/**
* The pipe screen of the native display.
- *
- * Note that the "flush_frontbuffer" and "update_buffer" callbacks will be
- * overridden.
*/
struct pipe_screen *screen;
+ /**
+ * Available for caller's use.
+ */
+ void *user_data;
+
void (*destroy)(struct native_display *ndpy);
/**
+ * Query the parameters of the native display.
+ *
+ * The return value is defined by the parameter.
+ */
+ int (*get_param)(struct native_display *ndpy,
+ enum native_param_type param);
+
+ /**
* Get the supported configs. The configs are owned by the display, but
* the returned array should be free()ed.
*
@@ -196,46 +209,17 @@ struct native_display {
};
/**
- * Mode setting interface of the native display. It exposes the mode setting
- * capabilities of the underlying graphics hardware.
+ * The handler for events that a native display may generate. The events are
+ * generated asynchronously and the handler may be called by any thread at any
+ * time.
*/
-struct native_display_modeset {
- /**
- * Get the available physical connectors and the number of CRTCs.
- */
- const struct native_connector **(*get_connectors)(struct native_display *ndpy,
- int *num_connectors,
- int *num_crtcs);
-
- /**
- * Get the current supported modes of a connector. The returned modes may
- * change every time this function is called and those from previous calls
- * might become invalid.
- */
- const struct native_mode **(*get_modes)(struct native_display *ndpy,
- const struct native_connector *nconn,
- int *num_modes);
-
- /**
- * Create a scan-out surface. Required unless no config has
- * GLX_SCREEN_BIT_MESA set.
- */
- struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
- const struct native_config *nconf,
- uint width, uint height);
-
+struct native_event_handler {
/**
- * Program the CRTC to output the surface to the given connectors with the
- * given mode. When surface is not given, the CRTC is disabled.
- *
- * This interface does not export a way to query capabilities of the CRTCs.
- * The native display usually needs to dynamically map the index to a CRTC
- * that supports the given connectors.
+ * This function is called when a surface needs to be validated.
*/
- boolean (*program)(struct native_display *ndpy, int crtc_idx,
- struct native_surface *nsurf, uint x, uint y,
- const struct native_connector **nconns, int num_nconns,
- const struct native_mode *nmode);
+ void (*invalid_surface)(struct native_display *ndpy,
+ struct native_surface *nsurf,
+ unsigned int seq_num);
};
/**
@@ -267,6 +251,7 @@ const char *
native_get_name(void);
struct native_display *
-native_create_display(EGLNativeDisplayType dpy);
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *handler);
#endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl/common/native_modeset.h b/src/gallium/state_trackers/egl/common/native_modeset.h
new file mode 100644
index 00000000000..71dc3ec860e
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_modeset.h
@@ -0,0 +1,87 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2009-2010 Chia-I Wu <[email protected]>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _NATIVE_MODESET_H_
+#define _NATIVE_MODESET_H_
+
+#include "pipe/p_compiler.h"
+
+struct native_display;
+struct native_surface;
+struct native_config;
+
+struct native_connector {
+ int dummy;
+};
+
+struct native_mode {
+ const char *desc;
+ int width, height;
+ int refresh_rate;
+};
+
+/**
+ * Mode setting interface of the native display. It exposes the mode setting
+ * capabilities of the underlying graphics hardware.
+ */
+struct native_display_modeset {
+ /**
+ * Get the available physical connectors and the number of CRTCs.
+ */
+ const struct native_connector **(*get_connectors)(struct native_display *ndpy,
+ int *num_connectors,
+ int *num_crtcs);
+
+ /**
+ * Get the current supported modes of a connector. The returned modes may
+ * change every time this function is called and those from previous calls
+ * might become invalid.
+ */
+ const struct native_mode **(*get_modes)(struct native_display *ndpy,
+ const struct native_connector *nconn,
+ int *num_modes);
+
+ /**
+ * Create a scan-out surface. Required unless no config has
+ * GLX_SCREEN_BIT_MESA set.
+ */
+ struct native_surface *(*create_scanout_surface)(struct native_display *ndpy,
+ const struct native_config *nconf,
+ uint width, uint height);
+
+ /**
+ * Program the CRTC to output the surface to the given connectors with the
+ * given mode. When surface is not given, the CRTC is disabled.
+ *
+ * This interface does not export a way to query capabilities of the CRTCs.
+ * The native display usually needs to dynamically map the index to a CRTC
+ * that supports the given connectors.
+ */
+ boolean (*program)(struct native_display *ndpy, int crtc_idx,
+ struct native_surface *nsurf, uint x, uint y,
+ const struct native_connector **nconns, int num_nconns,
+ const struct native_mode *nmode);
+};
+
+#endif /* _NATIVE_MODESET_H_ */
diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h
index 507a0ec4027..562dd68c150 100644
--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h
+++ b/src/gallium/state_trackers/egl/common/st_public_tmp.h
@@ -9,7 +9,7 @@ ST_PUBLIC(st_get_framebuffer_surface, int, struct st_f
ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture)
ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb)
ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb)
-ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read)
+ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read, void *winsys_drawable_handle)
ST_PUBLIC(st_get_current, struct st_context *, void)
ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence)
ST_PUBLIC(st_finish, void, struct st_context *st)
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index 91cefc538d1..73222408565 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -55,7 +55,7 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
templ.format = ksurf->color_format;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
if (ksurf->type == KMS_SURFACE_TYPE_SCANOUT)
- templ.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
}
/* create textures */
@@ -100,7 +100,7 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
for (i = 0; i < num_framebuffers; i++) {
struct kms_framebuffer *fb;
enum native_attachment natt;
- unsigned int handle, stride;
+ struct winsys_handle whandle;
uint block_bits;
if (i == 0) {
@@ -128,13 +128,17 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
/* TODO detect the real value */
fb->is_passive = TRUE;
- if (!kdpy->api->local_handle_from_texture(kdpy->api,
- kdpy->base.screen, fb->texture, &stride, &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!kdpy->base.screen->texture_get_handle(kdpy->base.screen,
+ fb->texture, &whandle))
return FALSE;
block_bits = util_format_get_blocksizebits(ksurf->color_format);
err = drmModeAddFB(kdpy->fd, ksurf->width, ksurf->height,
- block_bits, block_bits, stride, handle, &fb->buffer_id);
+ block_bits, block_bits, whandle.stride, whandle.handle,
+ &fb->buffer_id);
if (err) {
fb->buffer_id = 0;
return FALSE;
@@ -201,6 +205,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
/* the front/back textures are swapped */
ksurf->sequence_number++;
+ kdpy->event_handler->invalid_surface(&kdpy->base,
+ &ksurf->base, ksurf->sequence_number);
return TRUE;
}
@@ -499,7 +505,10 @@ kms_display_get_modes(struct native_display *ndpy,
kmode->base.desc = kmode->mode.name;
kmode->base.width = kmode->mode.hdisplay;
kmode->base.height = kmode->mode.vdisplay;
- kmode->base.refresh_rate = kmode->mode.vrefresh / 1000;
+ kmode->base.refresh_rate = kmode->mode.vrefresh;
+ /* not all kernels have vrefresh = refresh_rate * 1000 */
+ if (kmode->base.refresh_rate > 1000)
+ kmode->base.refresh_rate = (kmode->base.refresh_rate + 500) / 1000;
}
nmodes_return = malloc(count * sizeof(*nmodes_return));
@@ -606,9 +615,9 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
/* always double-buffered */
nconf->mode.doubleBufferMode = TRUE;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ format = PIPE_FORMAT_B8G8R8A8_UNORM;
if (!kms_display_is_format_supported(&kdpy->base, format, TRUE)) {
- format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
if (!kms_display_is_format_supported(&kdpy->base, format, TRUE))
format = PIPE_FORMAT_NONE;
}
@@ -622,9 +631,9 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
nconf->mode.alphaBits = 8;
nconf->mode.rgbBits = 32;
- format = PIPE_FORMAT_S8Z24_UNORM;
+ format = PIPE_FORMAT_Z24S8_UNORM;
if (!kms_display_is_format_supported(&kdpy->base, format, FALSE)) {
- format = PIPE_FORMAT_Z24S8_UNORM;
+ format = PIPE_FORMAT_S8Z24_UNORM;
if (!kms_display_is_format_supported(&kdpy->base, format, FALSE))
format = PIPE_FORMAT_NONE;
}
@@ -660,6 +669,21 @@ kms_display_get_configs(struct native_display *ndpy, int *num_configs)
return configs;
}
+static int
+kms_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
static void
kms_display_destroy(struct native_display *ndpy)
{
@@ -759,7 +783,9 @@ static struct native_display_modeset kms_display_modeset = {
};
static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
+kms_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct kms_display *kdpy;
@@ -767,6 +793,8 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!kdpy)
return NULL;
+ kdpy->event_handler = event_handler;
+
kdpy->api = api;
if (!kdpy->api) {
_eglLog(_EGL_WARNING, "failed to create DRM API");
@@ -802,6 +830,7 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
}
kdpy->base.destroy = kms_display_destroy;
+ kdpy->base.get_param = kms_display_get_param;
kdpy->base.get_configs = kms_display_get_configs;
kdpy->base.create_pbuffer_surface = kms_display_create_pbuffer_surface;
@@ -842,7 +871,8 @@ native_get_name(void)
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
@@ -850,7 +880,7 @@ native_create_display(EGLNativeDisplayType dpy)
drm_api = drm_api_create();
if (drm_api)
- ndpy = kms_create_display(dpy, drm_api);
+ ndpy = kms_create_display(dpy, event_handler, drm_api);
return ndpy;
}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index 095186e3cf3..f9cbcb158b5 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -53,6 +53,8 @@ struct kms_crtc {
struct kms_display {
struct native_display base;
+ struct native_event_handler *event_handler;
+
int fd;
struct drm_api *api;
drmModeResPtr resources;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 5f2fd412604..98399792311 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -26,6 +26,7 @@
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_inlines.h"
+#include "util/u_hash_table.h"
#include "pipe/p_compiler.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
@@ -47,12 +48,18 @@ struct dri2_display {
Display *dpy;
boolean own_dpy;
+ struct native_event_handler *event_handler;
+
struct drm_api *api;
struct x11_screen *xscr;
int xscr_number;
+ const char *dri_driver;
+ int dri_major, dri_minor;
struct dri2_config *configs;
int num_configs;
+
+ struct util_hash_table *surfaces;
};
struct dri2_surface {
@@ -62,10 +69,16 @@ struct dri2_surface {
enum pipe_format color_format;
struct dri2_display *dri2dpy;
- struct pipe_texture *pbuffer_textures[NUM_NATIVE_ATTACHMENTS];
- boolean have_back, have_fake;
+ unsigned int server_stamp;
+ unsigned int client_stamp;
int width, height;
- unsigned int sequence_number;
+ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS];
+ uint valid_mask;
+
+ boolean have_back, have_fake;
+
+ struct x11_drawable_buffer *last_xbufs;
+ int last_num_xbufs;
};
struct dri2_config {
@@ -90,110 +103,103 @@ dri2_config(const struct native_config *nconf)
return (struct dri2_config *) nconf;
}
-static boolean
-dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
+/**
+ * Process the buffers returned by the server.
+ */
+static void
+dri2_surface_process_drawable_buffers(struct native_surface *nsurf,
+ struct x11_drawable_buffer *xbufs,
+ int num_xbufs)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+ struct pipe_texture templ;
+ struct winsys_handle whandle;
+ uint valid_mask;
+ int i;
- /* pbuffer is private */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
- return TRUE;
+ /* free the old textures */
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
+ pipe_texture_reference(&dri2surf->textures[i], NULL);
+ dri2surf->valid_mask = 0x0;
- /* copy to real front buffer */
- if (dri2surf->have_fake)
- x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
- 0, 0, dri2surf->width, dri2surf->height,
- DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+ dri2surf->have_back = FALSE;
+ dri2surf->have_fake = FALSE;
- return TRUE;
-}
+ if (!xbufs)
+ return;
-static boolean
-dri2_surface_swap_buffers(struct native_surface *nsurf)
-{
- struct dri2_surface *dri2surf = dri2_surface(nsurf);
- struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = dri2surf->width;
+ templ.height0 = dri2surf->height;
+ templ.depth0 = 1;
+ templ.format = dri2surf->color_format;
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- /* pbuffer is private */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
- return TRUE;
+ valid_mask = 0x0;
+ for (i = 0; i < num_xbufs; i++) {
+ struct x11_drawable_buffer *xbuf = &xbufs[i];
+ const char *desc;
+ enum native_attachment natt;
- /* copy to front buffer */
- if (dri2surf->have_back)
- x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
- 0, 0, dri2surf->width, dri2surf->height,
- DRI2BufferBackLeft, DRI2BufferFrontLeft);
+ switch (xbuf->attachment) {
+ case DRI2BufferFrontLeft:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ desc = "DRI2 Front Buffer";
+ break;
+ case DRI2BufferFakeFrontLeft:
+ natt = NATIVE_ATTACHMENT_FRONT_LEFT;
+ desc = "DRI2 Fake Front Buffer";
+ dri2surf->have_fake = TRUE;
+ break;
+ case DRI2BufferBackLeft:
+ natt = NATIVE_ATTACHMENT_BACK_LEFT;
+ desc = "DRI2 Back Buffer";
+ dri2surf->have_back = TRUE;
+ break;
+ default:
+ desc = NULL;
+ break;
+ }
- /* and update fake front buffer */
- if (dri2surf->have_fake)
- x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
- 0, 0, dri2surf->width, dri2surf->height,
- DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ if (!desc || dri2surf->textures[natt]) {
+ if (!desc)
+ _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
+ else
+ _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
+ continue;
+ }
- return TRUE;
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.stride = xbuf->pitch;
+ whandle.handle = xbuf->name;
+ dri2surf->textures[natt] = dri2dpy->base.screen->texture_from_handle(
+ dri2dpy->base.screen, &templ, &whandle);
+ if (dri2surf->textures[natt])
+ valid_mask |= 1 << natt;
+ }
+
+ dri2surf->valid_mask = valid_mask;
}
-static boolean
-dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
- unsigned int *seq_num, struct pipe_texture **textures,
- int *width, int *height)
+/**
+ * Get the buffers from the server.
+ */
+static void
+dri2_surface_get_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct dri2_surface *dri2surf = dri2_surface(nsurf);
struct dri2_display *dri2dpy = dri2surf->dri2dpy;
unsigned int dri2atts[NUM_NATIVE_ATTACHMENTS];
- struct pipe_texture templ;
+ int num_ins, num_outs, att;
struct x11_drawable_buffer *xbufs;
- int num_ins, num_outs, att, i;
-
- if (attachment_mask) {
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = dri2surf->width;
- templ.height0 = dri2surf->height;
- templ.depth0 = 1;
- templ.format = dri2surf->color_format;
- templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
-
- if (textures)
- memset(textures, 0, sizeof(*textures) * NUM_NATIVE_ATTACHMENTS);
- }
-
- /* create textures for pbuffer */
- if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
- struct pipe_screen *screen = dri2dpy->base.screen;
-
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- struct pipe_texture *ptex = dri2surf->pbuffer_textures[att];
-
- /* delay the allocation */
- if (!native_attachment_mask_test(attachment_mask, att))
- continue;
-
- if (!ptex) {
- ptex = screen->texture_create(screen, &templ);
- dri2surf->pbuffer_textures[att] = ptex;
- }
-
- if (textures)
- pipe_texture_reference(&textures[att], ptex);
- }
-
- if (seq_num)
- *seq_num = dri2surf->sequence_number;
- if (width)
- *width = dri2surf->width;
- if (height)
- *height = dri2surf->height;
-
- return TRUE;
- }
/* prepare the attachments */
num_ins = 0;
for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(attachment_mask, att)) {
+ if (native_attachment_mask_test(buffer_mask, att)) {
unsigned int dri2att;
switch (att) {
@@ -220,79 +226,178 @@ dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
}
}
- dri2surf->have_back = FALSE;
- dri2surf->have_fake = FALSE;
-
- /* remember old geometry */
- templ.width0 = dri2surf->width;
- templ.height0 = dri2surf->height;
-
xbufs = x11_drawable_get_buffers(dri2dpy->xscr, dri2surf->drawable,
&dri2surf->width, &dri2surf->height,
dri2atts, FALSE, num_ins, &num_outs);
- if (!xbufs)
- return FALSE;
- if (templ.width0 != dri2surf->width || templ.height0 != dri2surf->height) {
- /* are there cases where the buffers change and the geometry doesn't? */
- dri2surf->sequence_number++;
+ /* we should be able to do better... */
+ if (xbufs && dri2surf->last_num_xbufs == num_outs &&
+ memcmp(dri2surf->last_xbufs, xbufs, sizeof(*xbufs) * num_outs) == 0) {
+ free(xbufs);
+ dri2surf->client_stamp = dri2surf->server_stamp;
+ return;
+ }
+
+ dri2_surface_process_drawable_buffers(&dri2surf->base, xbufs, num_outs);
+ dri2surf->server_stamp++;
+ dri2surf->client_stamp = dri2surf->server_stamp;
+
+ if (dri2surf->last_xbufs)
+ free(dri2surf->last_xbufs);
+ dri2surf->last_xbufs = xbufs;
+ dri2surf->last_num_xbufs = num_outs;
+}
+
+/**
+ * Update the buffers of the surface. This is a slow function due to the
+ * round-trip to the server.
+ */
+static boolean
+dri2_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ /* create textures for pbuffer */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER) {
+ struct pipe_screen *screen = dri2dpy->base.screen;
+ struct pipe_texture templ;
+ uint new_valid = 0x0;
+ int att;
+
+ buffer_mask &= ~dri2surf->valid_mask;
+ if (!buffer_mask)
+ return TRUE;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
templ.width0 = dri2surf->width;
templ.height0 = dri2surf->height;
- }
-
- for (i = 0; i < num_outs; i++) {
- struct x11_drawable_buffer *xbuf = &xbufs[i];
- const char *desc;
- enum native_attachment natt;
+ templ.depth0 = 1;
+ templ.format = dri2surf->color_format;
+ templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- switch (xbuf->attachment) {
- case DRI2BufferFrontLeft:
- natt = NATIVE_ATTACHMENT_FRONT_LEFT;
- desc = "DRI2 Front Buffer";
- break;
- case DRI2BufferFakeFrontLeft:
- natt = NATIVE_ATTACHMENT_FRONT_LEFT;
- desc = "DRI2 Fake Front Buffer";
- dri2surf->have_fake = TRUE;
- break;
- case DRI2BufferBackLeft:
- natt = NATIVE_ATTACHMENT_BACK_LEFT;
- desc = "DRI2 Back Buffer";
- dri2surf->have_back = TRUE;
- break;
- default:
- desc = NULL;
- break;
- }
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(buffer_mask, att)) {
+ assert(!dri2surf->textures[att]);
- if (!desc || !native_attachment_mask_test(attachment_mask, natt) ||
- (textures && textures[natt])) {
- if (!desc)
- _eglLog(_EGL_WARNING, "unknown buffer %d", xbuf->attachment);
- else if (!native_attachment_mask_test(attachment_mask, natt))
- _eglLog(_EGL_WARNING, "unexpected buffer %d", xbuf->attachment);
- else
- _eglLog(_EGL_WARNING, "both real and fake front buffers are listed");
- continue;
- }
+ dri2surf->textures[att] = screen->texture_create(screen, &templ);
+ if (!dri2surf->textures[att])
+ break;
- if (textures) {
- struct pipe_texture *ptex =
- dri2dpy->api->texture_from_shared_handle(dri2dpy->api,
- dri2dpy->base.screen, &templ,
- desc, xbuf->pitch, xbuf->name);
- if (ptex) {
- /* the caller owns the textures */
- textures[natt] = ptex;
+ new_valid |= 1 << att;
+ if (new_valid == buffer_mask)
+ break;
}
}
+ dri2surf->valid_mask |= new_valid;
+ /* no need to update the stamps */
+ }
+ else {
+ dri2_surface_get_buffers(&dri2surf->base, buffer_mask);
+ }
+
+ return ((dri2surf->valid_mask & buffer_mask) == buffer_mask);
+}
+
+/**
+ * Return TRUE if the surface receives DRI2_InvalidateBuffers events.
+ */
+static INLINE boolean
+dri2_surface_receive_events(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ return (dri2surf->dri2dpy->dri_minor >= 3);
+}
+
+static boolean
+dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ /* pbuffer is private */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ /* copy to real front buffer */
+ if (dri2surf->have_fake)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+
+ /* force buffers to be updated in next validation call */
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
+ dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
}
- free(xbufs);
+ return TRUE;
+}
+
+static boolean
+dri2_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+ struct dri2_display *dri2dpy = dri2surf->dri2dpy;
+
+ /* pbuffer is private */
+ if (dri2surf->type == DRI2_SURFACE_TYPE_PBUFFER)
+ return TRUE;
+
+ /* copy to front buffer */
+ if (dri2surf->have_back)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferBackLeft, DRI2BufferFrontLeft);
+
+ /* and update fake front buffer */
+ if (dri2surf->have_fake)
+ x11_drawable_copy_buffers(dri2dpy->xscr, dri2surf->drawable,
+ 0, 0, dri2surf->width, dri2surf->height,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+
+ /* force buffers to be updated in next validation call */
+ if (!dri2_surface_receive_events(&dri2surf->base)) {
+ dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+ }
+
+ return TRUE;
+}
+
+static boolean
+dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_texture **textures,
+ int *width, int *height)
+{
+ struct dri2_surface *dri2surf = dri2_surface(nsurf);
+
+ if (dri2surf->server_stamp != dri2surf->client_stamp ||
+ (dri2surf->valid_mask & attachment_mask) != attachment_mask) {
+ if (!dri2_surface_update_buffers(&dri2surf->base, attachment_mask))
+ return FALSE;
+ }
if (seq_num)
- *seq_num = dri2surf->sequence_number;
+ *seq_num = dri2surf->client_stamp;
+
+ if (textures) {
+ int att;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(attachment_mask, att)) {
+ struct pipe_texture *ptex = dri2surf->textures[att];
+
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], ptex);
+ }
+ }
+ }
+
if (width)
*width = dri2surf->width;
if (height)
@@ -320,14 +425,21 @@ dri2_surface_destroy(struct native_surface *nsurf)
struct dri2_surface *dri2surf = dri2_surface(nsurf);
int i;
+ if (dri2surf->last_xbufs)
+ free(dri2surf->last_xbufs);
+
for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct pipe_texture *ptex = dri2surf->pbuffer_textures[i];
+ struct pipe_texture *ptex = dri2surf->textures[i];
pipe_texture_reference(&ptex, NULL);
}
- if (dri2surf->drawable)
+ if (dri2surf->drawable) {
x11_drawable_enable_dri2(dri2surf->dri2dpy->xscr,
dri2surf->drawable, FALSE);
+
+ util_hash_table_remove(dri2surf->dri2dpy->surfaces,
+ (void *) dri2surf->drawable);
+ }
free(dri2surf);
}
@@ -345,9 +457,6 @@ dri2_display_create_surface(struct native_display *ndpy,
if (!dri2surf)
return NULL;
- if (drawable)
- x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
-
dri2surf->dri2dpy = dri2dpy;
dri2surf->type = type;
dri2surf->drawable = drawable;
@@ -359,6 +468,15 @@ dri2_display_create_surface(struct native_display *ndpy,
dri2surf->base.validate = dri2_surface_validate;
dri2surf->base.wait = dri2_surface_wait;
+ if (drawable) {
+ x11_drawable_enable_dri2(dri2dpy->xscr, drawable, TRUE);
+ /* initialize the geometry */
+ dri2_surface_update_buffers(&dri2surf->base, 0x0);
+
+ util_hash_table_set(dri2surf->dri2dpy->surfaces,
+ (void *) dri2surf->drawable, (void *) &dri2surf->base);
+ }
+
return dri2surf;
}
@@ -409,17 +527,17 @@ choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32])
switch (mode->rgbBits) {
case 32:
- formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+ formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 24:
- formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
formats[count++] = PIPE_FORMAT_B8G8R8X8_UNORM;
- formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
+ formats[count++] = PIPE_FORMAT_X8R8G8B8_UNORM;
formats[count++] = PIPE_FORMAT_B8G8R8A8_UNORM;
+ formats[count++] = PIPE_FORMAT_A8R8G8B8_UNORM;
break;
case 16:
- formats[count++] = PIPE_FORMAT_R5G6B5_UNORM;
+ formats[count++] = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
break;
@@ -440,12 +558,12 @@ choose_depth_stencil_format(const __GLcontextModes *mode,
break;
case 24:
if (mode->stencilBits) {
- formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
+ formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
}
else {
- formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
formats[count++] = PIPE_FORMAT_Z24X8_UNORM;
+ formats[count++] = PIPE_FORMAT_X8Z24_UNORM;
}
break;
case 16:
@@ -592,6 +710,25 @@ dri2_display_is_pixmap_supported(struct native_display *ndpy,
return (depth == nconf_depth || (depth == 24 && depth + 8 == nconf_depth));
}
+static int
+dri2_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ /* DRI2GetBuffers use the native buffers */
+ val = TRUE;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
static void
dri2_display_destroy(struct native_display *ndpy)
{
@@ -603,6 +740,9 @@ dri2_display_destroy(struct native_display *ndpy)
if (dri2dpy->base.screen)
dri2dpy->base.screen->destroy(dri2dpy->base.screen);
+ if (dri2dpy->surfaces)
+ util_hash_table_destroy(dri2dpy->surfaces);
+
if (dri2dpy->xscr)
x11_screen_destroy(dri2dpy->xscr);
if (dri2dpy->own_dpy)
@@ -612,6 +752,27 @@ dri2_display_destroy(struct native_display *ndpy)
free(dri2dpy);
}
+static void
+dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
+ void *user_data)
+{
+ struct native_display *ndpy = (struct native_display* ) user_data;
+ struct dri2_display *dri2dpy = dri2_display(ndpy);
+ struct native_surface *nsurf;
+ struct dri2_surface *dri2surf;
+
+ nsurf = (struct native_surface *)
+ util_hash_table_get(dri2dpy->surfaces, (void *) drawable);
+ if (!nsurf)
+ return;
+
+ dri2surf = dri2_surface(nsurf);
+
+ dri2surf->server_stamp++;
+ dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+ &dri2surf->base, dri2surf->server_stamp);
+}
+
/**
* Initialize DRI2 and pipe screen.
*/
@@ -629,7 +790,17 @@ dri2_display_init_screen(struct native_display *ndpy)
return FALSE;
}
- fd = x11_screen_enable_dri2(dri2dpy->xscr, driver);
+ dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
+ &dri2dpy->dri_major, &dri2dpy->dri_minor);
+ if (!dri2dpy->dri_driver || !driver ||
+ strcmp(dri2dpy->dri_driver, driver) != 0) {
+ _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
+ dri2dpy->dri_driver, dri2dpy->api->name);
+ return FALSE;
+ }
+
+ fd = x11_screen_enable_dri2(dri2dpy->xscr,
+ dri2_display_invalidate_buffers, &dri2dpy->base);
if (fd < 0)
return FALSE;
@@ -644,8 +815,23 @@ dri2_display_init_screen(struct native_display *ndpy)
return TRUE;
}
+static unsigned
+dri2_display_hash_table_hash(void *key)
+{
+ XID drawable = pointer_to_uintptr(key);
+ return (unsigned) drawable;
+}
+
+static int
+dri2_display_hash_table_compare(void *key1, void *key2)
+{
+ return (key1 - key2);
+}
+
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api)
{
struct dri2_display *dri2dpy;
@@ -653,12 +839,8 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
if (!dri2dpy)
return NULL;
+ dri2dpy->event_handler = event_handler;
dri2dpy->api = api;
- if (!dri2dpy->api) {
- _eglLog(_EGL_WARNING, "failed to create DRM API");
- free(dri2dpy);
- return NULL;
- }
dri2dpy->dpy = dpy;
if (!dri2dpy->dpy) {
@@ -682,7 +864,15 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
return NULL;
}
+ dri2dpy->surfaces = util_hash_table_create(dri2_display_hash_table_hash,
+ dri2_display_hash_table_compare);
+ if (!dri2dpy->surfaces) {
+ dri2_display_destroy(&dri2dpy->base);
+ return NULL;
+ }
+
dri2dpy->base.destroy = dri2_display_destroy;
+ dri2dpy->base.get_param = dri2_display_get_param;
dri2dpy->base.get_configs = dri2_display_get_configs;
dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported;
dri2dpy->base.create_window_surface = dri2_display_create_window_surface;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 8eb542bd827..c6eb17ab1ac 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -70,7 +70,7 @@ native_create_probe(EGLNativeDisplayType dpy)
xscr = x11_screen_create(xdpy, scr);
if (xscr) {
if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
- driver_name = x11_screen_probe_dri2(xscr);
+ driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
if (driver_name)
nprobe->data = strdup(driver_name);
}
@@ -126,7 +126,8 @@ native_get_name(void)
}
struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
boolean force_sw;
@@ -136,14 +137,14 @@ native_create_display(EGLNativeDisplayType dpy)
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
if (api && !force_sw) {
- ndpy = x11_create_dri2_display(dpy, api);
+ ndpy = x11_create_dri2_display(dpy, event_handler, api);
}
if (!ndpy) {
EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
_eglLog(level, "use software fallback");
- ndpy = x11_create_ximage_display(dpy, TRUE);
+ ndpy = x11_create_ximage_display(dpy, event_handler);
}
return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 622ddac5df6..1566524926a 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -29,9 +29,12 @@
#include "common/native.h"
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm);
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler);
struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api);
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler,
+ struct drm_api *api);
#endif /* _NATIVE_X11_H_ */
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 92a62f230e0..e0d12acabe8 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -28,17 +28,19 @@
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/extensions/XShm.h>
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "pipe/p_compiler.h"
-#include "util/u_simple_screen.h"
#include "util/u_inlines.h"
-#include "softpipe/sp_winsys.h"
+#include "state_tracker/xlib_sw_winsys.h"
+#include "target-helpers/wrap_screen.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "cell/ppu/cell_public.h"
#include "egllog.h"
-#include "sw_winsys.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -53,22 +55,18 @@ struct ximage_display {
Display *dpy;
boolean own_dpy;
+ struct native_event_handler *event_handler;
+
struct x11_screen *xscr;
int xscr_number;
- boolean use_xshm;
-
- struct pipe_winsys *winsys;
struct ximage_config *configs;
int num_configs;
};
struct ximage_buffer {
- XImage *ximage;
-
struct pipe_texture *texture;
- XShmSegmentInfo *shm_info;
- boolean xshm_attached;
+ struct xlib_drawable xdraw;
};
struct ximage_surface {
@@ -79,11 +77,11 @@ struct ximage_surface {
XVisualInfo visual;
struct ximage_display *xdpy;
+ unsigned int server_stamp;
+ unsigned int client_stamp;
int width, height;
- GC gc;
-
struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
- unsigned int sequence_number;
+ uint valid_mask;
};
struct ximage_config {
@@ -117,18 +115,6 @@ ximage_surface_free_buffer(struct native_surface *nsurf,
struct ximage_buffer *xbuf = &xsurf->buffers[which];
pipe_texture_reference(&xbuf->texture, NULL);
-
- if (xbuf->shm_info) {
- if (xbuf->xshm_attached)
- XShmDetach(xsurf->xdpy->dpy, xbuf->shm_info);
- if (xbuf->shm_info->shmaddr != (void *) -1)
- shmdt(xbuf->shm_info->shmaddr);
- if (xbuf->shm_info->shmid != -1)
- shmctl(xbuf->shm_info->shmid, IPC_RMID, 0);
-
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->shmid = -1;
- }
}
static boolean
@@ -152,40 +138,25 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- if (xbuf->shm_info) {
- struct pipe_buffer *pbuf;
- unsigned stride, size;
- void *addr = NULL;
-
- stride = util_format_get_stride(xsurf->color_format, xsurf->width);
- /* alignment should depend on visual? */
- stride = align(stride, 4);
- size = stride * xsurf->height;
-
- /* create and attach shm object */
- xbuf->shm_info->shmid = shmget(IPC_PRIVATE, size, 0755);
- if (xbuf->shm_info->shmid != -1) {
- xbuf->shm_info->shmaddr =
- shmat(xbuf->shm_info->shmid, NULL, 0);
- if (xbuf->shm_info->shmaddr != (void *) -1) {
- if (XShmAttach(xsurf->xdpy->dpy, xbuf->shm_info)) {
- addr = xbuf->shm_info->shmaddr;
- xbuf->xshm_attached = TRUE;
- }
- }
- }
-
- if (addr) {
- pbuf = screen->user_buffer_create(screen, addr, size);
- if (pbuf) {
- xbuf->texture =
- screen->texture_blanket(screen, &templ, &stride, pbuf);
- pipe_buffer_reference(&pbuf, NULL);
- }
+ if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
+ switch (which) {
+ case NATIVE_ATTACHMENT_FRONT_LEFT:
+ case NATIVE_ATTACHMENT_FRONT_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ break;
+ case NATIVE_ATTACHMENT_BACK_LEFT:
+ case NATIVE_ATTACHMENT_BACK_RIGHT:
+ templ.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ break;
+ default:
+ break;
}
}
- else {
- xbuf->texture = screen->texture_create(screen, &templ);
+ xbuf->texture = screen->texture_create(screen, &templ);
+ if (xbuf->texture) {
+ xbuf->xdraw.visual = xsurf->visual.visual;
+ xbuf->xdraw.depth = xsurf->visual.depth;
+ xbuf->xdraw.drawable = xsurf->drawable;
}
/* clean up the buffer if allocation failed */
@@ -195,6 +166,92 @@ ximage_surface_alloc_buffer(struct native_surface *nsurf,
return (xbuf->texture != NULL);
}
+/**
+ * Update the geometry of the surface. Return TRUE if the geometry has changed
+ * since last call.
+ */
+static boolean
+ximage_surface_update_geometry(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ Status ok;
+ Window root;
+ int x, y;
+ unsigned int w, h, border, depth;
+ boolean updated = FALSE;
+
+ /* pbuffer has fixed geometry */
+ if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
+ return FALSE;
+
+ ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
+ &root, &x, &y, &w, &h, &border, &depth);
+ if (ok && (xsurf->width != w || xsurf->height != h)) {
+ xsurf->width = w;
+ xsurf->height = h;
+
+ xsurf->server_stamp++;
+ updated = TRUE;
+ }
+
+ return updated;
+}
+
+static void
+ximage_surface_notify_invalid(struct native_surface *nsurf)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ struct ximage_display *xdpy = xsurf->xdpy;
+
+ xdpy->event_handler->invalid_surface(&xdpy->base,
+ &xsurf->base, xsurf->server_stamp);
+}
+
+/**
+ * Update the buffers of the surface. It is a slow function due to the
+ * round-trip to the server.
+ */
+static boolean
+ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
+{
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ boolean updated;
+ uint new_valid;
+ int att;
+
+ updated = ximage_surface_update_geometry(&xsurf->base);
+ if (updated) {
+ /* all buffers become invalid */
+ xsurf->valid_mask = 0x0;
+ }
+ else {
+ buffer_mask &= ~xsurf->valid_mask;
+ /* all requested buffers are valid */
+ if (!buffer_mask) {
+ xsurf->client_stamp = xsurf->server_stamp;
+ return TRUE;
+ }
+ }
+
+ new_valid = 0x0;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(buffer_mask, att)) {
+ /* reallocate the texture */
+ if (!ximage_surface_alloc_buffer(&xsurf->base, att))
+ break;
+
+ new_valid |= (1 << att);
+ if (buffer_mask == new_valid)
+ break;
+ }
+ }
+
+ xsurf->valid_mask |= new_valid;
+ xsurf->client_stamp = xsurf->server_stamp;
+
+ return (new_valid == buffer_mask);
+}
+
static boolean
ximage_surface_draw_buffer(struct native_surface *nsurf,
enum native_attachment which)
@@ -202,43 +259,22 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xbuf = &xsurf->buffers[which];
struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_transfer *transfer;
+ struct pipe_surface *psurf;
if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
return TRUE;
- assert(xsurf->drawable && xbuf->ximage && xbuf->texture);
+ assert(xsurf->drawable && xbuf->texture);
- transfer = screen->get_tex_transfer(screen, xbuf->texture,
- 0, 0, 0, PIPE_TRANSFER_READ, 0, 0, xsurf->width, xsurf->height);
- if (!transfer)
+ /* what's the cost of surface creation? */
+ psurf = screen->get_tex_surface(screen,
+ xbuf->texture, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
+ if (!psurf)
return FALSE;
- xbuf->ximage->bytes_per_line = transfer->stride;
- xbuf->ximage->data = screen->transfer_map(screen, transfer);
- if (!xbuf->ximage->data) {
- screen->tex_transfer_destroy(transfer);
- return FALSE;
- }
-
-
- if (xbuf->shm_info)
- XShmPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height, False);
- else
- XPutImage(xsurf->xdpy->dpy, xsurf->drawable, xsurf->gc,
- xbuf->ximage, 0, 0, 0, 0, xsurf->width, xsurf->height);
-
- xbuf->ximage->data = NULL;
- screen->transfer_unmap(screen, transfer);
+ screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
- /*
- * softpipe allows the pipe transfer to be re-used, but we don't want to
- * rely on that behavior.
- */
- screen->tex_transfer_destroy(transfer);
-
- XSync(xsurf->xdpy->dpy, FALSE);
+ pipe_surface_reference(&psurf, NULL);
return TRUE;
}
@@ -246,7 +282,16 @@ ximage_surface_draw_buffer(struct native_surface *nsurf,
static boolean
ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
{
- return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
+ struct ximage_surface *xsurf = ximage_surface(nsurf);
+ boolean ret;
+
+ ret = ximage_surface_draw_buffer(&xsurf->base,
+ NATIVE_ATTACHMENT_FRONT_LEFT);
+ /* force buffers to be updated in next validation call */
+ xsurf->server_stamp++;
+ ximage_surface_notify_invalid(&xsurf->base);
+
+ return ret;
}
static boolean
@@ -254,44 +299,26 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
struct ximage_buffer *xfront, *xback, xtmp;
+ boolean ret;
+
+ /* display the back buffer first */
+ ret = ximage_surface_draw_buffer(&xsurf->base,
+ NATIVE_ATTACHMENT_BACK_LEFT);
+ /* force buffers to be updated in next validation call */
+ xsurf->server_stamp++;
+ ximage_surface_notify_invalid(&xsurf->base);
xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
- /* draw the back buffer directly if there is no front buffer */
- if (!xfront->texture)
- return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
-
- /* swap the buffers */
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
-
- /* the front/back textures are swapped */
- xsurf->sequence_number++;
-
- return ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
-}
-
-static void
-ximage_surface_update_geometry(struct native_surface *nsurf)
-{
- struct ximage_surface *xsurf = ximage_surface(nsurf);
- Status ok;
- Window root;
- int x, y;
- unsigned int w, h, border, depth;
-
- /* pbuffer has fixed geometry */
- if (xsurf->type == XIMAGE_SURFACE_TYPE_PBUFFER)
- return;
-
- ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
- &root, &x, &y, &w, &h, &border, &depth);
- if (ok) {
- xsurf->width = w;
- xsurf->height = h;
+ /* skip swapping unless there is a front buffer */
+ if (xfront->texture) {
+ xtmp = *xfront;
+ *xfront = *xback;
+ *xback = xtmp;
}
+
+ return ret;
}
static boolean
@@ -300,44 +327,28 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean new_buffers = FALSE;
- int att;
- ximage_surface_update_geometry(&xsurf->base);
+ if (xsurf->client_stamp != xsurf->server_stamp ||
+ (xsurf->valid_mask & attachment_mask) != attachment_mask) {
+ if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
+ return FALSE;
+ }
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
- /* delay the allocation */
- if (!native_attachment_mask_test(attachment_mask, att))
- continue;
-
- /* reallocate the texture */
- if (!xbuf->texture ||
- xsurf->width != xbuf->texture->width0 ||
- xsurf->height != xbuf->texture->height0) {
- new_buffers = TRUE;
- if (ximage_surface_alloc_buffer(&xsurf->base, att)) {
- /* update ximage */
- if (xbuf->ximage) {
- xbuf->ximage->width = xsurf->width;
- xbuf->ximage->height = xsurf->height;
- }
- }
- }
+ if (seq_num)
+ *seq_num = xsurf->client_stamp;
- if (textures) {
- textures[att] = NULL;
- pipe_texture_reference(&textures[att], xbuf->texture);
+ if (textures) {
+ int att;
+ for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
+ if (native_attachment_mask_test(attachment_mask, att)) {
+ struct ximage_buffer *xbuf = &xsurf->buffers[att];
+
+ textures[att] = NULL;
+ pipe_texture_reference(&textures[att], xbuf->texture);
+ }
}
}
- /* increase the sequence number so that caller knows */
- if (new_buffers)
- xsurf->sequence_number++;
-
- if (seq_num)
- *seq_num = xsurf->sequence_number;
if (width)
*width = xsurf->width;
if (height)
@@ -360,18 +371,9 @@ ximage_surface_destroy(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
int i;
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
ximage_surface_free_buffer(&xsurf->base, i);
- /* xbuf->shm_info is owned by xbuf->ximage? */
- if (xbuf->ximage) {
- XDestroyImage(xbuf->ximage);
- xbuf->ximage = NULL;
- }
- }
- if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER)
- XFreeGC(xsurf->xdpy->dpy, xsurf->gc);
free(xsurf);
}
@@ -384,7 +386,6 @@ ximage_display_create_surface(struct native_display *ndpy,
struct ximage_display *xdpy = ximage_display(ndpy);
struct ximage_config *xconf = ximage_config(nconf);
struct ximage_surface *xsurf;
- int i;
xsurf = CALLOC_STRUCT(ximage_surface);
if (!xsurf)
@@ -398,49 +399,8 @@ ximage_display_create_surface(struct native_display *ndpy,
if (xsurf->type != XIMAGE_SURFACE_TYPE_PBUFFER) {
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
-
- xsurf->gc = XCreateGC(xdpy->dpy, xsurf->drawable, 0, NULL);
- if (!xsurf->gc) {
- free(xsurf);
- return NULL;
- }
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct ximage_buffer *xbuf = &xsurf->buffers[i];
-
- if (xdpy->use_xshm) {
- xbuf->shm_info = calloc(1, sizeof(*xbuf->shm_info));
- if (xbuf->shm_info) {
- /* initialize shm info */
- xbuf->shm_info->shmid = -1;
- xbuf->shm_info->shmaddr = (void *) -1;
- xbuf->shm_info->readOnly = TRUE;
-
- xbuf->ximage = XShmCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, NULL,
- xbuf->shm_info,
- 0, 0);
- }
- }
- else {
- xbuf->ximage = XCreateImage(xsurf->xdpy->dpy,
- xsurf->visual.visual,
- xsurf->visual.depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 8, /* bitmap_pad */
- 0); /* bytes_per_line */
- }
-
- if (!xbuf->ximage) {
- XFreeGC(xdpy->dpy, xsurf->gc);
- free(xsurf);
- return NULL;
- }
- }
+ /* initialize the geometry */
+ ximage_surface_update_buffers(&xsurf->base, 0x0);
}
xsurf->base.destroy = ximage_surface_destroy;
@@ -499,13 +459,13 @@ choose_format(const XVisualInfo *vinfo)
/* TODO elaborate the formats */
switch (vinfo->depth) {
case 32:
- fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+ fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
- fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+ fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
- fmt = PIPE_FORMAT_R5G6B5_UNORM;
+ fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
@@ -558,8 +518,8 @@ ximage_display_get_configs(struct native_display *ndpy, int *num_configs)
xconf->base.stencil_format = PIPE_FORMAT_NONE;
/* create the second config with depth/stencil buffer */
if (j == 1) {
- xconf->base.depth_format = PIPE_FORMAT_S8Z24_UNORM;
- xconf->base.stencil_format = PIPE_FORMAT_S8Z24_UNORM;
+ xconf->base.depth_format = PIPE_FORMAT_Z24S8_UNORM;
+ xconf->base.stencil_format = PIPE_FORMAT_Z24S8_UNORM;
mode->depthBits = 24;
mode->stencilBits = 8;
mode->haveDepthBuffer = TRUE;
@@ -607,13 +567,13 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy,
depth = x11_drawable_get_depth(xdpy->xscr, (Drawable) pix);
switch (depth) {
case 32:
- fmt = PIPE_FORMAT_A8R8G8B8_UNORM;
+ fmt = PIPE_FORMAT_B8G8R8A8_UNORM;
break;
case 24:
- fmt = PIPE_FORMAT_X8R8G8B8_UNORM;
+ fmt = PIPE_FORMAT_B8G8R8X8_UNORM;
break;
case 16:
- fmt = PIPE_FORMAT_R5G6B5_UNORM;
+ fmt = PIPE_FORMAT_B5G6R5_UNORM;
break;
default:
fmt = PIPE_FORMAT_NONE;
@@ -623,6 +583,25 @@ ximage_display_is_pixmap_supported(struct native_display *ndpy,
return (fmt == nconf->color_format);
}
+static int
+ximage_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ /* private buffers are allocated */
+ val = FALSE;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
static void
ximage_display_destroy(struct native_display *ndpy)
{
@@ -632,7 +611,6 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
- free(xdpy->winsys);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)
@@ -640,8 +618,63 @@ ximage_display_destroy(struct native_display *ndpy)
free(xdpy);
}
+
+/* Helper function to build a subset of a driver stack consisting of
+ * one of the software rasterizers (cell, llvmpipe, softpipe) and the
+ * xlib winsys.
+ *
+ * This function could be shared, but currently causes headaches for
+ * the build systems, particularly scons if we try.
+ *
+ * Long term, want to avoid having global #defines for things like
+ * GALLIUM_LLVMPIPE, GALLIUM_CELL, etc. Scons already eliminates
+ * those #defines, so things that are painful for it now are likely to
+ * be painful for other build systems in the future.
+ */
+static struct pipe_screen *
+swrast_xlib_create_screen( Display *display )
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ /* Create the underlying winsys, which performs presents to Xlib
+ * drawables:
+ */
+ winsys = xlib_create_sw_winsys( display );
+ if (winsys == NULL)
+ return NULL;
+
+ /* Create a software rasterizer on top of that winsys. Use
+ * llvmpipe if it is available.
+ */
+#if defined(GALLIUM_LLVMPIPE)
+ if (screen == NULL &&
+ !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen( winsys );
+#endif
+
+ if (screen == NULL)
+ screen = softpipe_create_screen( winsys );
+
+ if (screen == NULL)
+ goto fail;
+
+ /* Inject any wrapping layers we want to here:
+ */
+ return gallium_wrap_screen( screen );
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+
struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
{
struct ximage_display *xdpy;
@@ -659,6 +692,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
xdpy->own_dpy = TRUE;
}
+ xdpy->event_handler = event_handler;
+
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
if (!xdpy->xscr) {
@@ -666,13 +701,10 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
return NULL;
}
- xdpy->use_xshm =
- (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
-
- xdpy->winsys = create_sw_winsys();
- xdpy->base.screen = softpipe_create_screen(xdpy->winsys);
+ xdpy->base.screen = swrast_xlib_create_screen(xdpy->dpy);
xdpy->base.destroy = ximage_display_destroy;
+ xdpy->base.get_param = ximage_display_get_param;
xdpy->base.get_configs = ximage_display_get_configs;
xdpy->base.is_pixmap_supported = ximage_display_is_pixmap_supported;
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.c b/src/gallium/state_trackers/egl/x11/sw_winsys.c
deleted file mode 100644
index 33328aadf26..00000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * Totally software-based winsys layer.
- * Note that the one winsys function that we can't implement here
- * is flush_frontbuffer().
- * Whoever uses this code will have to provide that.
- *
- * Authors: Brian Paul
- */
-
-
-#include "util/u_simple_screen.h"
-#include "pipe/p_state.h"
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "sw_winsys.h"
-
-
-
-/** Subclass of pipe_winsys */
-struct sw_pipe_winsys
-{
- struct pipe_winsys Base;
- /* no extra fields for now */
-};
-
-
-/** subclass of pipe_buffer */
-struct sw_pipe_buffer
-{
- struct pipe_buffer Base;
- boolean UserBuffer; /** Is this a user-space buffer? */
- void *Data;
- void *Mapped;
-};
-
-
-/** cast wrapper */
-static INLINE struct sw_pipe_buffer *
-sw_pipe_buffer(struct pipe_buffer *b)
-{
- return (struct sw_pipe_buffer *) b;
-}
-
-
-static const char *
-get_name(struct pipe_winsys *pws)
-{
- return "software";
-}
-
-
-/** Create new pipe_buffer and allocate storage of given size */
-static struct pipe_buffer *
-buffer_create(struct pipe_winsys *pws,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.alignment = alignment;
- buffer->Base.usage = usage;
- buffer->Base.size = size;
-
- /* align to 16-byte multiple for Cell */
- buffer->Data = align_malloc(size, MAX2(alignment, 16));
-
- return &buffer->Base;
-}
-
-
-/**
- * Create buffer which wraps user-space data.
- */
-static struct pipe_buffer *
-user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
-{
- struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->Base.reference, 1);
- buffer->Base.size = bytes;
- buffer->UserBuffer = TRUE;
- buffer->Data = ptr;
-
- return &buffer->Base;
-}
-
-
-static void *
-buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = buffer->Data;
- return buffer->Mapped;
-}
-
-
-static void
-buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
- buffer->Mapped = NULL;
-}
-
-
-static void
-buffer_destroy(struct pipe_buffer *buf)
-{
- struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
-
- if (buffer->Data && !buffer->UserBuffer) {
- align_free(buffer->Data);
- buffer->Data = NULL;
- }
-
- free(buffer);
-}
-
-
-static struct pipe_buffer *
-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;
- unsigned nblocksy;
-
- nblocksy = util_format_get_nblocksy(format, height);
- *stride = align(util_format_get_stride(format, width), alignment);
-
- return winsys->buffer_create(winsys, alignment,
- usage,
- *stride * nblocksy);
-}
-
-
-static void
-fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- /* no-op */
-}
-
-
-static int
-fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-static int
-fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
- unsigned flag)
-{
- /* no-op */
- return 0;
-}
-
-
-/**
- * Create/return a new pipe_winsys object.
- */
-struct pipe_winsys *
-create_sw_winsys(void)
-{
- struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
- if (!ws)
- return NULL;
-
- /* Fill in this struct with callbacks that pipe will need to
- * communicate with the window system, buffer manager, etc.
- */
- ws->Base.buffer_create = buffer_create;
- ws->Base.user_buffer_create = user_buffer_create;
- ws->Base.buffer_map = buffer_map;
- ws->Base.buffer_unmap = buffer_unmap;
- ws->Base.buffer_destroy = buffer_destroy;
-
- ws->Base.surface_buffer_create = surface_buffer_create;
-
- ws->Base.fence_reference = fence_reference;
- ws->Base.fence_signalled = fence_signalled;
- ws->Base.fence_finish = fence_finish;
-
- ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
-
- ws->Base.get_name = get_name;
-
- return &ws->Base;
-}
diff --git a/src/gallium/state_trackers/egl/x11/sw_winsys.h b/src/gallium/state_trackers/egl/x11/sw_winsys.h
deleted file mode 100644
index f96c5a14b0a..00000000000
--- a/src/gallium/state_trackers/egl/x11/sw_winsys.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef SW_WINSYS_H
-#define SW_WINSYS_H
-
-
-struct pipe_winsys;
-
-
-extern struct pipe_winsys *
-create_sw_winsys(void);
-
-
-#endif /* SW_WINSYS_H */
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index d72bfc99d3e..f4096114844 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -39,6 +39,9 @@
#include "glxinit.h"
struct x11_screen {
+ /* dummy base class */
+ struct __GLXDRIdisplayRec base;
+
Display *dpy;
int number;
@@ -53,6 +56,9 @@ struct x11_screen {
char *dri_device;
int dri_fd;
+ x11_drawable_invalidate_buffers dri_invalidate_buffers;
+ void *dri_user_data;
+
XVisualInfo *visuals;
int num_visuals;
@@ -98,6 +104,8 @@ x11_screen_destroy(struct x11_screen *xscr)
Xfree(xscr->dri_device);
/* xscr->glx_dpy will be destroyed with the X display */
+ if (xscr->glx_dpy)
+ xscr->glx_dpy->dri2Display = NULL;
if (xscr->visuals)
XFree(xscr->visuals);
@@ -247,24 +255,25 @@ x11_screen_get_glx_visuals(struct x11_screen *xscr)
: NULL;
}
-static boolean
-x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
-{
- return (strcmp(xscr->dri_driver, driver) == 0);
-}
-
/**
* Probe the screen for the DRI2 driver name.
*/
const char *
-x11_screen_probe_dri2(struct x11_screen *xscr)
+x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor)
{
+ if (!x11_screen_init_dri2(xscr))
+ return NULL;
+
/* get the driver name and the device name */
if (!xscr->dri_driver) {
if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
&xscr->dri_driver, &xscr->dri_device))
xscr->dri_driver = xscr->dri_device = NULL;
}
+ if (major)
+ *major = xscr->dri_major;
+ if (minor)
+ *minor = xscr->dri_minor;
return xscr->dri_driver;
}
@@ -274,21 +283,17 @@ x11_screen_probe_dri2(struct x11_screen *xscr)
* descriptor will be closed automatically when the screen is destoryed.
*/
int
-x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
+x11_screen_enable_dri2(struct x11_screen *xscr,
+ x11_drawable_invalidate_buffers invalidate_buffers,
+ void *user_data)
{
if (xscr->dri_fd < 0) {
int fd;
drm_magic_t magic;
/* get the driver name and the device name first */
- if (!x11_screen_probe_dri2(xscr))
- return -1;
-
- if (!x11_screen_is_driver_equal(xscr, driver)) {
- _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
- xscr->dri_driver, driver);
+ if (!x11_screen_probe_dri2(xscr, NULL, NULL))
return -1;
- }
fd = open(xscr->dri_device, O_RDWR);
if (fd < 0) {
@@ -310,6 +315,22 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
return -1;
}
+ if (!x11_screen_init_glx(xscr)) {
+ _eglLog(_EGL_WARNING, "failed to initialize GLX");
+ close(fd);
+ return -1;
+ }
+ if (xscr->glx_dpy->dri2Display) {
+ _eglLog(_EGL_WARNING,
+ "display is already managed by another x11 screen");
+ close(fd);
+ return -1;
+ }
+
+ xscr->glx_dpy->dri2Display = (__GLXDRIdisplay *) xscr;
+ xscr->dri_invalidate_buffers = invalidate_buffers;
+ xscr->dri_user_data = user_data;
+
xscr->dri_fd = fd;
}
@@ -451,3 +472,20 @@ x11_context_modes_count(const __GLcontextModes *modes)
count++;
return count;
}
+
+/**
+ * This is called from src/glx/dri2.c.
+ */
+void
+dri2InvalidateBuffers(Display *dpy, XID drawable)
+{
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+ struct x11_screen *xscr = NULL;
+
+ if (priv && priv->dri2Display)
+ xscr = (struct x11_screen *) priv->dri2Display;
+ if (!xscr || !xscr->dri_invalidate_buffers)
+ return;
+
+ xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data);
+}
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h
index 5432858ac3e..37e8d5a40e6 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.h
@@ -48,6 +48,10 @@ struct x11_drawable_buffer {
struct x11_screen;
+typedef void (*x11_drawable_invalidate_buffers)(struct x11_screen *xscr,
+ Drawable drawable,
+ void *user_data);
+
struct x11_screen *
x11_screen_create(Display *dpy, int screen);
@@ -71,10 +75,12 @@ const __GLcontextModes *
x11_screen_get_glx_visuals(struct x11_screen *xscr);
const char *
-x11_screen_probe_dri2(struct x11_screen *xscr);
+x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
int
-x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
+x11_screen_enable_dri2(struct x11_screen *xscr,
+ x11_drawable_invalidate_buffers invalidate_buffers,
+ void *user_data);
__GLcontextModes *
x11_context_modes_create(unsigned count);
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index fa96df357d5..bb202351509 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -13,8 +13,6 @@ if env['platform'] == 'linux' \
'#/src/mesa/main',
])
- env.Append(CPPDEFINES = ['USE_XSHM'])
-
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
source = [
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 3caf56e924b..24545858500 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -280,7 +280,7 @@ default_depth_bits(void)
int zBits;
const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS");
if (zEnv)
- zBits = _mesa_atoi(zEnv);
+ zBits = atoi(zEnv);
else
zBits = DEFAULT_SOFTWARE_DEPTH_BITS;
return zBits;
@@ -292,7 +292,7 @@ default_alpha_bits(void)
int aBits;
const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS");
if (aEnv)
- aBits = _mesa_atoi(aEnv);
+ aBits = atoi(aEnv);
else
aBits = 0;
return aBits;
@@ -442,17 +442,17 @@ get_env_visual(Display *dpy, int scr, const char *varname)
return NULL;
}
- _mesa_strncpy( value, _mesa_getenv(varname), 100 );
+ strncpy( value, _mesa_getenv(varname), 100 );
value[99] = 0;
sscanf( value, "%s %d", type, &depth );
- if (_mesa_strcmp(type,"TrueColor")==0) xclass = TrueColor;
- else if (_mesa_strcmp(type,"DirectColor")==0) xclass = DirectColor;
- else if (_mesa_strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
- else if (_mesa_strcmp(type,"StaticColor")==0) xclass = StaticColor;
- else if (_mesa_strcmp(type,"GrayScale")==0) xclass = GrayScale;
- else if (_mesa_strcmp(type,"StaticGray")==0) xclass = StaticGray;
+ if (strcmp(type,"TrueColor")==0) xclass = TrueColor;
+ else if (strcmp(type,"DirectColor")==0) xclass = DirectColor;
+ else if (strcmp(type,"PseudoColor")==0) xclass = PseudoColor;
+ else if (strcmp(type,"StaticColor")==0) xclass = StaticColor;
+ else if (strcmp(type,"GrayScale")==0) xclass = GrayScale;
+ else if (strcmp(type,"StaticGray")==0) xclass = StaticGray;
if (xclass>-1 && depth>0) {
vis = get_visual( dpy, scr, depth, xclass );
@@ -689,6 +689,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
int desiredVisualID = -1;
int numAux = 0;
+ xmesa_init( dpy );
+
parselist = list;
while (*parselist) {
@@ -941,9 +943,6 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
/* give the visual some useful GLX attributes */
double_flag = GL_TRUE;
rgb_flag = GL_TRUE;
- depth_size = default_depth_bits();
- stencil_size = STENCIL_BITS;
- /* XXX accum??? */
}
}
else if (level==0) {
@@ -1018,9 +1017,9 @@ glXChooseVisual( Display *dpy, int screen, int *list )
xmvis = choose_visual(dpy, screen, list, GL_FALSE);
if (xmvis) {
/* create a new vishandle - the cached one may be stale */
- xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+ xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
if (xmvis->vishandle) {
- _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+ memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
}
return xmvis->vishandle;
}
@@ -1055,7 +1054,7 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
xmvis = create_glx_visual( dpy, visinfo );
if (!xmvis) {
/* unusable visual */
- _mesa_free(glxCtx);
+ free(glxCtx);
return NULL;
}
}
@@ -1063,7 +1062,7 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- _mesa_free(glxCtx);
+ free(glxCtx);
return NULL;
}
@@ -1336,7 +1335,7 @@ glXDestroyContext( Display *dpy, GLXContext ctx )
MakeCurrent_PrevReadBuffer = 0;
XMesaDestroyContext( glxCtx->xmesaContext );
XMesaGarbageCollect();
- _mesa_free(glxCtx);
+ free(glxCtx);
}
@@ -1679,8 +1678,8 @@ PUBLIC const char *
glXQueryServerString( Display *dpy, int screen, int name )
{
static char version[1000];
- _mesa_sprintf(version, "%d.%d %s",
- SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
+ sprintf(version, "%d.%d %s",
+ SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
(void) dpy;
(void) screen;
@@ -1704,8 +1703,8 @@ PUBLIC const char *
glXGetClientString( Display *dpy, int name )
{
static char version[1000];
- _mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
- CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
+ sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
+ CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
(void) dpy;
@@ -1755,7 +1754,7 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements);
if (*nelements > 0) {
XMesaVisual *results;
- results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual));
+ results = (XMesaVisual *) malloc(*nelements * sizeof(XMesaVisual));
if (!results) {
*nelements = 0;
return NULL;
@@ -1782,7 +1781,7 @@ glXChooseFBConfig( Display *dpy, int screen,
xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
if (xmvis) {
- GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual));
+ GLXFBConfig *config = (GLXFBConfig *) malloc(sizeof(XMesaVisual));
if (!config) {
*nitems = 0;
return NULL;
@@ -1807,9 +1806,9 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
return xmvis->vishandle;
#else
/* create a new vishandle - the cached one may be stale */
- xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo));
+ xmvis->vishandle = (XVisualInfo *) malloc(sizeof(XVisualInfo));
if (xmvis->vishandle) {
- _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
+ memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo));
}
return xmvis->vishandle;
#endif
@@ -2112,7 +2111,7 @@ glXCreateNewContext( Display *dpy, GLXFBConfig config,
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- _mesa_free(glxCtx);
+ free(glxCtx);
return NULL;
}
@@ -2332,7 +2331,7 @@ glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_
glxCtx->xmesaContext = XMesaCreateContext(xmvis,
shareCtx ? shareCtx->xmesaContext : NULL);
if (!glxCtx->xmesaContext) {
- _mesa_free(glxCtx);
+ free(glxCtx);
return NULL;
}
diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index e502198b204..8903b0e6cbd 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -343,7 +343,7 @@ glXUseXFont(Font font, int first, int count, int listbase)
glNewList(list, GL_COMPILE);
if (valid && (bm_width > 0) && (bm_height > 0)) {
- MEMSET(bm, '\0', bm_width * bm_height);
+ memset(bm, '\0', bm_width * bm_height);
fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
glBitmap(width, height, x0, y0, dx, dy, bm);
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index fb314f3b528..f4d7133d2ff 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -35,10 +35,6 @@
* corner of the window. Therefore, most drawing functions in this
* file have to flip Y coordinates.
*
- * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile
- * in support for the MIT Shared Memory extension. If enabled, when you
- * use an Ximage for the back buffer in double buffered mode, the "swap"
- * operation will be faster. You must also link with -lXext.
*
* Byte swapping: If the Mesa host and the X display use a different
* byte order then there's some trickiness to be aware of when using
@@ -67,11 +63,7 @@
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#include "trace/tr_texture.h"
-
-#include "xm_winsys.h"
+#include "xm_public.h"
#include <GL/glx.h>
@@ -91,7 +83,6 @@ void xmesa_set_driver( const struct xm_driver *templ )
*/
pipe_mutex _xmesa_lock;
-static struct pipe_screen *_screen = NULL;
static struct pipe_screen *screen = NULL;
@@ -111,41 +102,6 @@ static int host_byte_order( void )
}
-/**
- * Check if the X Shared Memory extension is available.
- * Return: 0 = not available
- * 1 = shared XImage support available
- * 2 = shared Pixmap support available also
- */
-int xmesa_check_for_xshm( Display *display )
-{
-#if defined(USE_XSHM)
- int major, minor, ignore;
- Bool pixmaps;
-
- if (getenv("SP_NO_RAST"))
- return 0;
-
- if (getenv("MESA_NOSHM")) {
- return 0;
- }
-
- if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
- if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
- return (pixmaps==True) ? 2 : 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
- }
-#else
- /* No XSHM support */
- return 0;
-#endif
-}
/**
@@ -175,7 +131,7 @@ bits_per_pixel( XMesaVisual xmv )
/* grab the bits/pixel value */
bitsPerPixel = img->bits_per_pixel;
/* free the XImage */
- _mesa_free( img->data );
+ free( img->data );
img->data = NULL;
XDestroyImage( img );
return bitsPerPixel;
@@ -242,7 +198,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
pipe_mutex_lock(_xmesa_lock);
XSync(b->xm_visual->display, 0); /* added for Chromium */
- stat = get_drawable_size(dpy, b->drawable, width, height);
+ stat = get_drawable_size(dpy, b->ws.drawable, width, height);
pipe_mutex_unlock(_xmesa_lock);
if (!stat) {
@@ -274,10 +230,10 @@ choose_pixel_format(XMesaVisual v)
&& v->BitsPerPixel == 32) {
if (native_byte_order) {
/* no byteswapping needed */
- return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */;
+ return PIPE_FORMAT_R8G8B8A8_UNORM;
}
else {
- return PIPE_FORMAT_R8G8B8A8_UNORM;
+ return PIPE_FORMAT_A8B8G8R8_UNORM;
}
}
else if ( GET_REDMASK(v) == 0xff0000
@@ -286,10 +242,10 @@ choose_pixel_format(XMesaVisual v)
&& v->BitsPerPixel == 32) {
if (native_byte_order) {
/* no byteswapping needed */
- return PIPE_FORMAT_A8R8G8B8_UNORM;
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
}
else {
- return PIPE_FORMAT_B8G8R8A8_UNORM;
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
}
}
else if ( GET_REDMASK(v) == 0x0000ff00
@@ -298,10 +254,10 @@ choose_pixel_format(XMesaVisual v)
&& v->BitsPerPixel == 32) {
if (native_byte_order) {
/* no byteswapping needed */
- return PIPE_FORMAT_B8G8R8A8_UNORM;
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
}
else {
- return PIPE_FORMAT_A8R8G8B8_UNORM;
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
}
}
else if ( GET_REDMASK(v) == 0xf800
@@ -310,7 +266,7 @@ choose_pixel_format(XMesaVisual v)
&& native_byte_order
&& v->BitsPerPixel == 16) {
/* 5-6-5 RGB */
- return PIPE_FORMAT_R5G6B5_UNORM;
+ return PIPE_FORMAT_B5G6R5_UNORM;
}
assert(0);
@@ -319,6 +275,51 @@ choose_pixel_format(XMesaVisual v)
+/**
+ * Query the default gallium screen for a Z/Stencil format that
+ * at least matches the given depthBits and stencilBits.
+ */
+static void
+xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
+ enum pipe_format *depthFormat,
+ enum pipe_format *stencilFormat)
+{
+ const enum pipe_texture_target target = PIPE_TEXTURE_2D;
+ const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
+ const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
+ PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
+ static enum pipe_format formats[] = {
+ PIPE_FORMAT_S8Z24_UNORM,
+ PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_FORMAT_Z16_UNORM,
+ PIPE_FORMAT_Z32_UNORM
+ };
+ int i;
+
+ assert(screen);
+
+ *depthFormat = *stencilFormat = PIPE_FORMAT_NONE;
+
+ /* search for supported format */
+ for (i = 0; i < Elements(formats); i++) {
+ if (screen->is_format_supported(screen, formats[i],
+ target, tex_usage, geom_flags)) {
+ *depthFormat = formats[i];
+ break;
+ }
+ }
+
+ if (stencilBits) {
+ *stencilFormat = *depthFormat;
+ }
+
+ /* XXX we should check that he chosen format has at least as many bits
+ * as what was requested.
+ */
+}
+
+
+
/**********************************************************************/
/***** Linked list of XMesaBuffers *****/
/**********************************************************************/
@@ -352,7 +353,9 @@ create_xmesa_buffer(Drawable d, BufferType type,
if (!b)
return NULL;
- b->drawable = d;
+ b->ws.drawable = d;
+ b->ws.visual = vis->visinfo->visual;
+ b->ws.depth = vis->visinfo->depth;
b->xm_visual = vis;
b->type = type;
@@ -361,34 +364,9 @@ create_xmesa_buffer(Drawable d, BufferType type,
/* determine PIPE_FORMATs for buffers */
colorFormat = choose_pixel_format(vis);
- if (vis->mesa_visual.depthBits == 0)
- depthFormat = PIPE_FORMAT_NONE;
-#ifdef GALLIUM_CELL /* XXX temporary for Cell! */
- else
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
-#else
- else if (vis->mesa_visual.depthBits <= 16)
- depthFormat = PIPE_FORMAT_Z16_UNORM;
- else if (vis->mesa_visual.depthBits <= 24)
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
- else
- depthFormat = PIPE_FORMAT_Z32_UNORM;
-#endif
-
- if (vis->mesa_visual.stencilBits == 8) {
- if (depthFormat == PIPE_FORMAT_S8Z24_UNORM)
- stencilFormat = depthFormat;
- else
- stencilFormat = PIPE_FORMAT_S8_UNORM;
- }
- else {
- /* no stencil */
- stencilFormat = PIPE_FORMAT_NONE;
- if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) {
- /* use 24-bit Z, undefined stencil channel */
- depthFormat = PIPE_FORMAT_X8Z24_UNORM;
- }
- }
+ xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
+ vis->mesa_visual.stencilBits,
+ &depthFormat, &stencilFormat);
get_drawable_size(vis->display, d, &width, &height);
@@ -402,18 +380,6 @@ create_xmesa_buffer(Drawable d, BufferType type,
(void *) b);
fb = &b->stfb->Base;
- /*
- * Create scratch XImage for xmesa_display_surface()
- */
- b->tempImage = XCreateImage(vis->display,
- vis->visinfo->visual,
- vis->visinfo->depth,
- ZPixmap, 0, /* format, offset */
- NULL, /* data */
- 0, 0, /* size */
- 32, /* bitmap_pad */
- 0); /* bytes_per_line */
-
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT;
@@ -470,16 +436,11 @@ xmesa_free_buffer(XMesaBuffer buffer)
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
- b->drawable = 0;
-
- buffer->tempImage->data = NULL;
- XDestroyImage(buffer->tempImage);
+ b->ws.drawable = 0;
/* Unreference. If count = zero we'll really delete the buffer */
_mesa_reference_framebuffer(&fb, NULL);
- XFreeGC(b->xm_visual->display, b->gc);
-
free(buffer);
return;
@@ -550,25 +511,10 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b,
* reports bugs.
*/
if (_mesa_getenv("MESA_INFO")) {
- _mesa_printf("X/Mesa visual = %p\n", (void *) v);
- _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level);
- _mesa_printf("X/Mesa depth = %d\n", v->visinfo->depth);
- _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
- }
-
- if (b && window) {
- /* these should have been set in create_xmesa_buffer */
- ASSERT(b->drawable == window);
-
- /* Setup for single/double buffering */
- if (v->mesa_visual.doubleBufferMode) {
- /* Double buffered */
- b->shm = xmesa_check_for_xshm( v->display );
- }
-
- /* X11 graphics context */
- b->gc = XCreateGC( v->display, window, 0, NULL );
- XSetFunction( v->display, b->gc, GXcopy );
+ printf("X/Mesa visual = %p\n", (void *) v);
+ printf("X/Mesa level = %d\n", v->mesa_visual.level);
+ printf("X/Mesa depth = %d\n", v->visinfo->depth);
+ printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel);
}
return GL_TRUE;
@@ -653,6 +599,8 @@ XMesaVisual XMesaCreateVisual( Display *display,
XMesaVisual v;
GLint red_bits, green_bits, blue_bits, alpha_bits;
+ xmesa_init( display );
+
/* For debugging only */
if (_mesa_getenv("MESA_XSYNC")) {
/* This makes debugging X easier.
@@ -669,16 +617,16 @@ XMesaVisual XMesaCreateVisual( Display *display,
v->display = display;
- /* Save a copy of the XVisualInfo struct because the user may X_mesa_free()
+ /* Save a copy of the XVisualInfo struct because the user may Xfree()
* the struct but we may need some of the information contained in it
* at a later time.
*/
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
if (!v->visinfo) {
- _mesa_free(v);
+ free(v);
return NULL;
}
- MEMCPY(v->visinfo, visinfo, sizeof(*visinfo));
+ memcpy(v->visinfo, visinfo, sizeof(*visinfo));
v->ximage_flag = ximage_flag;
@@ -724,10 +672,9 @@ XMesaVisual XMesaCreateVisual( Display *display,
}
_mesa_initialize_visual( &v->mesa_visual,
- rgb_flag, db_flag, stereo_flag,
+ db_flag, stereo_flag,
red_bits, green_bits,
blue_bits, alpha_bits,
- v->mesa_visual.indexBits,
depth_size,
stencil_size,
accum_red_size, accum_green_size,
@@ -743,11 +690,25 @@ XMesaVisual XMesaCreateVisual( Display *display,
PUBLIC
void XMesaDestroyVisual( XMesaVisual v )
{
- _mesa_free(v->visinfo);
- _mesa_free(v);
+ free(v->visinfo);
+ free(v);
}
+/**
+ * Do one-time initializations.
+ */
+void
+xmesa_init( Display *display )
+{
+ static GLboolean firstTime = GL_TRUE;
+ if (firstTime) {
+ pipe_mutex_init(_xmesa_lock);
+ screen = driver.create_pipe_screen( display );
+ firstTime = GL_FALSE;
+ }
+}
+
/**
* Create a new XMesaContext.
@@ -759,18 +720,12 @@ void XMesaDestroyVisual( XMesaVisual v )
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
- static GLboolean firstTime = GL_TRUE;
struct pipe_context *pipe = NULL;
XMesaContext c;
GLcontext *mesaCtx;
uint pf;
- if (firstTime) {
- pipe_mutex_init(_xmesa_lock);
- _screen = driver.create_pipe_screen();
- screen = trace_screen_create( _screen );
- firstTime = GL_FALSE;
- }
+ xmesa_init( v->display );
/* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */
c = (XMesaContext) CALLOC_STRUCT(xmesa_context);
@@ -811,7 +766,7 @@ fail:
else if (pipe)
pipe->destroy(pipe);
- _mesa_free(c);
+ free(c);
return NULL;
}
@@ -828,7 +783,7 @@ void XMesaDestroyContext( XMesaContext c )
screen->destroy(screen);
*/
- _mesa_free(c);
+ free(c);
}
@@ -1065,7 +1020,8 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
- st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb);
+ st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb,
+ &drawBuffer->ws);
xmesa_check_and_update_buffer_size(c, drawBuffer);
if (readBuffer != drawBuffer)
@@ -1076,7 +1032,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
}
else {
/* Detach */
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
}
return GL_TRUE;
@@ -1119,13 +1075,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
if (frontLeftSurf) {
- if (_screen != screen) {
- struct trace_surface *tr_surf = trace_surface( frontLeftSurf );
- struct pipe_surface *surf = tr_surf->surface;
- frontLeftSurf = surf;
- }
-
- driver.display_surface(b, frontLeftSurf);
+ screen->flush_frontbuffer( screen,
+ frontLeftSurf,
+ &b->ws );
}
xmesa_check_and_update_buffer_size(NULL, b);
@@ -1148,6 +1100,7 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
if (!surf_front || !surf_back)
return;
+ assert(pipe);
pipe->surface_copy(pipe,
surf_front, x, y, /* dest */
surf_back, x, y, /* src */
@@ -1172,7 +1125,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
for (b = XMesaBufferList; b; b = b->Next) {
- if (b->drawable == d && b->xm_visual->display == dpy) {
+ if (b->ws.drawable == d && b->xm_visual->display == dpy) {
return b;
}
}
@@ -1206,10 +1159,10 @@ void XMesaGarbageCollect( void )
next = b->Next;
if (b->xm_visual &&
b->xm_visual->display &&
- b->drawable &&
+ b->ws.drawable &&
b->type == WINDOW) {
XSync(b->xm_visual->display, False);
- if (!window_exists( b->xm_visual->display, b->drawable )) {
+ if (!window_exists( b->xm_visual->display, b->ws.drawable )) {
/* found a dead window, free the ancillary info */
XMesaDestroyBuffer( b );
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 63a329cbe05..de47064b410 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -62,15 +62,11 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "state_tracker/st_public.h"
#include "os/os_thread.h"
+#include "state_tracker/xlib_sw_winsys.h"
# include <X11/Xlib.h>
# include <X11/Xlibint.h>
# include <X11/Xutil.h>
-# ifdef USE_XSHM /* was SHM */
-# include <sys/ipc.h>
-# include <sys/shm.h>
-# include <X11/extensions/XShm.h>
-# endif
typedef struct xmesa_buffer *XMesaBuffer;
typedef struct xmesa_context *XMesaContext;
@@ -316,6 +312,7 @@ typedef enum {
*/
struct xmesa_buffer {
struct st_framebuffer *stfb;
+ struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
XMesaVisual xm_visual; /* the X/Mesa visual */
@@ -329,13 +326,6 @@ struct xmesa_buffer {
XImage *tempImage;
unsigned long selectedEvents;/* for pbuffers only */
- GLuint shm; /* X Shared Memory extension status: */
- /* 0 = not available */
- /* 1 = XImage support available */
- /* 2 = Pixmap support available too */
-#if defined(USE_XSHM)
- XShmSegmentInfo shminfo;
-#endif
GC gc; /* scratch GC for span, line, tri drawing */
@@ -367,6 +357,9 @@ xmesa_buffer(GLframebuffer *fb)
extern void
+xmesa_init(Display *dpy);
+
+extern void
xmesa_delete_framebuffer(struct gl_framebuffer *fb);
extern XMesaBuffer
@@ -394,8 +387,6 @@ xmesa_buffer_height(XMesaBuffer b)
return b->stfb->Base.Height;
}
-extern int
-xmesa_check_for_xshm(Display *display);
#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_winsys.h b/src/gallium/state_trackers/glx/xlib/xm_public.h
index 4bd5b5c8d3b..ac6a8ffb27a 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_winsys.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_public.h
@@ -29,22 +29,14 @@
#ifndef XM_WINSYS_H
#define XM_WINSYS_H
-struct pipe_context;
-struct pipe_screen;
-struct pipe_surface;
-struct xmesa_buffer;
-
+struct xm_driver;
+/* This is the driver interface required by the glx/xlib state tracker.
+ */
struct xm_driver {
-
- struct pipe_screen *(*create_pipe_screen)( void );
-
- void (*display_surface)( struct xmesa_buffer *,
- struct pipe_surface * );
-
+ struct pipe_screen *(*create_pipe_screen)( Display *display );
};
-
extern void
xmesa_set_driver( const struct xm_driver *driver );
diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README
index 4a060730242..e24a262aba9 100644
--- a/src/gallium/state_trackers/python/README
+++ b/src/gallium/state_trackers/python/README
@@ -18,7 +18,7 @@ On a Windows machine ensure the swig command is in your PATH.
Invoke scons on the top dir as
- scons debug=yes statetrackers=python drivers=softpipe,trace winsys=none
+ scons debug=yes statetrackers=python drivers=softpipe winsys=none
To use it set PYTHONPATH appropriately, e.g, in Linux do:
diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript
index 527e065cd91..781f54bf2b9 100644
--- a/src/gallium/state_trackers/python/SConscript
+++ b/src/gallium/state_trackers/python/SConscript
@@ -24,6 +24,7 @@ if 'python' in env['statetrackers']:
'ws2_32',
])
else:
+ env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY'])
env.Append(LIBS = [
'GL',
'X11',
@@ -33,31 +34,27 @@ if 'python' in env['statetrackers']:
'gallium.i',
'st_device.c',
'st_sample.c',
+ 'st_hardpipe_winsys.c',
+ 'st_softpipe_winsys.c',
]
- drivers = [
- trace
- ]
+ env.Prepend(LIBS = [
+ ws_null,
+ trace,
+ gallium,
+ ])
if 'llvmpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_LLVMPIPE'])
env.Tool('llvm')
- sources += ['st_llvmpipe_winsys.c']
- drivers += [llvmpipe]
- else:
- sources += ['st_softpipe_winsys.c']
- drivers += [softpipe]
-
- pyst = env.ConvenienceLibrary(
- target = 'pyst',
- source = sources,
- )
+ env.Prepend(LIBS = [llvmpipe])
+ if 'softpipe' in env['drivers']:
+ env.Append(CPPDEFINES = ['HAVE_SOFTPIPE'])
+ env.Prepend(LIBS = [softpipe])
env['no_import_lib'] = 1
env.SharedLibrary(
target = '_gallium',
- source = [
- 'st_hardpipe_winsys.c',
- ],
- LIBS = [pyst] + drivers + gallium + env['LIBS'],
+ source = sources,
)
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 85c9598d069..df700bc663c 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -51,7 +51,7 @@ struct st_context {
void set_blend( const struct pipe_blend_state *state ) {
cso_set_blend($self->cso, state);
}
-
+
void set_fragment_sampler( unsigned index, const struct pipe_sampler_state *state ) {
cso_single_sampler($self->cso, index, state);
cso_single_sampler_done($self->cso);
@@ -239,9 +239,9 @@ struct st_context {
void set_vertex_elements(unsigned num)
{
$self->num_vertex_elements = num;
- $self->pipe->set_vertex_elements($self->pipe,
- $self->num_vertex_elements,
- $self->vertex_elements);
+ cso_set_vertex_elements($self->cso,
+ $self->num_vertex_elements,
+ $self->vertex_elements);
}
/*
diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c
index d5a14fd795d..0d87c705e75 100644
--- a/src/gallium/state_trackers/python/st_device.c
+++ b/src/gallium/state_trackers/python/st_device.c
@@ -35,8 +35,7 @@
#include "util/u_memory.h"
#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
+#include "trace/tr_public.h"
#include "st_device.h"
#include "st_winsys.h"
@@ -76,43 +75,34 @@ st_device_destroy(struct st_device *st_dev)
}
-static struct st_device *
-st_device_create_from_st_winsys(const struct st_winsys *st_ws)
+struct st_device *
+st_device_create(boolean hardware)
{
+ struct pipe_screen *screen;
struct st_device *st_dev;
-
- if(!st_ws->screen_create)
- return NULL;
-
+
+ if (hardware)
+ screen = st_hardware_screen_create();
+ else
+ screen = st_software_screen_create();
+
+ screen = trace_screen_create(screen);
+ if (!screen)
+ goto no_screen;
+
st_dev = CALLOC_STRUCT(st_device);
- if(!st_dev)
- return NULL;
+ if (!st_dev)
+ goto no_device;
pipe_reference_init(&st_dev->reference, 1);
- st_dev->st_ws = st_ws;
-
- st_dev->real_screen = st_ws->screen_create();
- if(!st_dev->real_screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
-
- st_dev->screen = trace_screen_create(st_dev->real_screen);
- if(!st_dev->screen) {
- st_device_destroy(st_dev);
- return NULL;
- }
+ st_dev->screen = screen;
return st_dev;
-}
-
-struct st_device *
-st_device_create(boolean hardware) {
- if(hardware)
- return st_device_create_from_st_winsys(&st_hardpipe_winsys);
- else
- return st_device_create_from_st_winsys(&st_softpipe_winsys);
+no_device:
+ screen->destroy(screen);
+no_screen:
+ return NULL;
}
@@ -247,7 +237,7 @@ st_context_create(struct st_device *st_dev)
memset( &templat, 0, sizeof( templat ) );
templat.target = PIPE_TEXTURE_2D;
- templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templat.width0 = 1;
templat.height0 = 1;
templat.depth0 = 1;
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
index dee9a8ca7b5..dcd0dc6e273 100644
--- a/src/gallium/state_trackers/python/st_device.h
+++ b/src/gallium/state_trackers/python/st_device.h
@@ -47,7 +47,8 @@ struct st_surface
};
-struct st_context {
+struct st_context
+{
struct st_device *st_dev;
struct pipe_context *pipe;
@@ -72,13 +73,11 @@ struct st_context {
};
-struct st_device {
+struct st_device
+{
/* FIXME: we also need to refcount for textures and surfaces... */
struct pipe_reference reference;
- const struct st_winsys *st_ws;
-
- struct pipe_screen *real_screen;
struct pipe_screen *screen;
};
diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
index a3110a19d5d..b141177b793 100644
--- a/src/gallium/state_trackers/python/st_hardpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c
@@ -54,11 +54,6 @@ static PFNGETGALLIUMSCREENMESAPROC pfnGetGalliumScreenMESA = NULL;
static PFNCREATEGALLIUMCONTEXTMESAPROC pfnCreateGalliumContextMESA = NULL;
-/* XXX: Force init_gallium symbol to be linked */
-extern void init_gallium(void);
-void (*force_init_gallium_linkage)(void) = &init_gallium;
-
-
#ifdef PIPE_OS_WINDOWS
static INLINE boolean
@@ -207,16 +202,11 @@ st_hardpipe_load(void)
#endif
-static struct pipe_screen *
-st_hardpipe_screen_create(void)
+struct pipe_screen *
+st_hardware_screen_create(void)
{
if(st_hardpipe_load())
return pfnGetGalliumScreenMESA();
else
- return st_softpipe_winsys.screen_create();
+ return st_software_screen_create();
}
-
-
-const struct st_winsys st_hardpipe_winsys = {
- &st_hardpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c b/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
deleted file mode 100644
index 5d83b5a9e15..00000000000
--- a/src/gallium/state_trackers/python/st_llvmpipe_winsys.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- *
- **************************************************************************/
-
-/**
- * @file
- * Llvmpipe support.
- *
- * @author Jose Fonseca
- */
-
-
-#include "pipe/p_format.h"
-#include "pipe/p_context.h"
-#include "util/u_inlines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "llvmpipe/lp_winsys.h"
-#include "st_winsys.h"
-
-
-static boolean
-llvmpipe_ws_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
- enum pipe_format format )
-{
- return FALSE;
-}
-
-
-static void *
-llvmpipe_ws_displaytarget_map(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt,
- unsigned flags )
-{
- assert(0);
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_unmap(struct llvmpipe_winsys *ws,
- struct llvmpipe_displaytarget *dt )
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_displaytarget_destroy(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt)
-{
- assert(0);
-}
-
-
-static struct llvmpipe_displaytarget *
-llvmpipe_ws_displaytarget_create(struct llvmpipe_winsys *winsys,
- enum pipe_format format,
- unsigned width, unsigned height,
- unsigned alignment,
- unsigned *stride)
-{
- return NULL;
-}
-
-
-static void
-llvmpipe_ws_displaytarget_display(struct llvmpipe_winsys *winsys,
- struct llvmpipe_displaytarget *dt,
- void *context_private)
-{
- assert(0);
-}
-
-
-static void
-llvmpipe_ws_destroy(struct llvmpipe_winsys *winsys)
-{
- FREE(winsys);
-}
-
-
-static struct pipe_screen *
-st_llvmpipe_screen_create(void)
-{
- static struct llvmpipe_winsys *winsys;
- struct pipe_screen *screen;
-
- winsys = CALLOC_STRUCT(llvmpipe_winsys);
- if (!winsys)
- goto no_winsys;
-
- winsys->destroy = llvmpipe_ws_destroy;
- winsys->is_displaytarget_format_supported = llvmpipe_ws_is_displaytarget_format_supported;
- winsys->displaytarget_create = llvmpipe_ws_displaytarget_create;
- winsys->displaytarget_map = llvmpipe_ws_displaytarget_map;
- winsys->displaytarget_unmap = llvmpipe_ws_displaytarget_unmap;
- winsys->displaytarget_display = llvmpipe_ws_displaytarget_display;
- winsys->displaytarget_destroy = llvmpipe_ws_displaytarget_destroy;
-
- screen = llvmpipe_create_screen(winsys);
- if (!screen)
- goto no_screen;
-
- return screen;
-
-no_screen:
- FREE(winsys);
-no_winsys:
- return NULL;
-}
-
-
-
-const struct st_winsys st_softpipe_winsys = {
- &st_llvmpipe_screen_create
-};
diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c
index 32a6551a87a..e1808153461 100644
--- a/src/gallium/state_trackers/python/st_sample.c
+++ b/src/gallium/state_trackers/python/st_sample.c
@@ -485,7 +485,7 @@ st_sample_generic_pixel_block(enum pipe_format format,
w, h,
rgba, rgba_stride);
- if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) {
+ if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
for(y = 0; y < h; ++y) {
for(x = 0; x < w; ++x) {
for(ch = 0; ch < 4; ++ch) {
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 81676bc3a4f..985374190c3 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -26,18 +26,47 @@
*
**************************************************************************/
-/**
- * @file
- * Softpipe support.
- *
- * @author Keith Whitwell
- * @author Brian Paul
- * @author Jose Fonseca
- */
-
-#include "softpipe/sp_winsys.h"
+#include "util/u_debug.h"
+#include "softpipe/sp_public.h"
+#include "llvmpipe/lp_public.h"
+#include "state_tracker/sw_winsys.h"
+#include "null/null_sw_winsys.h"
#include "st_winsys.h"
-const struct st_winsys st_softpipe_winsys = {
- &softpipe_create_screen_malloc
-};
+
+struct pipe_screen *
+st_software_screen_create(void)
+{
+ struct sw_winsys *ws;
+ const char *default_driver;
+ const char *driver;
+ struct pipe_screen *screen = NULL;
+
+#if defined(HAVE_LLVMPIPE)
+ default_driver = "llvmpipe";
+#elif defined(HAVE_SOFTPIPE)
+ default_driver = "softpipe";
+#else
+ default_driver = "";
+#endif
+
+ ws = null_sw_create();
+ if(!ws)
+ return NULL;
+
+ driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#ifdef HAVE_LLVMPIPE
+ if (strcmp(driver, "llvmpipe") == 0) {
+ screen = llvmpipe_create_screen(ws);
+ }
+#endif
+
+#ifdef HAVE_SOFTPIPE
+ if (strcmp(driver, "softpipe") == 0) {
+ screen = softpipe_create_screen(ws);
+ }
+#endif
+
+ return screen;
+}
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
index 0c7b6a200e1..e1a99383a41 100644
--- a/src/gallium/state_trackers/python/st_winsys.h
+++ b/src/gallium/state_trackers/python/st_winsys.h
@@ -31,19 +31,13 @@
struct pipe_screen;
-struct pipe_context;
-struct st_winsys
-{
- struct pipe_screen *
- (*screen_create)(void);
-};
+struct pipe_screen *
+st_hardware_screen_create(void);
-
-extern const struct st_winsys st_softpipe_winsys;
-
-extern const struct st_winsys st_hardpipe_winsys;
+struct pipe_screen *
+st_software_screen_create(void);
#endif /* ST_WINSYS_H_ */
diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile
index 037d8dc911a..7f04b2aa832 100644
--- a/src/gallium/state_trackers/vega/Makefile
+++ b/src/gallium/state_trackers/vega/Makefile
@@ -53,7 +53,7 @@ INCLUDE_DIRS = \
.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend $(TOP)/$(LIB_DIR)/$(VG_LIB_NAME)
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 20c72c1ff54..02248ad4337 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -67,7 +67,7 @@ static INLINE struct pipe_texture *create_texture_1d(struct vg_context *ctx,
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_1D;
- templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templ.last_level = 0;
templ.width0 = color_data_len;
templ.height0 = 1;
diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c
index 9c123a4cf95..7eb5ea1f078 100644
--- a/src/gallium/state_trackers/vega/api_masks.c
+++ b/src/gallium/state_trackers/vega/api_masks.c
@@ -86,6 +86,8 @@ draw_clear_quad(struct vg_context *st,
/* draw */
if (buf) {
+ cso_set_vertex_elements(st->cso_context, 2, st->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c
index 2e10965be4f..41c979bfecf 100644
--- a/src/gallium/state_trackers/vega/image.c
+++ b/src/gallium/state_trackers/vega/image.c
@@ -48,16 +48,16 @@ static enum pipe_format vg_format_to_pipe(VGImageFormat format)
{
switch(format) {
case VG_sRGB_565:
- return PIPE_FORMAT_R5G6B5_UNORM;
+ return PIPE_FORMAT_B5G6R5_UNORM;
case VG_sRGBA_5551:
- return PIPE_FORMAT_A1R5G5B5_UNORM;
+ return PIPE_FORMAT_B5G5R5A1_UNORM;
case VG_sRGBA_4444:
- return PIPE_FORMAT_A4R4G4B4_UNORM;
+ return PIPE_FORMAT_B4G4R4A4_UNORM;
case VG_sL_8:
case VG_lL_8:
return PIPE_FORMAT_L8_UNORM;
case VG_BW_1:
- return PIPE_FORMAT_A8R8G8B8_UNORM;
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
case VG_A_8:
return PIPE_FORMAT_A8_UNORM;
#ifdef OPENVG_VERSION_1_1
@@ -66,7 +66,7 @@ static enum pipe_format vg_format_to_pipe(VGImageFormat format)
return PIPE_FORMAT_A8_UNORM;
#endif
default:
- return PIPE_FORMAT_A8R8G8B8_UNORM;
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
}
}
diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c
index 467b95b7519..839dc19a3b8 100644
--- a/src/gallium/state_trackers/vega/mask.c
+++ b/src/gallium/state_trackers/vega/mask.c
@@ -488,7 +488,7 @@ struct vg_mask_layer * mask_layer_create(VGint width, VGint height)
memset(&pt, 0, sizeof(pt));
pt.target = PIPE_TEXTURE_2D;
- pt.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ pt.format = PIPE_FORMAT_B8G8R8A8_UNORM;
pt.last_level = 0;
pt.width0 = width;
pt.height0 = height;
diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c
index 3405d635f0c..cdb87d3bf68 100644
--- a/src/gallium/state_trackers/vega/paint.c
+++ b/src/gallium/state_trackers/vega/paint.c
@@ -151,7 +151,7 @@ static INLINE struct pipe_texture *create_gradient_texture(struct vg_paint *p)
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_1D;
- templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templ.last_level = 0;
templ.width0 = 1024;
templ.height0 = 1;
@@ -639,9 +639,6 @@ VGint paint_bind_samplers(struct vg_paint *paint, struct pipe_sampler_state **sa
}
break;
default:
- samplers[0] = &paint->pattern.sampler; /* dummy */
- textures[0] = 0;
- return 0;
break;
}
return 0;
diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c
index c06dbf52069..eef2c1eb876 100644
--- a/src/gallium/state_trackers/vega/polygon.c
+++ b/src/gallium/state_trackers/vega/polygon.c
@@ -292,12 +292,12 @@ static void draw_polygon(struct vg_context *ctx,
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
+ memset(&velement, 0, sizeof(velement));
velement.src_offset = 0;
velement.instance_divisor = 0;
velement.vertex_buffer_index = 0;
velement.src_format = PIPE_FORMAT_R32G32_FLOAT;
- velement.nr_components = COMPONENTS;
- pipe->set_vertex_elements(pipe, 1, &velement);
+ cso_set_vertex_elements(ctx->cso_context, 1, &velement);
/* draw */
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index 05620efa9c0..47e8b470a11 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -210,6 +210,7 @@ void renderer_draw_quad(struct renderer *r,
buf = setup_vertex_data(r, x1, y1, x2, y2, depth);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(r->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -248,6 +249,7 @@ void renderer_draw_texture(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -370,6 +372,7 @@ void renderer_copy_texture(struct renderer *ctx,
0.0f);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -535,6 +538,7 @@ void renderer_copy_surface(struct renderer *ctx,
(float) dstX1, (float) dstY1, z);
if (buf) {
+ cso_set_vertex_elements(ctx->cso, 2, ctx->owner->velems);
util_draw_vertex_buffer(ctx->pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -587,6 +591,7 @@ void renderer_texture_quad(struct renderer *r,
s0, t0, s1, t1, 0.0f);
if (buf) {
+ cso_set_vertex_elements(r->cso, 2, r->owner->velems);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c
index 426bf9bc62b..170391ec031 100644
--- a/src/gallium/state_trackers/vega/vg_context.c
+++ b/src/gallium/state_trackers/vega/vg_context.c
@@ -72,6 +72,7 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
struct vg_context *share)
{
struct vg_context *ctx;
+ unsigned i;
ctx = CALLOC_STRUCT(vg_context);
@@ -103,6 +104,13 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
ctx->blend_sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
ctx->blend_sampler.normalized_coords = 0;
+ for (i = 0; i < 2; i++) {
+ ctx->velems[i].src_offset = i * 4 * sizeof(float);
+ ctx->velems[i].instance_divisor = 0;
+ ctx->velems[i].vertex_buffer_index = 0;
+ ctx->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
+
vg_set_error(ctx, VG_NO_ERROR);
ctx->owned_objects[VG_OBJECT_PAINT] = cso_hash_create();
diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h
index bc88c8d139d..804e9e76d77 100644
--- a/src/gallium/state_trackers/vega/vg_context.h
+++ b/src/gallium/state_trackers/vega/vg_context.h
@@ -146,6 +146,7 @@ struct vg_context
struct vg_shader *clear_vs;
struct vg_shader *texture_vs;
struct pipe_buffer *vs_const_buffer;
+ struct pipe_vertex_element velems[2];
};
struct vg_object {
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index a94dfb160c9..a002e50faf7 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -51,7 +51,7 @@ create_texture(struct pipe_context *pipe, enum pipe_format format,
templ.format = format;
}
else {
- templ.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
}
templ.target = PIPE_TEXTURE_2D;
@@ -186,7 +186,7 @@ struct st_framebuffer * st_create_framebuffer(const void *visual,
if (stencilFormat == depthFormat)
stfb->dsrb = st_new_renderbuffer_fb(stencilFormat);
else
- stfb->dsrb = st_new_renderbuffer_fb(PIPE_FORMAT_S8Z24_UNORM);
+ stfb->dsrb = st_new_renderbuffer_fb(PIPE_FORMAT_Z24S8_UNORM);
/*### currently we always allocate it but it's possible it's
not necessary if EGL_ALPHA_MASK_SIZE was 0
@@ -209,12 +209,12 @@ static void setup_new_alpha_mask(struct vg_context *ctx,
struct pipe_texture *old_texture = stfb->alpha_mask;
/*
- we use PIPE_FORMAT_A8R8G8B8_UNORM because we want to render to
+ we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
this texture and use it as a sampler, so while this wastes some
space it makes both of those a lot simpler
*/
stfb->alpha_mask =
- create_texture(pipe, PIPE_FORMAT_A8R8G8B8_UNORM, width, height);
+ create_texture(pipe, PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
if (!stfb->alpha_mask) {
if (old_texture)
@@ -327,7 +327,7 @@ void st_resize_framebuffer(struct st_framebuffer *stfb,
setup_new_alpha_mask(ctx, stfb, width, height);
pipe_texture_reference( &stfb->blend_texture, NULL );
- stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_A8R8G8B8_UNORM,
+ stfb->blend_texture = create_texture(ctx->pipe, PIPE_FORMAT_B8G8R8A8_UNORM,
width, height);
}
@@ -376,11 +376,19 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb)
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read)
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle)
{
vg_set_current_context(st);
if (st) {
st->draw_buffer = draw;
+
+ /* VG state tracker doesn't seem to do front-buffer rendering
+ * (no calls to flush_frontbuffer). If it ever did start doing
+ * that, it would need to pass this value down in the
+ * flush_frontbuffer call:
+ */
+ st->pipe->priv = winsys_drawable_handle;
}
return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index c1196954a76..165a6b7a332 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -101,7 +101,8 @@ void st_unreference_framebuffer(struct st_framebuffer *stfb);
PUBLIC
boolean st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
- struct st_framebuffer *read);
+ struct st_framebuffer *read,
+ void *winsys_drawable_handle);
PUBLIC
struct vg_context *st_get_current(void);
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 05ccd5febcf..1f11b649c3e 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -226,7 +226,7 @@ DrvDeleteContext(
/* Unbind current if deleting current context. */
if (curctx == ctx)
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
st_destroy_context(ctx->st);
FREE(ctx);
@@ -317,7 +317,7 @@ stw_make_current(
}
if (hdc == NULL || dhglrc == 0) {
- return st_make_current( NULL, NULL, NULL );
+ return st_make_current( NULL, NULL, NULL, NULL );
}
pipe_mutex_lock( stw_dev->ctx_mutex );
@@ -352,7 +352,7 @@ stw_make_current(
/* pass to stw_flush_frontbuffer as context_private */
ctx->st->pipe->priv = hdc;
- if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc ))
goto fail;
success:
@@ -367,7 +367,7 @@ success:
fail:
if(fb)
stw_framebuffer_release(fb);
- st_make_current( NULL, NULL, NULL );
+ st_make_current( NULL, NULL, NULL, NULL );
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index e5fa6ac8eb4..ea300f27cb5 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -33,11 +33,6 @@
#include "pipe/p_screen.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_device.h"
#include "stw_winsys.h"
#include "stw_pixelformat.h"
@@ -47,7 +42,6 @@
#ifdef WIN32_THREADS
extern _glthread_Mutex OneTimeLock;
-extern void FreeAllTSD(void);
#endif
@@ -108,13 +102,10 @@ stw_init(const struct stw_winsys *stw_winsys)
if(stw_winsys->get_adapter_luid)
stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
-#ifdef DEBUG
- stw_dev->screen = trace_screen_create(screen);
- stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
-#else
stw_dev->screen = screen;
-#endif
-
+
+ /* XXX
+ */
stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->ctx_mutex );
@@ -183,7 +174,8 @@ stw_cleanup(void)
#ifdef WIN32_THREADS
_glthread_DESTROY_MUTEX(OneTimeLock);
- FreeAllTSD();
+
+ _glapi_destroy_multithread();
#endif
#ifdef DEBUG
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index a83841f6b7d..2e9ba197dfa 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -48,10 +48,6 @@ struct stw_device
struct pipe_screen *screen;
-#ifdef DEBUG
- boolean trace_running;
-#endif
-
LUID AdapterLuid;
struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
diff --git a/src/gallium/state_trackers/wgl/stw_ext_gallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index 8dd63f124ad..5ecbd8048de 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_gallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -31,11 +31,6 @@
#include "stw_winsys.h"
#include "stw_ext_gallium.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
struct pipe_screen * APIENTRY
wglGetGalliumScreenMESA(void)
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 02de21ccb2b..4f1629de2f2 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -34,11 +34,6 @@
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
-
#include "stw_icd.h"
#include "stw_framebuffer.h"
#include "stw_device.h"
@@ -495,13 +490,6 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
surface = (struct pipe_surface *)data->pPrivateData;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
if(data->hSharedSurface != fb->hSharedSurface) {
if(fb->shared_surface) {
stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
@@ -563,13 +551,6 @@ stw_framebuffer_present_locked(HDC hdc,
else {
struct pipe_screen *screen = stw_dev->screen;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
-
stw_dev->stw_winsys->present( screen, surface, hdc );
stw_framebuffer_update(fb);
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index b750b03695f..bc28f31ed1c 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -74,17 +74,17 @@ struct stw_pf_depth_info
static const struct stw_pf_color_info
stw_pf_color[] = {
/* no-alpha */
- { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} },
- { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} },
- { PIPE_FORMAT_R5G6B5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} },
+ { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} },
+ { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} },
+ { PIPE_FORMAT_B5G6R5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} },
/* alpha */
- { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} },
- { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} },
+ { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} },
+ { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} },
#if 0
- { PIPE_FORMAT_A2B10G10R10_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} },
+ { PIPE_FORMAT_R10G10B10A2_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} },
#endif
- { PIPE_FORMAT_A1R5G5B5_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} },
- { PIPE_FORMAT_A4R4G4B4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} }
+ { PIPE_FORMAT_B5G5R5A1_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} },
+ { PIPE_FORMAT_B4G4R4A4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} }
};
@@ -92,12 +92,12 @@ static const struct stw_pf_depth_info
stw_pf_depth_stencil[] = {
/* pure depth */
{ PIPE_FORMAT_Z32_UNORM, {32, 0} },
- { PIPE_FORMAT_Z24X8_UNORM, {24, 0} },
{ PIPE_FORMAT_X8Z24_UNORM, {24, 0} },
+ { PIPE_FORMAT_Z24X8_UNORM, {24, 0} },
{ PIPE_FORMAT_Z16_UNORM, {16, 0} },
/* combined depth-stencil */
- { PIPE_FORMAT_S8Z24_UNORM, {24, 8} },
- { PIPE_FORMAT_Z24S8_UNORM, {24, 8} }
+ { PIPE_FORMAT_Z24S8_UNORM, {24, 8} },
+ { PIPE_FORMAT_S8Z24_UNORM, {24, 8} }
};
@@ -271,14 +271,12 @@ stw_pixelformat_visual(GLvisual *visual,
memset(visual, 0, sizeof *visual);
_mesa_initialize_visual(
visual,
- (pfi->pfd.iPixelType == PFD_TYPE_RGBA) ? GL_TRUE : GL_FALSE,
(pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
(pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE,
pfi->pfd.cRedBits,
pfi->pfd.cGreenBits,
pfi->pfd.cBlueBits,
pfi->pfd.cAlphaBits,
- (pfi->pfd.iPixelType == PFD_TYPE_COLORINDEX) ? pfi->pfd.cColorBits : 0,
pfi->pfd.cDepthBits,
pfi->pfd.cStencilBits,
pfi->pfd.cAccumRedBits,
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 221ce772af9..44f7da0f960 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -197,25 +197,26 @@ crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
if (!crtcp->cursor_tex) {
struct pipe_texture templat;
- unsigned pitch;
+ struct winsys_handle whandle;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth0 = 1;
- templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
templat.width0 = 64;
templat.height0 = 64;
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
- ms->api->local_handle_from_texture(ms->api,
- ms->screen,
- crtcp->cursor_tex,
- &pitch,
- &crtcp->cursor_handle);
+ ms->screen->texture_get_handle(ms->screen, crtcp->cursor_tex, &whandle);
+
+ crtcp->cursor_handle = whandle.handle;
}
transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index 5b673924350..f23e4c6cc7c 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -67,7 +67,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
struct exa_pixmap_priv *exa_priv;
BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
- unsigned stride, handle;
+ struct winsys_handle whandle;
if (pDraw->type == DRAWABLE_PIXMAP)
pPixmap = (PixmapPtr) pDraw;
@@ -75,6 +75,7 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
exa_priv = exaGetPixmapDriverPrivate(pPixmap);
+
switch (buffer->attachment) {
default:
if (buffer->attachment != DRI2BufferFakeFrontLeft ||
@@ -116,19 +117,19 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
break;
default:
template.format = ms->ds_depth_bits_last ?
- PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
+ PIPE_FORMAT_Z24X8_UNORM : PIPE_FORMAT_X8Z24_UNORM;
break;
}
} else {
template.format = ms->ds_depth_bits_last ?
- PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
+ PIPE_FORMAT_Z24S8_UNORM : PIPE_FORMAT_S8Z24_UNORM;
}
template.width0 = pDraw->width;
template.height0 = pDraw->height;
template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
- PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ PIPE_TEXTURE_USAGE_SHARED;
tex = ms->screen->texture_create(ms->screen, &template);
pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
@@ -153,10 +154,13 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
if (!tex)
FatalError("NO TEXTURE IN DRI2\n");
- ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+
+ ms->screen->texture_get_handle(ms->screen, tex, &whandle);
- buffer->name = handle;
- buffer->pitch = stride;
+ buffer->name = whandle.handle;
+ buffer->pitch = whandle.stride;
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
@@ -431,11 +435,11 @@ xorg_dri2_init(ScreenPtr pScreen)
dri2info.Wait = NULL;
ms->d_depth_bits_last =
- ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,
+ ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
ms->ds_depth_bits_last =
- ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_S8Z24_UNORM,
+ ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24S8_UNORM,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index f53a879a14a..004a28f00e1 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -155,7 +155,7 @@ drv_get_rec(ScrnInfoPtr pScrn)
if (pScrn->driverPrivate)
return TRUE;
- pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
+ pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec));
return TRUE;
}
@@ -183,31 +183,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index)
static Bool
drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
modesettingPtr ms = modesettingPTR(pScrn);
- PixmapPtr rootPixmap;
ScreenPtr pScreen = pScrn->pScreen;
+ int old_width, old_height;
+ PixmapPtr rootPixmap;
+ int i;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
+ old_width = pScrn->virtualX;
+ old_height = pScrn->virtualY;
pScrn->virtualX = width;
pScrn->virtualY = height;
- /*
- * Remove the old framebuffer & texture.
- */
- drmModeRmFB(ms->fd, ms->fb_id);
- if (!ms->destroy_front_buffer(pScrn))
- FatalError("failed to destroy front buffer\n");
+ /* ms->create_front_buffer will remove the old front buffer */
rootPixmap = pScreen->GetScreenPixmap(pScreen);
if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
- return FALSE;
+ goto error_modify;
pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
- /* now create new frontbuffer */
- return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
+ if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn))
+ goto error_create;
+
+ /*
+ * create && bind will turn off all crtc(s) in the kernel so we need to
+ * re-enable all the crtcs again. For real HW we might want to do this
+ * before destroying the old framebuffer.
+ */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y);
+ }
+
+ return TRUE;
+
+ /*
+ * This is the error recovery path.
+ */
+error_create:
+ if (!pScreen->ModifyPixmapHeader(rootPixmap, old_width, old_height, -1, -1, -1, NULL))
+ FatalError("failed to resize rootPixmap error path\n");
+
+ pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
+
+error_modify:
+ pScrn->virtualX = old_width;
+ pScrn->virtualY = old_height;
+
+ if (ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn))
+ return FALSE;
+
+ FatalError("failed to setup old framebuffer\n");
+ return FALSE;
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
@@ -333,6 +368,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
EntityInfoPtr pEnt;
EntPtr msEnt = NULL;
int max_width, max_height;
+ CustomizerPtr cust;
if (pScrn->numEntities != 1)
return FALSE;
@@ -344,6 +380,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
return TRUE;
}
+ cust = (CustomizerPtr) pScrn->driverPrivate;
+ pScrn->driverPrivate = NULL;
+
/* Allocate driverPrivate */
if (!drv_get_rec(pScrn))
return FALSE;
@@ -351,6 +390,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
ms = modesettingPTR(pScrn);
ms->SaveGeneration = -1;
ms->pEnt = pEnt;
+ ms->cust = cust;
pScrn->displayWidth = 640; /* default it */
@@ -423,8 +463,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- max_width = 8192;
- max_height = 8192;
+ max_width = 2048; /* A very low default */
+ max_height = 2048; /* see screen_init */
xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
@@ -607,7 +647,9 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned max_width, max_height;
VisualPtr visual;
+ CustomizerPtr cust = ms->cust;
if (!drv_init_drm(pScrn)) {
FatalError("Could not init DRM");
@@ -624,6 +666,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
+ /* get max width and height */
+ {
+ drmModeResPtr res;
+ res = drmModeGetResources(ms->fd);
+ max_width = res->max_width;
+ max_height = res->max_height;
+ drmModeFreeResources(res);
+ }
+
+ if (ms->screen) {
+ float maxf;
+ int max;
+ maxf = ms->screen->get_paramf(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ max = (1 << (int)(maxf - 1.0f));
+ max_width = max < max_width ? max : max_width;
+ max_height = max < max_height ? max : max_height;
+ }
+
+ xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height);
+
pScrn->pScreen = pScreen;
/* HW dependent - FIXME */
@@ -673,7 +735,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
xf86SetBlackWhitePixels(pScreen);
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
- ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
+ ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
if (ms->screen) {
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
@@ -684,6 +746,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#endif
}
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n",
+ ms->screen ? "Gallium3D" : "libkms");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
@@ -694,6 +761,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -725,8 +793,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- if (ms->winsys_screen_init)
- ms->winsys_screen_init(pScrn);
+ if (cust && cust->winsys_screen_init)
+ cust->winsys_screen_init(cust, ms->fd);
return drv_enter_vt(scrnIndex, 1);
}
@@ -759,10 +827,11 @@ drv_leave_vt(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ CustomizerPtr cust = ms->cust;
int o;
- if (ms->winsys_leave_vt)
- ms->winsys_leave_vt(pScrn);
+ if (cust && cust->winsys_leave_vt)
+ cust->winsys_leave_vt(cust);
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
@@ -778,6 +847,7 @@ drv_leave_vt(int scrnIndex, int flags)
}
drmModeRmFB(ms->fd, ms->fb_id);
+ ms->fb_id = -1;
drv_restore_hw_state(pScrn);
@@ -796,6 +866,7 @@ drv_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
+ CustomizerPtr cust = ms->cust;
if (drmSetMaster(ms->fd)) {
if (errno == EINVAL) {
@@ -826,8 +897,8 @@ drv_enter_vt(int scrnIndex, int flags)
if (!xf86SetDesiredModes(pScrn))
return FALSE;
- if (ms->winsys_enter_vt)
- ms->winsys_enter_vt(pScrn);
+ if (cust && cust->winsys_enter_vt)
+ cust->winsys_enter_vt(cust);
return TRUE;
}
@@ -845,13 +916,14 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
+ CustomizerPtr cust = ms->cust;
if (pScrn->vtSema) {
drv_leave_vt(scrnIndex, 0);
}
- if (ms->winsys_screen_close)
- ms->winsys_screen_close(pScrn);
+ if (cust && cust->winsys_screen_close)
+ cust->winsys_screen_close(cust);
#ifdef DRI2
if (ms->screen)
@@ -900,6 +972,15 @@ static Bool
drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
+
+ if (!ms->root_texture)
+ return TRUE;
+
+ if (ms->fb_id != -1) {
+ drmModeRmFB(ms->fd, ms->fb_id);
+ ms->fb_id = -1;
+ }
+
pipe_texture_reference(&ms->root_texture, NULL);
return TRUE;
}
@@ -908,8 +989,9 @@ static Bool
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
struct pipe_texture *tex;
+ struct winsys_handle whandle;
+ unsigned fb_id;
int ret;
ms->noEvict = TRUE;
@@ -920,10 +1002,10 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
if (!tex)
return FALSE;
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_KMS;
+
+ if (!ms->screen->texture_get_handle(ms->screen, tex, &whandle))
goto err_destroy;
ret = drmModeAddFB(ms->fd,
@@ -931,21 +1013,25 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- stride,
- handle,
- &ms->fb_id);
+ whandle.stride,
+ whandle.handle,
+ &fb_id);
if (ret) {
- debug_printf("%s: failed to create framebuffer (%i, %s)",
+ debug_printf("%s: failed to create framebuffer (%i, %s)\n",
__func__, ret, strerror(-ret));
goto err_destroy;
}
+ if (!drv_destroy_front_buffer_ga3d(pScrn))
+ FatalError("%s: failed to take down old framebuffer\n", __func__);
+
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
pipe_texture_reference(&ms->root_texture, tex);
pipe_texture_reference(&tex, NULL);
+ ms->fb_id = fb_id;
return TRUE;
@@ -993,6 +1079,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
if (!ms->root_bo)
return TRUE;
+ if (ms->fb_id != -1) {
+ drmModeRmFB(ms->fd, ms->fb_id);
+ ms->fb_id = -1;
+ }
+
kms_bo_unmap(ms->root_bo);
kms_bo_destroy(&ms->root_bo);
return TRUE;
@@ -1005,6 +1096,7 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
unsigned handle, stride;
struct kms_bo *bo;
unsigned attr[8];
+ unsigned fb_id;
int ret;
attr[0] = KMS_BO_TYPE;
@@ -1035,17 +1127,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
pScrn->bitsPerPixel,
stride,
handle,
- &ms->fb_id);
+ &fb_id);
if (ret) {
debug_printf("%s: failed to create framebuffer (%i, %s)",
__func__, ret, strerror(-ret));
goto err_destroy;
}
+ if (!drv_destroy_front_buffer_kms(pScrn))
+ FatalError("%s: could not takedown old bo", __func__);
+
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
ms->root_bo = bo;
+ ms->fb_id = fb_id;
return TRUE;
@@ -1113,4 +1209,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
return TRUE;
}
+CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn)
+{
+ return modesettingPTR(pScrn)->cust;
+}
+
+Bool xorg_has_gallium(ScrnInfoPtr pScrn)
+{
+ return modesettingPTR(pScrn)->screen != NULL;
+}
+
/* vim: set sw=4 ts=8 sts=4: */
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 665efdc0f03..a7ffe3f4992 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -118,22 +118,22 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_
{
switch (depth) {
case 32:
- *format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ *format = PIPE_FORMAT_B8G8R8A8_UNORM;
*picture_format = PICT_a8r8g8b8;
assert(*bbp == 32);
break;
case 24:
- *format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ *format = PIPE_FORMAT_B8G8R8X8_UNORM;
*picture_format = PICT_x8r8g8b8;
assert(*bbp == 32);
break;
case 16:
- *format = PIPE_FORMAT_R5G6B5_UNORM;
+ *format = PIPE_FORMAT_B5G6R5_UNORM;
*picture_format = PICT_r5g6b5;
assert(*bbp == 16);
break;
case 15:
- *format = PIPE_FORMAT_A1R5G5B5_UNORM;
+ *format = PIPE_FORMAT_B5G5R5A1_UNORM;
*picture_format = PICT_x1r5g5b5;
assert(*bbp == 16);
break;
@@ -144,7 +144,7 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_
break;
case 4:
case 1:
- *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
+ *format = PIPE_FORMAT_B8G8R8A8_UNORM; /* bad bad bad */
break;
default:
assert(0);
@@ -789,7 +789,7 @@ xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+ priv->flags |= PIPE_TEXTURE_USAGE_SCANOUT;
return 0;
}
@@ -805,7 +805,7 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
- priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ priv->flags |= PIPE_TEXTURE_USAGE_SHARED;
return 0;
}
@@ -943,7 +943,7 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
{
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- int mask = PIPE_TEXTURE_USAGE_PRIMARY | PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ int mask = PIPE_TEXTURE_USAGE_SHARED | PIPE_TEXTURE_USAGE_SCANOUT;
if (!priv)
return FALSE;
@@ -976,8 +976,8 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
- template.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SCANOUT;
+ template.tex_usage |= PIPE_TEXTURE_USAGE_SHARED;
return exa->scrn->texture_create(exa->scrn, &template);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 83b0d31e38d..1eb926360b9 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -68,6 +68,8 @@ renderer_draw(struct xorg_renderer *r)
if (buf) {
+ cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
num_verts, /* verts */
@@ -92,6 +94,7 @@ renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_rasterizer_state raster;
+ unsigned i;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
@@ -103,6 +106,14 @@ renderer_init_state(struct xorg_renderer *r)
raster.gl_rasterization_rules = 1;
cso_set_rasterizer(r->cso, &raster);
+ /* vertex elements state */
+ memset(&r->velems[0], 0, sizeof(r->velems[0]) * 3);
+ for (i = 0; i < 3; i++) {
+ r->velems[i].src_offset = i * 4 * sizeof(float);
+ r->velems[i].instance_divisor = 0;
+ r->velems[i].vertex_buffer_index = 0;
+ r->velems[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ }
}
@@ -600,6 +611,8 @@ void renderer_draw_yuv(struct xorg_renderer *r,
if (buf) {
const int num_attribs = 2; /*pos + tex coord*/
+ cso_set_vertex_elements(r->cso, num_attribs, r->velems);
+
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index af6aa0567d6..3d006287199 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -28,6 +28,7 @@ struct xorg_renderer {
float buffer[BUF_SIZE];
int buffer_size;
+ struct pipe_vertex_element velems[3];
/* number of attributes per vertex for the current
* draw operation */
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 58bb60a721d..2f5cc64d9c5 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -67,6 +67,14 @@ typedef struct
#define XORG_NR_FENCES 3
+typedef struct _CustomizerRec
+{
+ Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
+ Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
+ Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
+ Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
+} CustomizerRec, *CustomizerPtr;
+
typedef struct _modesettingRec
{
/* drm */
@@ -117,12 +125,7 @@ typedef struct _modesettingRec
Bool accelerate_2d;
Bool debug_fallback;
- /* winsys hocks */
- Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
- Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
- Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
- Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
- void *winsys_priv;
+ CustomizerPtr cust;
#ifdef DRM_MODE_FEATURE_DIRTYFB
DamagePtr damage;
@@ -131,6 +134,9 @@ typedef struct _modesettingRec
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
+CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
+
+Bool xorg_has_gallium(ScrnInfoPtr pScrn);
/***********************************************************************
* xorg_exa.c
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index 0e39a390c69..12d94e0c5ca 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -101,12 +101,12 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
memset(&template, 0, sizeof(struct pipe_texture));
template.target = PIPE_TEXTURE_2D;
/* XXX: Needs to match the drawable's format? */
- template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
template.last_level = 0;
template.width0 = width;
template.height0 = height;
template.depth0 = 1;
- template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_SHARED;
tex = vpipe->screen->texture_create(vpipe->screen, &template);
if (!tex)