summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c130
-rw-r--r--src/egl/drivers/xdri/Makefile28
-rw-r--r--src/egl/drivers/xdri/driinit.c85
-rw-r--r--src/egl/drivers/xdri/driinit.h9
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c625
-rw-r--r--src/egl/main/eglconfig.c25
-rw-r--r--src/egl/main/eglconfig.h21
-rw-r--r--src/egl/main/eglcontext.h6
-rw-r--r--src/egl/main/egldriver.h6
-rw-r--r--src/egl/main/eglsurface.h6
-rw-r--r--src/gallium/state_trackers/egl/Makefile4
-rw-r--r--src/gallium/state_trackers/egl/x11/glxinit.c (renamed from src/egl/drivers/xdri/glxinit.c)0
-rw-r--r--src/gallium/state_trackers/egl/x11/glxinit.h (renamed from src/egl/drivers/xdri/glxinit.h)0
-rw-r--r--src/gallium/state_trackers/egl/x11/x11_screen.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_program.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c1
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c6
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c7
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c7
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_debug.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c1
-rw-r--r--src/mesa/main/dd.h10
-rw-r--r--src/mesa/main/texenvprogram.c11
-rw-r--r--src/mesa/shader/arbprogram.c9
-rw-r--r--src/mesa/shader/atifragshader.c16
-rw-r--r--src/mesa/shader/shader_api.c6
-rw-r--r--src/mesa/shader/slang/slang_link.c17
-rw-r--r--src/mesa/state_tracker/st_cb_program.c9
-rw-r--r--src/mesa/tnl/t_vb_program.c3
-rw-r--r--src/mesa/tnl/tnl.h2
32 files changed, 224 insertions, 855 deletions
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 56d2b8bbe6..d53f137530 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -97,35 +97,8 @@ struct dri2_egl_config
const __DRIconfig *dri_config;
};
-static struct dri2_egl_driver *
-dri2_egl_driver(_EGLDriver *drv)
-{
- return (struct dri2_egl_driver *) drv;
-}
-
-static struct dri2_egl_display *
-dri2_egl_display(_EGLDisplay *dpy)
-{
- return (struct dri2_egl_display *) dpy->DriverData;
-}
-
-static struct dri2_egl_context *
-dri2_egl_context(_EGLContext *ctx)
-{
- return (struct dri2_egl_context *) ctx;
-}
-
-static struct dri2_egl_surface *
-dri2_egl_surface(_EGLSurface *surf)
-{
- return (struct dri2_egl_surface *) surf;
-}
-
-static struct dri2_egl_config *
-dri2_egl_config(_EGLConfig *conf)
-{
- return (struct dri2_egl_config *) conf;
-}
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
EGLint dri2_to_egl_attribute_map[] = {
0,
@@ -171,8 +144,8 @@ EGLint dri2_to_egl_attribute_map[] = {
0, /* __DRI_ATTRIB_SWAP_METHOD */
EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */
EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */
- EGL_BIND_TO_TEXTURE_RGB, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */
- EGL_BIND_TO_TEXTURE_RGBA, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
+ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */
+ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
0, /* __DRI_ATTRIB_YINVERTED */
@@ -183,8 +156,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id)
{
struct dri2_egl_config *conf;
struct dri2_egl_display *dri2_dpy;
- unsigned int attrib, value, surface_type;
- EGLint key;
+ unsigned int attrib, value, double_buffer;
+ EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
int i;
dri2_dpy = disp->DriverData;
@@ -194,7 +167,6 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id)
conf->dri_config = dri_config;
_eglInitConfig(&conf->base, disp, id);
- surface_type = EGL_PBUFFER_BIT | EGL_PIXMAP_BIT;
i = 0;
while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
@@ -222,9 +194,16 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id)
_eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, value);
break;
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
+ bind_to_texture_rgb = value;
+ break;
+
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
+ bind_to_texture_rgba = value;
+ break;
+
case __DRI_ATTRIB_DOUBLE_BUFFER:
- if (value)
- surface_type |= EGL_WINDOW_BIT;
+ double_buffer = value;
break;
default:
@@ -236,22 +215,28 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id)
}
/* EGL_SWAP_BEHAVIOR_PRESERVED_BIT */
- _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, surface_type);
+
+ if (double_buffer) {
+ /* FIXME: Figure out how to get the visual ID and types */
+ _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0x21);
+ _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE,
+ XCB_VISUAL_CLASS_TRUE_COLOR);
+ } else {
+ _eglSetConfigKey(&conf->base,
+ EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
+ _eglSetConfigKey(&conf->base,
+ EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
+ _eglSetConfigKey(&conf->base,
+ EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);
+ }
/* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */
_eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
_eglSetConfigKey(&conf->base, EGL_CONFORMANT, EGL_OPENGL_BIT);
- /* FIXME: Figure out how to get the visual ID and types */
- _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0x21);
- _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE,
- XCB_VISUAL_CLASS_TRUE_COLOR);
-
- _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
- _eglSetConfigKey(&conf->base, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
-
if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
- _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", i);
+ _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
free(conf);
return;
}
@@ -484,13 +469,16 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
dri2_dpy->driver = NULL;
end = search_paths + strlen(search_paths);
for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) {
+ int path_len;
+
next = strchr(p, ':');
if (next == NULL)
next = end;
+ path_len = next - p;
snprintf(path, sizeof path,
dri_driver_format,
- next - p, p,
+ path_len, p,
xcb_dri2_connect_driver_name_length (connect),
xcb_dri2_connect_driver_name (connect));
@@ -583,6 +571,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
for (i = 0; extensions[i]; i++) {
+ _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name);
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0))
dri2_dpy->flush = (__DRI2flushExtension *) extensions[i];
}
@@ -719,11 +708,11 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if ((cctx == NULL && ddraw == NULL && rdraw == NULL) ||
dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) {
- if (dsurf)
+ if (dsurf && !_eglIsSurfaceLinked(dsurf))
dri2_destroy_surface(drv, disp, dsurf);
- if (rsurf && rsurf != dsurf)
+ if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(dsurf))
dri2_destroy_surface(drv, disp, rsurf);
- if (ctx != NULL)
+ if (ctx != NULL && !_eglIsContextLinked(ctx))
dri2_dpy->core->unbindContext(dri2_egl_context(ctx)->dri_context);
return EGL_TRUE;
@@ -835,8 +824,7 @@ dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
xcb_dri2_copy_region_cookie_t cookie;
- if (dri2_dpy->flush)
- (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
#if 0
/* FIXME: Add support for dri swapbuffers, that'll give us swap
@@ -873,15 +861,21 @@ dri2_get_proc_address(_EGLDriver *drv, const char *procname)
}
static EGLBoolean
-dri2_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
{
- /* glXWaitGL(); */
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface);
+
+ /* FIXME: If EGL allows frontbuffer rendering for window surfaces,
+ * we need to copy fake to real here.*/
+
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
return EGL_TRUE;
}
static EGLBoolean
-dri2_wait_native(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
+dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine)
{
if (engine != EGL_CORE_NATIVE_ENGINE)
return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
@@ -897,6 +891,31 @@ dri2_unload(_EGLDriver *drv)
free(dri2_drv);
}
+static EGLBoolean
+dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
+ EGLNativePixmapType target)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+ xcb_gcontext_t gc;
+
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+
+ gc = xcb_generate_id(dri2_dpy->conn);
+ xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL);
+ xcb_copy_area(dri2_dpy->conn,
+ dri2_surf->drawable,
+ target,
+ gc,
+ 0, 0,
+ 0, 0,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height);
+ xcb_free_gc(dri2_dpy->conn, gc);
+
+ return EGL_TRUE;
+}
+
/**
* This is the main entrypoint into the driver, called by libEGL.
* Create a new _EGLDriver object and init its dispatch table.
@@ -923,6 +942,7 @@ _eglMain(const char *args)
dri2_drv->base.API.GetProcAddress = dri2_get_proc_address;
dri2_drv->base.API.WaitClient = dri2_wait_client;
dri2_drv->base.API.WaitNative = dri2_wait_native;
+ dri2_drv->base.API.CopyBuffers = dri2_copy_buffers;
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile
deleted file mode 100644
index 9120620dc5..0000000000
--- a/src/egl/drivers/xdri/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# src/egl/drivers/xdri/Makefile
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER = egl_xdri.so
-
-# steal sources from GLX
-GLX_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c drisw_glx.c
-GLX_SOURCES := $(addprefix ../../../glx/x11/,$(GLX_SOURCES))
-GLX_INCLUDES = \
- $(shell pkg-config --cflags-only-I libdrm) \
- -I$(TOP)/include/GL/internal \
- -I$(TOP)/src/glx/x11 \
- -I$(TOP)/src/mesa/glapi \
- -I$(TOP)/src/mesa
-GLX_CFLAGS = -DGLX_DIRECT_RENDERING
-
-EGL_SOURCES = egl_xdri.c glxinit.c driinit.c $(GLX_SOURCES)
-EGL_INCLUDES = \
- -I$(TOP)/include \
- -I$(TOP)/src/egl/main \
- $(GLX_INCLUDES)
-
-EGL_CFLAGS = $(GLX_CFLAGS)
-EGL_LIBS = -lX11 -lGL
-
-include ../Makefile.template
diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c
deleted file mode 100644
index 3e54f0bd4d..0000000000
--- a/src/egl/drivers/xdri/driinit.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * DRI initialization. The DRI loaders are defined in src/glx/x11/.
- */
-
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "glxclient.h"
-#include "driinit.h"
-
-/* for __DRI_SYSTEM_TIME extension */
-_X_HIDDEN int
-__glXGetUST(int64_t * ust)
-{
- struct timeval tv;
-
- if (ust == NULL) {
- return -EFAULT;
- }
-
- if (gettimeofday(&tv, NULL) == 0) {
- ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
- return 0;
- }
- else {
- return -errno;
- }
-}
-
-_X_HIDDEN GLboolean
-__driGetMscRateOML(__DRIdrawable * draw,
- int32_t * numerator, int32_t * denominator, void *private)
-{
- return GL_FALSE;
-}
-
-/* ignore glx extensions */
-_X_HIDDEN void
-__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name)
-{
-}
-
-_X_HIDDEN __GLXDRIdisplay *
-__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version)
-{
- __GLXDRIdisplay *driDisplay = NULL;
- int ver = 0;
- char *env;
- int force_sw;
-
- env = getenv("EGL_SOFTWARE");
- force_sw = (env && *env != '0');
-
- /* try DRI2 first */
- if (!force_sw) {
- driDisplay = dri2CreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- /* fill in the required field */
- dpyPriv->dri2Display = driDisplay;
- ver = 2;
- }
- }
-
- /* and then DRI */
- if (!force_sw && !driDisplay) {
- driDisplay = driCreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- dpyPriv->driDisplay = driDisplay;
- ver = 1;
- }
- }
-
- /* and then DRISW */
- if (!driDisplay) {
- driDisplay = driswCreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- dpyPriv->driDisplay = driDisplay;
- ver = 0;
- }
- }
-
- if (version)
- *version = ver;
- return driDisplay;
-}
diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h
deleted file mode 100644
index 6ea05cebef..0000000000
--- a/src/egl/drivers/xdri/driinit.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef DRIINIT_INCLUDED
-#define DRIINIT_INCLUDED
-
-#include "glxclient.h"
-
-extern __GLXDRIdisplay *
-__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version);
-
-#endif /* DRIINIT_INCLUDED */
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
deleted file mode 100644
index 555473c00a..0000000000
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ /dev/null
@@ -1,625 +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.
- *
- **************************************************************************/
-
-
-/**
- * Code to interface a DRI driver to libEGL.
- * Note that unlike previous DRI/EGL interfaces, this one is meant to
- * be used _with_ X. Applications will use eglCreateWindowSurface()
- * to render into X-created windows.
- *
- * This is an EGL driver that, in turn, loads a regular DRI driver.
- * There are some dependencies on code in libGL, but those could be
- * removed with some effort.
- *
- * Authors: Brian Paul
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-
-#include "glxinit.h"
-#include "driinit.h"
-#include "glapi/glapi.h" /* for glapi functions */
-
-#include "eglconfig.h"
-#include "eglconfigutil.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglcurrent.h"
-#include "egllog.h"
-#include "eglsurface.h"
-
-#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
-
-/** subclass of _EGLDriver */
-struct xdri_egl_driver
-{
- _EGLDriver Base; /**< base class */
- void (*FlushCurrentContext)(void);
-};
-
-
-/** driver data of _EGLDisplay */
-struct xdri_egl_display
-{
- Display *dpy;
- __GLXdisplayPrivate *dpyPriv;
- __GLXDRIdisplay *driDisplay;
- int driVersion;
-
- __GLXscreenConfigs *psc;
- EGLint scr;
-};
-
-
-/** subclass of _EGLContext */
-struct xdri_egl_context
-{
- _EGLContext Base; /**< base class */
-
- /* just enough info to create dri contexts */
- GLXContext dummy_gc;
-
- __GLXDRIcontext *driContext;
-};
-
-
-/** subclass of _EGLSurface */
-struct xdri_egl_surface
-{
- _EGLSurface Base; /**< base class */
-
- Drawable drawable;
- __GLXDRIdrawable *driDrawable;
-};
-
-
-/** subclass of _EGLConfig */
-struct xdri_egl_config
-{
- _EGLConfig Base; /**< base class */
-
- const __GLcontextModes *mode; /**< corresponding GLX mode */
- EGLint window_render_buffer;
-};
-
-
-
-/* standard typecasts */
-_EGL_DRIVER_STANDARD_TYPECASTS(xdri_egl)
-
-#define lookup_display(dpy) xdri_egl_display(dpy)
-#define lookup_context(ctx) xdri_egl_context(ctx)
-#define lookup_surface(surf) xdri_egl_surface(surf)
-#define lookup_config(conf) xdri_egl_config(conf)
-
-
-/** Get size of given window */
-static Status
-get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
-{
- Window root;
- Status stat;
- int xpos, ypos;
- unsigned int w, h, bw, depth;
- stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
- *width = w;
- *height = h;
- return stat;
-}
-
-
-static EGLBoolean
-convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m)
-{
- EGLint val;
-
- if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT))
- return EGL_FALSE;
-
- if (m->doubleBufferMode) {
- /* pixmap and pbuffer surfaces are always single-buffered */
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
- SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val);
- }
- else {
- /* EGL requires OpenGL ES context to be double-buffered */
- val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE);
- val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
- SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val);
- }
- /* skip "empty" config */
- if (!val)
- return EGL_FALSE;
-
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- if (!(val & EGL_PBUFFER_BIT)) {
- /* bind-to-texture cannot be EGL_TRUE without pbuffer bit */
- SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
- SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
- }
-
- /* EGL_NATIVE_RENDERABLE is a boolean */
- val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE);
- if (val != EGL_TRUE)
- SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE);
-
- return _eglValidateConfig(conf, EGL_FALSE);
-}
-
-
-/**
- * Produce a set of EGL configs.
- */
-static EGLint
-create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(disp);
- int id = first_id;
-
- for (; m; m = m->next) {
- struct xdri_egl_config *xdri_conf;
- _EGLConfig conf;
- EGLint rb;
-
- _eglInitConfig(&conf, disp, id);
- if (!convert_config(&conf, id, m))
- continue;
- if (m->doubleBufferMode) {
- rb = EGL_BACK_BUFFER;
- }
- else {
- /* ignore single-buffered mode for DRISW */
- if (xdri_dpy->driVersion == 0)
- continue;
- rb = EGL_SINGLE_BUFFER;
- }
-
- xdri_conf = CALLOC_STRUCT(xdri_egl_config);
- if (xdri_conf) {
- memcpy(&xdri_conf->Base, &conf, sizeof(conf));
- xdri_conf->mode = m;
- xdri_conf->window_render_buffer = rb;
- _eglAddConfig(disp, &xdri_conf->Base);
- id++;
- }
- }
-
- return id;
-}
-
-
-/**
- * Called via eglInitialize(), xdri_dpy->API.Initialize().
- */
-static EGLBoolean
-xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLint *minor, EGLint *major)
-{
- struct xdri_egl_display *xdri_dpy;
- __GLXdisplayPrivate *dpyPriv;
- __GLXDRIdisplay *driDisplay;
- __GLXscreenConfigs *psc;
- EGLint first_id = 1;
- int scr;
-
- xdri_dpy = CALLOC_STRUCT(xdri_egl_display);
- if (!xdri_dpy)
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
- xdri_dpy->dpy = (Display *) dpy->NativeDisplay;
- if (!xdri_dpy->dpy) {
- xdri_dpy->dpy = XOpenDisplay(NULL);
- if (!xdri_dpy->dpy) {
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
- }
-
- dpyPriv = __glXInitialize(xdri_dpy->dpy);
- if (!dpyPriv) {
- _eglLog(_EGL_WARNING, "failed to create GLX display");
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- driDisplay = __driCreateDisplay(dpyPriv, &xdri_dpy->driVersion);
- if (!driDisplay) {
- _eglLog(_EGL_WARNING, "failed to create DRI display");
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- scr = DefaultScreen(xdri_dpy->dpy);
- psc = &dpyPriv->screenConfigs[scr];
-
- xdri_dpy->dpyPriv = dpyPriv;
- xdri_dpy->driDisplay = driDisplay;
- xdri_dpy->psc = psc;
- xdri_dpy->scr = scr;
-
- psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv);
- if (!psc->driScreen) {
- _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr);
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- dpy->DriverData = xdri_dpy;
- dpy->ClientAPIsMask = EGL_OPENGL_BIT;
-
- /* add visuals and fbconfigs */
- first_id = create_configs(dpy, psc->visuals, first_id);
- create_configs(dpy, psc->configs, first_id);
-
- /* we're supporting EGL 1.4 */
- *minor = 1;
- *major = 4;
-
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglTerminate(), drv->API.Terminate().
- */
-static EGLBoolean
-xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- __GLXscreenConfigs *psc;
-
- _eglReleaseDisplayResources(drv, dpy);
- _eglCleanupDisplay(dpy);
-
- psc = xdri_dpy->psc;
- if (psc->driver_configs) {
- unsigned int i;
- for (i = 0; psc->driver_configs[i]; i++)
- free((__DRIconfig *) psc->driver_configs[i]);
- free(psc->driver_configs);
- psc->driver_configs = NULL;
- }
- if (psc->driScreen) {
- psc->driScreen->destroyScreen(psc);
- free(psc->driScreen);
- psc->driScreen = NULL;
- }
-
- xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
-
- free(xdri_dpy);
- dpy->DriverData = NULL;
-
- return EGL_TRUE;
-}
-
-
-/*
- * Called from eglGetProcAddress() via drv->API.GetProcAddress().
- */
-static _EGLProc
-xdri_eglGetProcAddress(_EGLDriver *drv, const char *procname)
-{
- /* the symbol is defined in libGL.so */
- return (_EGLProc) _glapi_get_proc_address(procname);
-}
-
-
-/**
- * Called via eglCreateContext(), drv->API.CreateContext().
- */
-static _EGLContext *
-xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- _EGLContext *share_list, const EGLint *attrib_list)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(conf);
- struct xdri_egl_context *shared = lookup_context(share_list);
- __GLXscreenConfigs *psc = xdri_dpy->psc;
- int renderType = GLX_RGBA_BIT;
- struct xdri_egl_context *xdri_ctx;
-
- xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
- if (!xdri_ctx) {
- _eglError(EGL_BAD_ALLOC, "eglCreateContext");
- return NULL;
- }
-
- xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec);
- if (!xdri_ctx->dummy_gc) {
- _eglError(EGL_BAD_ALLOC, "eglCreateContext");
- free(xdri_ctx);
- return NULL;
- }
-
- if (!_eglInitContext(&xdri_ctx->Base, dpy, &xdri_config->Base, attrib_list)) {
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
- return NULL;
- }
-
- /* the config decides the render buffer for the context */
- xdri_ctx->Base.WindowRenderBuffer = xdri_config->window_render_buffer;
-
- xdri_ctx->driContext =
- psc->driScreen->createContext(psc,
- xdri_config->mode,
- xdri_ctx->dummy_gc,
- (shared) ? shared->dummy_gc : NULL,
- renderType);
- if (!xdri_ctx->driContext) {
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
- return NULL;
- }
-
- /* fill in the required field */
- xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext;
-
- return &xdri_ctx->Base;
-}
-
-
-/**
- * Destroy a context.
- */
-static void
-destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_context *xdri_ctx = lookup_context(ctx);
-
- /* FIXME a context might live longer than its display */
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
-
- xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
- xdri_dpy->psc, xdri_dpy->dpy);
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
-}
-
-
-/**
- * Destroy a surface.
- */
-static void
-destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
-{
- struct xdri_egl_surface *xdri_surf = lookup_surface(surf);
-
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
-
- xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
- free(xdri_surf);
-}
-
-
-static EGLBoolean
-xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- if (!_eglIsContextBound(ctx))
- destroy_context(dpy, ctx);
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglMakeCurrent(), drv->API.MakeCurrent().
- */
-static EGLBoolean
-xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
- _EGLSurface *r, _EGLContext *context)
-{
- struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
- struct xdri_egl_context *xdri_ctx = lookup_context(context);
- struct xdri_egl_surface *draw = lookup_surface(d);
- struct xdri_egl_surface *read = lookup_surface(r);
-
- /* bind the new context and return the "orphaned" one */
- if (!_eglBindContext(&context, &d, &r))
- return EGL_FALSE;
-
- /* flush before context switch */
- if (context && xdri_driver->FlushCurrentContext)
- xdri_driver->FlushCurrentContext();
-
- /* the symbol is defined in libGL.so */
- _glapi_check_multithread();
-
- if (xdri_ctx) {
- if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext,
- draw->driDrawable,
- read->driDrawable)) {
- return EGL_FALSE;
- }
- }
- else if (context) {
- xdri_ctx = lookup_context(context);
- xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
- }
-
- if (context && !_eglIsContextLinked(context))
- destroy_context(dpy, context);
- if (d && !_eglIsSurfaceLinked(d))
- destroy_surface(dpy, d);
- if (r && r != d && !_eglIsSurfaceLinked(r))
- destroy_surface(dpy, r);
-
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
- */
-static _EGLSurface *
-xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- EGLNativeWindowType window,
- const EGLint *attrib_list)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(conf);
- struct xdri_egl_surface *xdri_surf;
- uint width, height;
-
- xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
- if (!xdri_surf) {
- _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
- return NULL;
- }
-
- if (!_eglInitSurface(&xdri_surf->Base, dpy, EGL_WINDOW_BIT,
- &xdri_config->Base, attrib_list)) {
- free(xdri_surf);
- return NULL;
- }
-
- xdri_surf->driDrawable =
- xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc,
- (XID) window,
- (GLXDrawable) window,
- xdri_config->mode);
- if (!xdri_surf->driDrawable) {
- free(xdri_surf);
- return NULL;
- }
-
- xdri_surf->drawable = (Drawable) window;
-
- get_drawable_size(xdri_dpy->dpy, window, &width, &height);
- xdri_surf->Base.Width = width;
- xdri_surf->Base.Height = height;
-
- return &xdri_surf->Base;
-}
-
-
-/**
- * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface().
- */
-static _EGLSurface *
-xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-
-static EGLBoolean
-xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
-{
- if (!_eglIsSurfaceBound(surface))
- destroy_surface(dpy, surface);
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLint buffer)
-{
- return EGL_FALSE;
-}
-
-
-static EGLBoolean
-xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLint buffer)
-{
- return EGL_FALSE;
-}
-
-
-static EGLBoolean
-xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
-{
- struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
-
- /* swapBuffers does not flush commands */
- if (draw->CurrentContext && xdri_driver->FlushCurrentContext)
- xdri_driver->FlushCurrentContext();
-
- xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0);
-
- return EGL_TRUE;
-}
-
-
-static void
-xdri_Unload(_EGLDriver *drv)
-{
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- free(xdri_drv);
-}
-
-
-/**
- * This is the main entrypoint into the driver, called by libEGL.
- * Create a new _EGLDriver object and init its dispatch table.
- */
-_EGLDriver *
-_eglMain(const char *args)
-{
- struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver);
- if (!xdri_drv)
- return NULL;
-
- _eglInitDriverFallbacks(&xdri_drv->Base);
- xdri_drv->Base.API.Initialize = xdri_eglInitialize;
- xdri_drv->Base.API.Terminate = xdri_eglTerminate;
-
- xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress;
-
- xdri_drv->Base.API.CreateContext = xdri_eglCreateContext;
- xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext;
- xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent;
- xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
- xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface;
- xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface;
- xdri_drv->Base.API.BindTexImage = xdri_eglBindTexImage;
- xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage;
- xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
-
- xdri_drv->Base.Name = "X/DRI";
- xdri_drv->Base.Unload = xdri_Unload;
-
- /* we need a way to flush commands */
- xdri_drv->FlushCurrentContext =
- (void (*)(void)) xdri_eglGetProcAddress(&xdri_drv->Base, "glFlush");
-
- return &xdri_drv->Base;
-}
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 635ffee92b..1190f8cdd5 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -366,8 +366,11 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (_eglValidationTable[i].criterion == ATTRIB_CRITERION_SPECIAL)
valid = EGL_TRUE;
}
- if (!valid)
+ if (!valid) {
+ _eglLog(_EGL_DEBUG,
+ "attribute 0x%04x has an invalid value 0x%x", attr, val);
break;
+ }
}
/* any invalid attribute value should have been catched */
@@ -390,10 +393,18 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
valid = EGL_FALSE;
break;
}
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
+ return EGL_FALSE;
+ }
val = GET_CONFIG_ATTRIB(conf, EGL_SAMPLE_BUFFERS);
if (!val && GET_CONFIG_ATTRIB(conf, EGL_SAMPLES))
valid = EGL_FALSE;
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "conflicting samples and sample buffers");
+ return EGL_FALSE;
+ }
val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
if (!(val & EGL_WINDOW_BIT)) {
@@ -406,6 +417,10 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
GET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA))
valid = EGL_FALSE;
}
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "conflicting surface type and native visual/texture binding");
+ return EGL_FALSE;
+ }
return valid;
}
@@ -457,8 +472,14 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
break;
}
- if (!matched)
+ if (!matched) {
+#ifdef DEBUG
+ _eglLog(_EGL_DEBUG,
+ "the value (0x%x) of attribute 0x%04x did not meet the criteria (0x%x)",
+ val, attr, cmp);
+#endif
break;
+ }
}
return matched;
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 09dc61f547..56ec95fe9a 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -21,6 +21,9 @@ struct _egl_config
};
+/**
+ * Macros for source level compatibility.
+ */
#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) _eglSetConfigKey(CONF, ATTR, VAL)
#define GET_CONFIG_ATTRIB(CONF, ATTR) _eglGetConfigKey(CONF, ATTR)
@@ -55,6 +58,10 @@ _eglResetConfigKeys(_EGLConfig *conf, EGLint val)
/**
* Update a config for a given key.
+ *
+ * Note that a valid key is not necessarily a valid attribute. There are gaps
+ * in the attribute enums. The separation is to catch application errors.
+ * Drivers should never set a key that is an invalid attribute.
*/
static INLINE void
_eglSetConfigKey(_EGLConfig *conf, EGLint key, EGLint val)
@@ -77,20 +84,6 @@ _eglGetConfigKey(const _EGLConfig *conf, EGLint key)
}
-/**
- * Set a given attribute.
- *
- * Because _eglGetConfigAttrib is already used as a fallback driver
- * function, this function is not considered to have a good name.
- * SET_CONFIG_ATTRIB is preferred over this function.
- */
-static INLINE void
-_eglSetConfigAttrib(_EGLConfig *conf, EGLint attr, EGLint val)
-{
- SET_CONFIG_ATTRIB(conf, attr, val);
-}
-
-
PUBLIC void
_eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id);
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 14fce02c11..cfe92dd9f5 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -60,6 +60,9 @@ _eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLConte
/**
* Return true if the context is bound to a thread.
+ *
+ * The binding is considered a reference to the context. Drivers should not
+ * destroy a context when it is bound.
*/
static INLINE EGLBoolean
_eglIsContextBound(_EGLContext *ctx)
@@ -119,6 +122,9 @@ _eglGetContextHandle(_EGLContext *ctx)
/**
* Return true if the context is linked to a display.
+ *
+ * The link is considered a reference to the context (the display is owning the
+ * context). Drivers should not destroy a context when it is linked.
*/
static INLINE EGLBoolean
_eglIsContextLinked(_EGLContext *ctx)
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index c1e6fa2820..55686681dc 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -8,6 +8,9 @@
/**
* Define an inline driver typecast function.
+ *
+ * Note that this macro defines a function and should not be ended with a
+ * semicolon when used.
*/
#define _EGL_DRIVER_TYPECAST(drvtype, egltype, code) \
static INLINE struct drvtype *drvtype(const egltype *obj) \
@@ -17,6 +20,9 @@
/**
* Define the driver typecast functions for _EGLDriver, _EGLDisplay,
* _EGLContext, _EGLSurface, and _EGLConfig.
+ *
+ * Note that this macro defines several functions and should not be ended with
+ * a semicolon when used.
*/
#define _EGL_DRIVER_STANDARD_TYPECASTS(drvname) \
_EGL_DRIVER_TYPECAST(drvname ## _driver, _EGLDriver, obj) \
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index feba30d4f8..0a00035730 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -107,6 +107,9 @@ _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
/**
* Return true if there is a context bound to the surface.
+ *
+ * The binding is considered a reference to the surface. Drivers should not
+ * destroy a surface when it is bound.
*/
static INLINE EGLBoolean
_eglIsSurfaceBound(_EGLSurface *surf)
@@ -166,6 +169,9 @@ _eglGetSurfaceHandle(_EGLSurface *surf)
/**
* Return true if the surface is linked to a display.
+ *
+ * The link is considered a reference to the surface (the display is owning the
+ * surface). Drivers should not destroy a surface when it is linked.
*/
static INLINE EGLBoolean
_eglIsSurfaceLinked(_EGLSurface *surf)
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index b696f2fae9..2863320a48 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -15,13 +15,11 @@ common_OBJECTS = $(common_SOURCES:.c=.o)
x11_INCLUDES = \
-I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/glx/x11 \
- -I$(TOP)/src/egl/drivers/xdri \
-I$(TOP)/src/mesa \
$(shell pkg-config --cflags-only-I libdrm)
x11_SOURCES = $(wildcard x11/*.c) \
- $(TOP)/src/glx/x11/dri2.c \
- $(TOP)/src/egl/drivers/xdri/glxinit.c
+ $(TOP)/src/glx/x11/dri2.c
x11_OBJECTS = $(x11_SOURCES:.c=.o)
diff --git a/src/egl/drivers/xdri/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c
index ba6132788a..ba6132788a 100644
--- a/src/egl/drivers/xdri/glxinit.c
+++ b/src/gallium/state_trackers/egl/x11/glxinit.c
diff --git a/src/egl/drivers/xdri/glxinit.h b/src/gallium/state_trackers/egl/x11/glxinit.h
index 1cc7c460fe..1cc7c460fe 100644
--- a/src/egl/drivers/xdri/glxinit.h
+++ b/src/gallium/state_trackers/egl/x11/glxinit.h
diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c
index 76ce45ee57..d72bfc99d3 100644
--- a/src/gallium/state_trackers/egl/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl/x11/x11_screen.c
@@ -43,7 +43,7 @@ struct x11_screen {
int number;
/*
- * This is used to fetch GLX visuals/fbconfigs. It uses code from egl_xdri.
+ * This is used to fetch GLX visuals/fbconfigs. It steals code from GLX.
* It might be better to rewrite the part in Xlib or XCB.
*/
__GLXdisplayPrivate *glx_dpy;
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index a273bd28ea..15e3b87097 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -1205,7 +1205,7 @@ i915IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
return GL_TRUE;
}
-static void
+static GLboolean
i915ProgramStringNotify(GLcontext * ctx,
GLenum target, struct gl_program *prog)
{
@@ -1223,7 +1223,10 @@ i915ProgramStringNotify(GLcontext * ctx,
}
}
- _tnl_program_string(ctx, target, prog);
+ (void) _tnl_program_string(ctx, target, prog);
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
void
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index e3b6fccc49..c78f7b38ae 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -111,9 +111,10 @@ static GLboolean brwIsProgramNative( GLcontext *ctx,
return GL_TRUE;
}
-static void brwProgramStringNotify( GLcontext *ctx,
- GLenum target,
- struct gl_program *prog )
+
+static GLboolean brwProgramStringNotify( GLcontext *ctx,
+ GLenum target,
+ struct gl_program *prog )
{
struct brw_context *brw = brw_context(ctx);
@@ -150,6 +151,9 @@ static void brwProgramStringNotify( GLcontext *ctx,
*/
_tnl_program_string(ctx, target, prog);
}
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
void brwInitFragProgFuncs( struct dd_function_table *functions )
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index 3135d5330d..2f2b8d94dc 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -88,6 +88,7 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] );
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.stp );
for (i = 0; i < 8; ++i)
insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] );
for (i = 0; i < 3 + mtu; ++i)
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index d9bf31b611..d6964484bf 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -2464,6 +2464,12 @@ static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask )
radeon_firevertices(&r200->radeon);
+ radeon_print(RADEON_STATE, RADEON_TRACE,
+ "%s(%p) first 32 bits are %x.\n",
+ __func__,
+ ctx,
+ *(uint32_t*)mask);
+
R200_STATECHANGE(r200, stp);
/* Must flip pattern upside down.
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 4f225a233d..12f869d96f 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -1218,7 +1218,7 @@ r200DeleteProgram(GLcontext *ctx, struct gl_program *prog)
_mesa_delete_program(ctx, prog);
}
-static void
+static GLboolean
r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
{
struct r200_vertex_program *vp = (void *)prog;
@@ -1237,7 +1237,10 @@ r200ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
break;
}
/* need this for tcl fallbacks */
- _tnl_program_string(ctx, target, prog);
+ (void) _tnl_program_string(ctx, target, prog);
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
static GLboolean
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index a4f9db13ec..3638010e48 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -98,7 +98,7 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog)
_mesa_delete_program(ctx, prog);
}
-static void
+static GLboolean
r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
struct r300_vertex_program_cont *vp = (struct r300_vertex_program_cont *)prog;
@@ -116,7 +116,10 @@ r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
}
/* need this for tcl fallbacks */
- _tnl_program_string(ctx, target, prog);
+ (void) _tnl_program_string(ctx, target, prog);
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
static GLboolean
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 0d476fcd86..2a50361199 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -132,7 +132,7 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
_mesa_delete_program(ctx, prog);
}
-static void
+static GLboolean
r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
struct r700_vertex_program_cont *vpc = (struct r700_vertex_program_cont *)prog;
@@ -153,6 +153,8 @@ r700ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog)
break;
}
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
static GLboolean r700IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h
index 26da31c1c4..ef8b9671ac 100644
--- a/src/mesa/drivers/dri/radeon/radeon_debug.h
+++ b/src/mesa/drivers/dri/radeon/radeon_debug.h
@@ -47,7 +47,11 @@ typedef enum radeon_debug_levels {
* errors.
*/
#ifndef RADEON_DEBUG_LEVEL
-#define RADEON_DEBUG_LEVEL RADEON_VERBOSE
+# ifdef DEBUG
+# define RADEON_DEBUG_LEVEL RADEON_TRACE
+# else
+# define RADEON_DEBUG_LEVEL RADEON_VERBOSE
+# endif
#endif
typedef enum radeon_debug_types {
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 4fd60ac18e..db0e4f2f7a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -92,6 +92,7 @@ void radeonSetUpAtomList( r100ContextPtr rmesa )
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i]);
for (i = 0; i < 6; ++i)
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i]);
+ insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.stp);
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.eye);
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.grd);
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.fog);
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 6705c901dd..d98a14e09c 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -581,9 +581,13 @@ struct dd_function_table {
struct gl_program * (*NewProgram)(GLcontext *ctx, GLenum target, GLuint id);
/** Delete a program */
void (*DeleteProgram)(GLcontext *ctx, struct gl_program *prog);
- /** Notify driver that a program string has been specified. */
- void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
- struct gl_program *prog);
+ /**
+ * Notify driver that a program string (and GPU code) has been specified
+ * or modified. Return GL_TRUE or GL_FALSE to indicate if the program is
+ * supported by the driver.
+ */
+ GLboolean (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
+ struct gl_program *prog);
/** Query if program can be loaded onto hardware */
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 499b7330d0..414607e228 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -1535,8 +1535,15 @@ create_new_program(GLcontext *ctx, struct state_key *key,
/* Notify driver the fragment program has (actually) changed.
*/
if (ctx->Driver.ProgramStringNotify) {
- ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB,
- &p.program->Base );
+ GLboolean ok = ctx->Driver.ProgramStringNotify(ctx,
+ GL_FRAGMENT_PROGRAM_ARB,
+ &p.program->Base);
+ /* Driver should be able to handle any texenv programs as long as
+ * the driver correctly reported max number of texture units correctly,
+ * etc.
+ */
+ ASSERT(ok);
+ (void) ok; /* silence unused var warning */
}
if (DISASSEM) {
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 746138071e..7e3040a6ef 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -489,8 +489,13 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
return;
}
- if (ctx->Program.ErrorPos == -1 && ctx->Driver.ProgramStringNotify)
- ctx->Driver.ProgramStringNotify( ctx, target, base );
+ if (ctx->Program.ErrorPos == -1) {
+ /* finally, give the program to the driver for translation/checking */
+ if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glProgramStringARB(rejected by driver");
+ }
+ }
}
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
index e04a05b22f..ab7b2030d1 100644
--- a/src/mesa/shader/atifragshader.c
+++ b/src/mesa/shader/atifragshader.c
@@ -378,8 +378,11 @@ _mesa_EndFragmentShaderATI(void)
}
if (ctx->ATIFragmentShader.Current->cur_pass > 1)
ctx->ATIFragmentShader.Current->NumPasses = 2;
- else ctx->ATIFragmentShader.Current->NumPasses = 1;
- ctx->ATIFragmentShader.Current->cur_pass=0;
+ else
+ ctx->ATIFragmentShader.Current->NumPasses = 1;
+
+ ctx->ATIFragmentShader.Current->cur_pass = 0;
+
#if MESA_DEBUG_ATI_FS
for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
@@ -402,8 +405,13 @@ _mesa_EndFragmentShaderATI(void)
}
}
#endif
- if (ctx->Driver.ProgramStringNotify)
- ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_SHADER_ATI, NULL );
+
+ if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
+ ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+ /* XXX is this the right error? */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glEndFragmentShaderATI(driver rejected shader)");
+ }
}
void GLAPIENTRY
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index d53580f5f6..e8eaa9c103 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1715,7 +1715,11 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
*/
FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
_mesa_update_shader_textures_used(program);
- ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+ /* Do we need to care about the return value here?
+ * This should not be the first time the driver was notified of
+ * this program.
+ */
+ (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
}
}
else {
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 21497b34e2..df524ce078 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -719,6 +719,7 @@ _slang_link(GLcontext *ctx,
{
const struct gl_vertex_program *vertProg = NULL;
const struct gl_fragment_program *fragProg = NULL;
+ GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
GLuint numSamplers = 0;
GLuint i;
@@ -871,8 +872,8 @@ _slang_link(GLcontext *ctx,
_mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
/* notify driver that a new fragment program has been compiled/linked */
- ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
- &shProg->FragmentProgram->Base);
+ vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ &shProg->FragmentProgram->Base);
if (ctx->Shader.Flags & GLSL_DUMP) {
_mesa_printf("Mesa pre-link fragment program:\n");
_mesa_print_program(&fragProg->Base);
@@ -889,8 +890,8 @@ _slang_link(GLcontext *ctx,
_mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
/* notify driver that a new vertex program has been compiled/linked */
- ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
- &shProg->VertexProgram->Base);
+ fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+ &shProg->VertexProgram->Base);
if (ctx->Shader.Flags & GLSL_DUMP) {
_mesa_printf("Mesa pre-link vertex program:\n");
_mesa_print_program(&vertProg->Base);
@@ -918,6 +919,12 @@ _slang_link(GLcontext *ctx,
}
}
- shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+ if (!vertNotify || !fragNotify) {
+ /* driver rejected one/both of the vertex/fragment programs */
+ link_error(shProg, "Vertex and/or fragment program rejected by driver\n");
+ }
+ else {
+ shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+ }
}
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 86c53b4e76..82ef5572e1 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -177,9 +177,9 @@ static GLboolean st_is_program_native( GLcontext *ctx,
}
-static void st_program_string_notify( GLcontext *ctx,
- GLenum target,
- struct gl_program *prog )
+static GLboolean st_program_string_notify( GLcontext *ctx,
+ GLenum target,
+ struct gl_program *prog )
{
struct st_context *st = st_context(ctx);
@@ -211,6 +211,9 @@ static void st_program_string_notify( GLcontext *ctx,
if (st->vp == stvp)
st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
}
+
+ /* XXX check if program is legal, within limits */
+ return GL_TRUE;
}
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 5396548666..44b64b17d1 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -203,13 +203,14 @@ vp_fetch_texel(GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
* Called via ctx->Driver.ProgramStringNotify() after a new vertex program
* string has been parsed.
*/
-void
+GLboolean
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program)
{
/* No-op.
* If we had derived anything from the program that was private to this
* stage we'd recompute/validate it here.
*/
+ return GL_TRUE;
}
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
index 9c66d3b019..2c0d1fef73 100644
--- a/src/mesa/tnl/tnl.h
+++ b/src/mesa/tnl/tnl.h
@@ -66,7 +66,7 @@ _tnl_allow_vertex_fog( GLcontext *ctx, GLboolean value );
extern void
_tnl_allow_pixel_fog( GLcontext *ctx, GLboolean value );
-extern void
+extern GLboolean
_tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program);
struct _mesa_prim;